gpui_macos/
system_theme.rs1use crate::{ActiveTheme, Theme};
3use gpui_kit::{App, Global, Window};
4use std::collections::HashSet;
5#[derive(Default)]
6struct AppearancePolicy {
7 following: bool,
8 windows: HashSet<gpui_kit::WindowId>,
9}
10impl Global for AppearancePolicy {}
11
12impl Theme {
13 pub fn follow_system(cx: &mut App) {
16 cx.set_window_appearance(None);
17 cx.default_global::<AppearancePolicy>().following = true;
18 sync(cx);
19 }
20 pub fn is_following_system(cx: &App) -> bool {
21 cx.try_global::<AppearancePolicy>()
22 .is_some_and(|policy| policy.following)
23 }
24}
25pub(crate) fn stop_following(cx: &mut App) {
26 cx.default_global::<AppearancePolicy>().following = false;
27}
28fn sync(cx: &mut App) {
29 let mut next = Theme::system(cx);
30 if let Some(current) = cx.try_global::<Theme>() {
31 next.glass_tint = current.glass_tint;
32 let default = if current.is_dark() {
34 Theme::dark()
35 } else {
36 Theme::light()
37 };
38 if current.accent != default.accent {
39 next = next.with_accent(current.accent);
40 }
41 }
42 if cx.try_global::<Theme>() != Some(&next) {
43 next.apply_palette(cx);
44 }
45}
46pub fn observe_window(window: &mut Window, cx: &mut App) {
49 if cx
50 .default_global::<AppearancePolicy>()
51 .windows
52 .insert(window.window_handle().window_id())
53 {
54 window
55 .observe_window_appearance(|_, cx| {
56 if Theme::is_following_system(cx) {
57 sync(cx);
58 }
59 gpui_kit::base::apply_system_reduce_motion(cx);
60 })
61 .detach();
62 }
63}
64pub fn refresh_accessibility(cx: &mut App) {
66 crate::native::refresh_sidebar_metrics();
67 let mut theme = cx.macos().clone();
68 theme.read_accessibility();
69 theme.apply_palette(cx);
70 gpui_kit::base::apply_system_reduce_motion(cx);
71}