Initialize the SystemAppearance using the app's global window appearance (#7508)

This PR changes our approach to initializing the `SystemAppearance` so
that we can do it earlier in the startup process.

Previously we were using the appearance from the window, meaning that we
couldn't initialize the value until we first opened the window.

Now we read the `window_appearance` from the `AppContext`. On macOS this
is backed by the
[`effectiveAppearance`](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance)
on the `NSApplication`.

We currently still watch for changes to the appearance at the window
level, as the only hook I could find in the documentation is
[`viewDidChangeEffectiveAppearance`](https://developer.apple.com/documentation/appkit/nsview/2977088-viewdidchangeeffectiveappearance),
which is at the `NSView` level.

In my testing this makes it so Zed appropriately chooses the correct
light/dark theme on startup.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-02-07 11:51:18 -05:00 committed by GitHub
parent b59e110c59
commit c322179bb9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 46 additions and 28 deletions

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use derive_more::{Deref, DerefMut};
use gpui::{
px, AppContext, Font, FontFeatures, FontStyle, FontWeight, Global, Pixels, Subscription,
ViewContext, WindowContext,
ViewContext,
};
use refineable::Refineable;
use schemars::{
@ -49,6 +49,12 @@ struct GlobalSystemAppearance(SystemAppearance);
impl Global for GlobalSystemAppearance {}
impl SystemAppearance {
/// Initializes the [`SystemAppearance`] for the application.
pub fn init(cx: &mut AppContext) {
*cx.default_global::<GlobalSystemAppearance>() =
GlobalSystemAppearance(SystemAppearance(cx.window_appearance().into()));
}
/// Returns the global [`SystemAppearance`].
///
/// Inserts a default [`SystemAppearance`] if one does not yet exist.
@ -56,12 +62,6 @@ impl SystemAppearance {
cx.default_global::<GlobalSystemAppearance>().0
}
/// Initializes the [`SystemAppearance`] for the current window.
pub fn init_for_window(cx: &mut WindowContext) {
*cx.default_global::<GlobalSystemAppearance>() =
GlobalSystemAppearance(SystemAppearance(cx.appearance().into()));
}
/// Returns the global [`SystemAppearance`].
pub fn global(cx: &AppContext) -> Self {
cx.global::<GlobalSystemAppearance>().0