Follow Ghostty split light/dark themes per system appearance#96
Merged
Conversation
Ghostty resolves `theme = light:X,dark:Y` to one set of colors at config finalize, keyed on a private conditional state that defaults to light, with no C API to query the other variant. Mori never pushed a color scheme or observed the system appearance, so split themes were stuck on the light variant for both the terminal and Mori's own chrome. - GhosttyApp/GhosttyAdapter: push the color scheme to libghostty (app + every surface, and on surface creation) so the terminal re-resolves the split theme live; resolve the active variant ourselves and re-extract chrome colors via a forced single-theme extraction config. - AppDelegate: observe NSApp.effectiveAppearance and re-run theme propagation (factored into propagateGhosttyTheme) on system dark/light changes. - Settings: model gains syncAppearance + darkTheme; read/write parse and emit the light:…,dark:… syntax. Theme UI adds a "sync with system appearance" toggle with light/dark variant pickers. - Docs + en/zh localization updated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Mori now follows Ghostty's split light/dark themes. Set
theme = light:…,dark:…in your Ghostty config — or toggle Sync with system appearance in Settings → Theme and pick a light and a dark theme — and the terminal and Mori's own chrome (sidebar, windows, panels, tmux) switch live when you change the macOS appearance.Why
Ghostty resolves
theme = light:X,dark:Yto a single set of colors at config-finalize time, keyed on a private conditional state that defaults to light, and exposes no C API to query the other variant from a config. Mori never pushed a color scheme to libghostty nor observed the system appearance — so split themes were effectively stuck on the light variant for both the terminal and Mori's chrome.How
GhosttyApp/GhosttyAdapter): newGhosttyColorScheme(resolved fromNSApp.effectiveAppearance).setColorScheme(_:)callsghostty_app_set_color_scheme+ per-surfaceghostty_surface_set_color_scheme(and on surface creation) so the terminal re-resolves the split theme live.GhosttyApp.extractThemeInfo): since a bare config can't surface the non-active variant, Mori parses thethemestring itself, picks the variant for the current appearance, and forces it onto a throwaway extraction config. The terminal's own config keeps the full split string.AppDelegate): KVO onNSApp.effectiveAppearancere-runs theme propagation (factored intopropagateGhosttyTheme, shared with config reload).syncAppearance+darkTheme; read/write parse and emit thelight:…,dark:…syntax. Theme UI adds a sync toggle with light/dark variant pickers.Verification
swift build -c release --product Mori— clean (Swift 6 strict concurrency, incl. the KVO closure)mise run test— all suites passCI=1 bash scripts/bundle.sh— bundles cleanlyNot done: live GUI launch test (blocked locally by the single-instance guard against an already-running install) and a unit test for the split parser (MoriTerminal has no test target; pure string split). Manual check: set
theme = light:rose-pine-dawn,dark:rose-pine, toggle system appearance, confirm terminal + sidebar follow.