From 2f2661ecd28621707d2d36999501bba9d03129cf Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Sun, 1 Nov 2026 16:15:28 +0700 Subject: [PATCH] chore: improve native theme usage --- crates/settings/src/lib.rs | 45 ++++++++++++++++++++++++++----------- crates/workspace/src/lib.rs | 9 ++++---- desktop/src/main.rs | 21 ++++++----------- 3 files changed, 44 insertions(+), 31 deletions(-) diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs index fb7b1150..8e16d781 100644 --- a/crates/settings/src/lib.rs +++ b/crates/settings/src/lib.rs @@ -330,22 +330,40 @@ impl AppSettings { }); } - /// Apply the persisted theme tuning on top of the active theme pub fn apply_theme_style(cx: &mut App) { + Self::apply_theme_tuning(Self::get_theme(cx), cx); + } + + fn apply_theme_tuning(tuning: ThemeSettings, cx: &mut App) { use gpui_kit::component::Theme; - let theme = Self::get_theme(cx); - let styled = Theme::global_mut(cx); - styled.font_size = px(theme.font_size); - styled.focus_ring = theme.focus_ring; - if let Some(radius) = theme.radius { - styled.radius = px(radius); + { + let styled = Theme::global_mut(cx); + styled.font_size = px(tuning.font_size); + styled.focus_ring = tuning.focus_ring; + if let Some(radius) = tuning.radius { + styled.radius = px(radius); + } + if let Some(radius_lg) = tuning.radius_lg { + styled.radius_lg = px(radius_lg); + } } - if let Some(radius_lg) = theme.radius_lg { - styled.radius_lg = px(radius_lg); - } - Theme::sync_base(cx); - cx.refresh_windows(); + + Theme::update(cx, |styled| { + let background = styled.background; + let foreground = styled.foreground; + let (hover_alpha, active_alpha) = if styled.is_dark() { + (0.08, 0.12) + } else { + (0.04, 0.06) + }; + if styled.list_hover == background { + styled.list_hover = foreground.alpha(hover_alpha); + } + if styled.tab_active == background { + styled.tab_active = foreground.alpha(active_alpha); + } + }); } /// Load settings @@ -416,7 +434,8 @@ impl AppSettings { AppearanceMode::Light => Theme::change(gpui_kit::component::ThemeMode::Light, None, cx), AppearanceMode::Dark => Theme::change(gpui_kit::component::ThemeMode::Dark, None, cx), } - cx.refresh_windows(); + let tuning = self.inner.read(cx).theme; + Self::apply_theme_tuning(tuning, cx); } /// Check if decoupling encryption key is enabled diff --git a/crates/workspace/src/lib.rs b/crates/workspace/src/lib.rs index 6f99f2b0..3a80a0c9 100644 --- a/crates/workspace/src/lib.rs +++ b/crates/workspace/src/lib.rs @@ -91,11 +91,12 @@ impl Workspace { let workspace = cx.entity().downgrade(); let mut subscriptions = smallvec![]; - if AppSettings::get_appearance_mode(cx) == AppearanceMode::System { - subscriptions.push(cx.observe_window_appearance(window, |_this, window, cx| { + subscriptions.push(cx.observe_window_appearance(window, |_this, window, cx| { + if AppSettings::get_appearance_mode(cx) == AppearanceMode::System { Theme::sync_system_appearance(Some(window), cx); - })); - } + AppSettings::apply_theme_style(cx); + } + })); subscriptions.push( // Subscribe to the nostr events diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 84c0b6de..f1e34dcd 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -72,14 +72,13 @@ fn main() { let appearance = settings::persisted_appearance_mode(); let font_size = settings::persisted_theme().font_size; - match apply_native_theme(appearance, font_size, cx) { - Ok(()) => start_theme_watcher(appearance, cx), - Err(error) => { - log::warn!("native theme unavailable ({error})"); - apply_appearance(appearance, cx); - AppSettings::apply_theme_style(cx); - } + + if let Err(error) = apply_native_theme(appearance, font_size, cx) { + log::warn!("native theme unavailable ({error})"); + apply_appearance(appearance, cx); + AppSettings::apply_theme_style(cx); } + start_theme_watcher(cx); // Initialize the nostr client state::init(cx, cli_key); @@ -213,14 +212,12 @@ fn apply_appearance(appearance: AppearanceMode, cx: &mut App) { /// Holds the watcher subscription so it lives as long as the app. struct ThemeWatcher { _subscription: ThemeSubscription, - /// The appearance mode the observer in `workspace` was registered with. - appearance: std::cell::Cell, } impl Global for ThemeWatcher {} /// Start a background task to watch for OS theme changes and re-apply the native theme. -fn start_theme_watcher(initial_appearance: AppearanceMode, cx: &mut App) { +fn start_theme_watcher(cx: &mut App) { let (sender, receiver) = flume::unbounded(); match native_theme::watch::on_theme_change(move |event| { if let Err(error) = sender.send(event) { @@ -230,7 +227,6 @@ fn start_theme_watcher(initial_appearance: AppearanceMode, cx: &mut App) { Ok(subscription) => { cx.set_global(ThemeWatcher { _subscription: subscription, - appearance: std::cell::Cell::new(initial_appearance), }); cx.spawn(async move |cx| { while receiver.recv_async().await.is_ok() { @@ -238,9 +234,6 @@ fn start_theme_watcher(initial_appearance: AppearanceMode, cx: &mut App) { cx.update(|cx| { let appearance = AppSettings::get_appearance_mode(cx); let font_size = AppSettings::get_theme(cx).font_size; - if let Some(watcher) = cx.try_global::() { - watcher.appearance.set(appearance); - } if let Err(error) = apply_native_theme(appearance, font_size, cx) { log::warn!("failed to apply updated OS theme ({error})"); }