From 144487bf1ac3b21e16f5ae03b715a3e13f88f1d7 Mon Sep 17 00:00:00 2001 From: Finn Evers Date: Fri, 7 Feb 2025 17:30:53 +0100 Subject: [PATCH] theme: Implement icon theme reloading (#24449) Closes #24353 This PR implements icon theme reload to ensure file icons are properly updated whenever an icon theme extension is upgraded or uninstalled. Currently, on both upgrade and uninstall of an icon theme extension the file icons from the previously installed version will stay visibile and will not be updated as shown in the linked issue. With this change, file icons will properly be updated on extension upgrade or reinstall. The code is primarily a copy for reloading the current color theme adapted to work for icon themes. Happy for any feedback! Release Notes: - Fixed file icons not being properly updated upon icon theme upgrade or uninstall. --- crates/extension/src/extension_host_proxy.rs | 10 +++++ crates/extension_host/src/extension_host.rs | 1 + crates/theme/src/settings.rs | 42 +++++++++++++++++++ crates/theme_extension/src/theme_extension.rs | 4 ++ 4 files changed, 57 insertions(+) diff --git a/crates/extension/src/extension_host_proxy.rs b/crates/extension/src/extension_host_proxy.rs index 25d4a4e539cc1d18f49e73a7dc95c5953798ec7c..a692795e87f2f07d918b424cf0bb11cb71f67a78 100644 --- a/crates/extension/src/extension_host_proxy.rs +++ b/crates/extension/src/extension_host_proxy.rs @@ -118,6 +118,8 @@ pub trait ExtensionThemeProxy: Send + Sync + 'static { icons_root_dir: PathBuf, fs: Arc, ) -> Task>; + + fn reload_current_icon_theme(&self, cx: &mut App); } impl ExtensionThemeProxy for ExtensionHostProxy { @@ -185,6 +187,14 @@ impl ExtensionThemeProxy for ExtensionHostProxy { proxy.load_icon_theme(icon_theme_path, icons_root_dir, fs) } + + fn reload_current_icon_theme(&self, cx: &mut App) { + let Some(proxy) = self.theme_proxy.read().clone() else { + return; + }; + + proxy.reload_current_icon_theme(cx) + } } pub trait ExtensionGrammarProxy: Send + Sync + 'static { diff --git a/crates/extension_host/src/extension_host.rs b/crates/extension_host/src/extension_host.rs index 69c26d44a46b61ed41906498337d0899670cd1fa..e1e866705ac7447367df376c60ac1b03cd078dc1 100644 --- a/crates/extension_host/src/extension_host.rs +++ b/crates/extension_host/src/extension_host.rs @@ -1292,6 +1292,7 @@ impl ExtensionStore { this.wasm_extensions.extend(wasm_extensions); this.proxy.reload_current_theme(cx); + this.proxy.reload_current_icon_theme(cx); }) .ok(); }) diff --git a/crates/theme/src/settings.rs b/crates/theme/src/settings.rs index 2032b98983906da6fd0cf9ca06e9845a5f9a5cb2..f44e45d549dd4b0c7692c3c027047109884a9781 100644 --- a/crates/theme/src/settings.rs +++ b/crates/theme/src/settings.rs @@ -164,6 +164,30 @@ impl ThemeSettings { } } } + + /// Reloads the current icon theme. + /// + /// Reads the [`ThemeSettings`] to know which icon theme should be loaded. + pub fn reload_current_icon_theme(cx: &mut App) { + let mut theme_settings = ThemeSettings::get_global(cx).clone(); + + let active_theme = theme_settings.active_icon_theme.clone(); + let mut icon_theme_name = active_theme.name.as_ref(); + + // If the selected theme doesn't exist, fall back to the default theme. + let theme_registry = ThemeRegistry::global(cx); + if theme_registry + .get_icon_theme(icon_theme_name) + .ok() + .is_none() + { + icon_theme_name = DEFAULT_ICON_THEME_NAME; + }; + + if let Some(_theme) = theme_settings.switch_icon_theme(icon_theme_name, cx) { + ThemeSettings::override_global(theme_settings, cx); + } + } } /// The appearance of the system. @@ -487,6 +511,24 @@ impl ThemeSettings { self.active_theme = Arc::new(base_theme); } } + + /// Switches to the icon theme with the given name, if it exists. + /// + /// Returns a `Some` containing the new icon theme if it was successful. + /// Returns `None` otherwise. + pub fn switch_icon_theme(&mut self, icon_theme: &str, cx: &mut App) -> Option> { + let themes = ThemeRegistry::default_global(cx); + + let mut new_icon_theme = None; + + if let Some(icon_theme) = themes.get_icon_theme(icon_theme).log_err() { + self.active_icon_theme = icon_theme.clone(); + new_icon_theme = Some(icon_theme); + cx.refresh_windows(); + } + + new_icon_theme + } } // TODO: Make private, change usages to use `get_ui_font_size` instead. diff --git a/crates/theme_extension/src/theme_extension.rs b/crates/theme_extension/src/theme_extension.rs index bce271840c962598520aa05fe9eea5a91167b854..83903da6c69147af52f9d714c497f21674ed1adb 100644 --- a/crates/theme_extension/src/theme_extension.rs +++ b/crates/theme_extension/src/theme_extension.rs @@ -77,4 +77,8 @@ impl ExtensionThemeProxy for ThemeRegistryProxy { .await }) } + + fn reload_current_icon_theme(&self, cx: &mut App) { + ThemeSettings::reload_current_icon_theme(cx) + } }