Skip to content

splash: three sources of truth for the pre-config background #763

Description

@deblasis

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions