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...");
if let Err(err) = ThemeRegistry::watch_dir(PathBuf::from("./themes"), cx, move |cx| {
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)
.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<Self>,
) -> 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.));

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
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 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();
})

View file

@ -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;
}
}