theme: Fix reload theme to keep last selected. (#1164)

This commit is contained in:
Jason Lee 2025-08-20 17:33:12 +08:00 committed by GitHub
parent eb5fa06809
commit c4c948b177
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 27 deletions

View file

@ -25,15 +25,14 @@ pub fn init(cx: &mut App) {
tracing::info!("Load themes..."); tracing::info!("Load themes...");
if let Err(err) = ThemeRegistry::watch_dir(PathBuf::from("./themes"), cx, move |cx| { if let Err(err) = ThemeRegistry::watch_dir(PathBuf::from("./themes"), cx, move |cx| {
if let Ok(state) = serde_json::from_str::<State>(&json) { if let Ok(state) = serde_json::from_str::<State>(&json) {
tracing::info!("apply theme: {:?}", state.theme);
AppState::global_mut(cx).theme_name = Some(state.theme.clone());
if let Some(theme) = ThemeRegistry::global(cx) if let Some(theme) = ThemeRegistry::global(cx)
.themes() .themes()
.get(&state.theme) .get(&state.theme)
.cloned() .cloned()
{ {
AppState::global_mut(cx).theme_name = Some(state.theme.clone());
Theme::global_mut(cx).apply_config(&theme); 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)] #[action(namespace = themes, no_json)]
struct SwitchTheme(SharedString); struct SwitchTheme(SharedString);
pub struct ThemeSwitcher { pub struct ThemeSwitcher {}
current_theme_name: SharedString,
}
impl ThemeSwitcher { impl ThemeSwitcher {
pub fn new(cx: &mut App) -> Self { pub fn new(_: &mut App) -> Self {
let theme_name = AppState::global(cx) Self {}
.theme_name
.clone()
.unwrap_or("default-light".into());
Self {
current_theme_name: theme_name,
}
} }
} }
@ -68,22 +58,28 @@ impl Render for ThemeSwitcher {
_: &mut gpui::Window, _: &mut gpui::Window,
cx: &mut gpui::Context<Self>, cx: &mut gpui::Context<Self>,
) -> impl gpui::IntoElement { ) -> impl gpui::IntoElement {
let theme_name = AppState::global(cx)
.theme_name
.clone()
.unwrap_or("default-light".into());
div() div()
.id("theme-switcher") .id("theme-switcher")
.on_action(cx.listener(|this, switch: &SwitchTheme, _, cx| { .on_action(cx.listener(|_, switch: &SwitchTheme, _, cx| {
this.current_theme_name = switch.0.clone(); let theme_name = switch.0.clone();
let theme_name = this.current_theme_name.clone(); // Save AppState
let mut state = State {
theme: theme_name.clone(),
};
if let Some(theme_config) = if let Some(theme_config) =
ThemeRegistry::global(cx).themes().get(&theme_name).cloned() ThemeRegistry::global(cx).themes().get(&theme_name).cloned()
{ {
Theme::global_mut(cx).apply_config(&theme_config); 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(); let json = serde_json::to_string_pretty(&state).unwrap();
std::fs::write(STATE_FILE, json).unwrap(); std::fs::write(STATE_FILE, json).unwrap();
@ -95,7 +91,7 @@ impl Render for ThemeSwitcher {
.ghost() .ghost()
.small() .small()
.popup_menu({ .popup_menu({
let current_theme_id = self.current_theme_name.clone(); let current_theme_id = theme_name.clone();
move |menu, _, cx| { move |menu, _, cx| {
let mut menu = menu.scrollable().max_h(px(600.)); let mut menu = menu.scrollable().max_h(px(600.));

View file

@ -45,9 +45,10 @@ pub(super) fn init(cx: &mut App) {
// Observe changes to the theme registry to apply changes to the active theme // Observe changes to the theme registry to apply changes to the active theme
cx.observe_global::<ThemeRegistry>(|cx| { cx.observe_global::<ThemeRegistry>(|cx| {
tracing::info!("Reload active theme..."); let mode = Theme::global(cx).mode;
let light_theme = Theme::global(cx).light_theme.name.clone(); let light_theme = Theme::global(cx).light_theme.name.clone();
let dark_theme = Theme::global(cx).dark_theme.name.clone(); let dark_theme = Theme::global(cx).dark_theme.name.clone();
if let Some(theme) = ThemeRegistry::global(cx) if let Some(theme) = ThemeRegistry::global(cx)
.themes() .themes()
.get(&light_theme) .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() { if let Some(theme) = ThemeRegistry::global(cx).themes().get(&dark_theme).cloned() {
Theme::global_mut(cx).dark_theme = theme; 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); Theme::change(mode, None, cx);
cx.refresh_windows(); cx.refresh_windows();
}) })

View file

@ -619,7 +619,7 @@ impl Theme {
if let Some(style) = &config.highlight { if let Some(style) = &config.highlight {
let highlight_theme = Arc::new(HighlightTheme { let highlight_theme = Arc::new(HighlightTheme {
name: config.name.to_string(), name: config.name.to_string(),
appearance: self.mode, appearance: config.mode,
style: style.clone(), style: style.clone(),
}); });
self.highlight_theme = highlight_theme.clone(); self.highlight_theme = highlight_theme.clone();
@ -632,6 +632,7 @@ impl Theme {
}; };
self.colors.apply_config(&config, &default_theme); self.colors.apply_config(&config, &default_theme);
self.mode = config.mode;
} }
} }