App applies conditional state, supports theme setting

The prior light/dark mode awareness work works on surface-level APIs. As
a result, configurations used at the app-level (such as split divider
colors, inactive split opacity, etc.) are not aware of the current theme
configurations and default to the "light" theme.

This commit adds APIs to specify app-level color scheme changes. This
changes the configuration for the app and sets the default conditional
state to use that new theme. This latter point makes it so that future
surfaces use the correct theme on load rather than requiring some apprt
event loop ticks. Some users have already reported a short "flicker" to
load the correct theme, so this should help alleviate that.
This commit is contained in:
Mitchell Hashimoto
2024-11-22 13:42:48 -08:00
parent 958316d851
commit cd49015243
6 changed files with 112 additions and 3 deletions

View File

@@ -95,6 +95,9 @@ class AppDelegate: NSObject,
/// makes our logic very easy.
private var isVisible: Bool = true
/// The observer for the app appearance.
private var appearanceObserver: NSKeyValueObservation? = nil
override init() {
terminalManager = TerminalManager(ghostty)
updaterController = SPUStandardUpdaterController(
@@ -187,6 +190,23 @@ class AppDelegate: NSObject,
)
])
center.delegate = self
// Observe our appearance so we can report the correct value to libghostty.
self.appearanceObserver = NSApplication.shared.observe(
\.effectiveAppearance,
options: [.new, .initial]
) { _, change in
guard let appearance = change.newValue else { return }
guard let app = self.ghostty.app else { return }
let scheme: ghostty_color_scheme_e
if (appearance.isDark) {
scheme = GHOSTTY_COLOR_SCHEME_DARK
} else {
scheme = GHOSTTY_COLOR_SCHEME_LIGHT
}
ghostty_app_set_color_scheme(app, scheme)
}
}
func applicationDidBecomeActive(_ notification: Notification) {

View File

@@ -1212,6 +1212,7 @@ extension Ghostty {
switch (target.tag) {
case GHOSTTY_TARGET_APP:
// Notify the world that the app config changed
NotificationCenter.default.post(
name: .ghosttyConfigDidChange,
object: nil,
@@ -1219,6 +1220,14 @@ extension Ghostty {
SwiftUI.Notification.Name.GhosttyConfigChangeKey: config,
]
)
// We also REPLACE our app-level config when this happens. This lets
// all the various things that depend on this but are still theme specific
// such as split border color work.
guard let app_ud = ghostty_app_userdata(app) else { return }
let ghostty = Unmanaged<App>.fromOpaque(app_ud).takeUnretainedValue()
ghostty.config = config
return
case GHOSTTY_TARGET_SURFACE: