From c4c948b177ef7fd27efc9f6142c0cf5b0c4c42da Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 20 Aug 2025 17:33:12 +0800 Subject: [PATCH] theme: Fix reload theme to keep last selected. (#1164) --- crates/story/src/themes.rs | 44 +++++++++++++++------------------ crates/ui/src/theme/registry.rs | 11 +++++++-- crates/ui/src/theme/schema.rs | 3 ++- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/crates/story/src/themes.rs b/crates/story/src/themes.rs index 239d7a10..110c92e5 100644 --- a/crates/story/src/themes.rs +++ b/crates/story/src/themes.rs @@ -25,15 +25,14 @@ pub fn init(cx: &mut App) { tracing::info!("Load themes..."); if let Err(err) = ThemeRegistry::watch_dir(PathBuf::from("./themes"), cx, move |cx| { if let Ok(state) = serde_json::from_str::(&json) { - tracing::info!("apply theme: {:?}", state.theme); - AppState::global_mut(cx).theme_name = Some(state.theme.clone()); - if let Some(theme) = ThemeRegistry::global(cx) .themes() .get(&state.theme) .cloned() { + AppState::global_mut(cx).theme_name = Some(state.theme.clone()); Theme::global_mut(cx).apply_config(&theme); + cx.refresh_windows(); } } }) { @@ -45,20 +44,11 @@ pub fn init(cx: &mut App) { #[action(namespace = themes, no_json)] struct SwitchTheme(SharedString); -pub struct ThemeSwitcher { - current_theme_name: SharedString, -} +pub struct ThemeSwitcher {} impl ThemeSwitcher { - pub fn new(cx: &mut App) -> Self { - let theme_name = AppState::global(cx) - .theme_name - .clone() - .unwrap_or("default-light".into()); - - Self { - current_theme_name: theme_name, - } + pub fn new(_: &mut App) -> Self { + Self {} } } @@ -68,22 +58,28 @@ impl Render for ThemeSwitcher { _: &mut gpui::Window, cx: &mut gpui::Context, ) -> impl gpui::IntoElement { + let theme_name = AppState::global(cx) + .theme_name + .clone() + .unwrap_or("default-light".into()); + div() .id("theme-switcher") - .on_action(cx.listener(|this, switch: &SwitchTheme, _, cx| { - this.current_theme_name = switch.0.clone(); - let theme_name = this.current_theme_name.clone(); + .on_action(cx.listener(|_, switch: &SwitchTheme, _, cx| { + let theme_name = switch.0.clone(); + // Save AppState + let mut state = State { + theme: theme_name.clone(), + }; + if let Some(theme_config) = ThemeRegistry::global(cx).themes().get(&theme_name).cloned() { Theme::global_mut(cx).apply_config(&theme_config); + state.theme = theme_config.name.clone(); + AppState::global_mut(cx).theme_name = Some(theme_name.clone()); } - // Save AppState - let state = State { - theme: theme_name.clone(), - }; - AppState::global_mut(cx).theme_name = Some(theme_name.clone()); let json = serde_json::to_string_pretty(&state).unwrap(); std::fs::write(STATE_FILE, json).unwrap(); @@ -95,7 +91,7 @@ impl Render for ThemeSwitcher { .ghost() .small() .popup_menu({ - let current_theme_id = self.current_theme_name.clone(); + let current_theme_id = theme_name.clone(); move |menu, _, cx| { let mut menu = menu.scrollable().max_h(px(600.)); diff --git a/crates/ui/src/theme/registry.rs b/crates/ui/src/theme/registry.rs index c327492f..ee15747a 100644 --- a/crates/ui/src/theme/registry.rs +++ b/crates/ui/src/theme/registry.rs @@ -45,9 +45,10 @@ pub(super) fn init(cx: &mut App) { // Observe changes to the theme registry to apply changes to the active theme cx.observe_global::(|cx| { - tracing::info!("Reload active theme..."); + let mode = Theme::global(cx).mode; let light_theme = Theme::global(cx).light_theme.name.clone(); let dark_theme = Theme::global(cx).dark_theme.name.clone(); + if let Some(theme) = ThemeRegistry::global(cx) .themes() .get(&light_theme) @@ -58,8 +59,14 @@ pub(super) fn init(cx: &mut App) { if let Some(theme) = ThemeRegistry::global(cx).themes().get(&dark_theme).cloned() { Theme::global_mut(cx).dark_theme = theme; } - let mode = Theme::global(cx).mode; + let theme_name = if mode.is_dark() { + dark_theme + } else { + light_theme + }; + + tracing::info!("Reload active theme: {:?}...", theme_name); Theme::change(mode, None, cx); cx.refresh_windows(); }) diff --git a/crates/ui/src/theme/schema.rs b/crates/ui/src/theme/schema.rs index 59c21fc1..780bd382 100644 --- a/crates/ui/src/theme/schema.rs +++ b/crates/ui/src/theme/schema.rs @@ -619,7 +619,7 @@ impl Theme { if let Some(style) = &config.highlight { let highlight_theme = Arc::new(HighlightTheme { name: config.name.to_string(), - appearance: self.mode, + appearance: config.mode, style: style.clone(), }); self.highlight_theme = highlight_theme.clone(); @@ -632,6 +632,7 @@ impl Theme { }; self.colors.apply_config(&config, &default_theme); + self.mode = config.mode; } }