Three places decide what colour the window is before the config is resolved,
and they can disagree with each other and with the terminal.
The splash duplicates the built-in backgrounds
SplashWindow.cs hardcodes 0x131620 and 0xF4F6FB. Their source of truth
is src/config/wintty_theme.zig. Nothing links the two, so a palette tweak
silently desynchronises the first frame from every frame after it.
It does not have to guess: InitGhostty() runs before StartGui(), and
ghostty_config_builtin_theme touches no config handle and no allocator, so
it is callable at that point. Parse background out of it, or add a narrow
ghostty_builtin_theme_background(scheme) -> u32.
The splash and the app read the OS theme two different ways
SplashWindow reads AppsUseLightTheme from the registry. Everything else
goes through UISettings.GetColorValue(UIColorType.Foreground) (OsTheme).
Under a High Contrast theme these disagree: UISettings reflects the HC
scheme while the registry value keeps whatever it was. Under HC White with
AppsUseLightTheme = 0 the splash paints near-black and the terminal comes
up white, which is the flash this work removed everywhere else. The codebase
already supports HC (HighContrastMonitor, HighContrastOverrideFile), so
it is reachable. Not reproduced, so confirm before fixing.
Related, smaller: a missing AppsUseLightTheme currently defaults to dark.
Windows' own default for that value absent is light.
BackgroundFollowsOsTheme misses conditional user themes
MainWindow.RecordSplashBackground computes it as
!IsConfiguredInFile("background") && string.IsNullOrEmpty(CurrentTheme)
A user with theme = light:catppuccin-latte,dark:catppuccin-mocha has a
non-empty CurrentTheme, so this reads false -- but their background does
track the desktop. Flip the desktop between two launches and the splash
trusts the stale saved colour. ThemeParser.ParseThemePair already returns
non-null for both halves in that case.
IsConfiguredInFile("background") also only sees the top-level config file,
so background set in a file reached through config-file reads as
unconfigured. Same root cause as the one fixed by
ghostty_config_theme_is_builtin; the same treatment probably applies.
One-time flash on upgrade
An existing WindowState JSON has no BackgroundFollowsOsTheme, so it
deserializes to false and the first launch after upgrade trusts the saved
colour before RecordSplashBackground corrects it. Acceptable, noted so it
is not mistaken for a regression.
Three places decide what colour the window is before the config is resolved,
and they can disagree with each other and with the terminal.
The splash duplicates the built-in backgrounds
SplashWindow.cshardcodes0x131620and0xF4F6FB. Their source of truthis
src/config/wintty_theme.zig. Nothing links the two, so a palette tweaksilently desynchronises the first frame from every frame after it.
It does not have to guess:
InitGhostty()runs beforeStartGui(), andghostty_config_builtin_themetouches no config handle and no allocator, soit is callable at that point. Parse
backgroundout of it, or add a narrowghostty_builtin_theme_background(scheme) -> u32.The splash and the app read the OS theme two different ways
SplashWindowreadsAppsUseLightThemefrom the registry. Everything elsegoes through
UISettings.GetColorValue(UIColorType.Foreground)(OsTheme).Under a High Contrast theme these disagree:
UISettingsreflects the HCscheme while the registry value keeps whatever it was. Under HC White with
AppsUseLightTheme = 0the splash paints near-black and the terminal comesup white, which is the flash this work removed everywhere else. The codebase
already supports HC (
HighContrastMonitor,HighContrastOverrideFile), soit is reachable. Not reproduced, so confirm before fixing.
Related, smaller: a missing
AppsUseLightThemecurrently defaults to dark.Windows' own default for that value absent is light.
BackgroundFollowsOsThememisses conditional user themesMainWindow.RecordSplashBackgroundcomputes it asA user with
theme = light:catppuccin-latte,dark:catppuccin-mochahas anon-empty
CurrentTheme, so this reads false -- but their background doestrack the desktop. Flip the desktop between two launches and the splash
trusts the stale saved colour.
ThemeParser.ParseThemePairalready returnsnon-null for both halves in that case.
IsConfiguredInFile("background")also only sees the top-level config file,so
backgroundset in a file reached throughconfig-filereads asunconfigured. Same root cause as the one fixed by
ghostty_config_theme_is_builtin; the same treatment probably applies.One-time flash on upgrade
An existing
WindowStateJSON has noBackgroundFollowsOsTheme, so itdeserializes to false and the first launch after upgrade trusts the saved
colour before
RecordSplashBackgroundcorrects it. Acceptable, noted so itis not mistaken for a regression.