Fall back to One themes if the selected theme doesn't exist (#7911)

Marshall Bowers created

This PR makes it so the One themes—One Dark and One Light—are used as a
fallback when trying to reload a theme that no longer exists in the
registry.

This makes it so when an extension providing the current theme is
removed, the active theme will change to either One Dark or One Light
(based on the system appearance) instead of retaining a cached version
of the theme.

Release Notes:

- Changed the behavior when uninstalling a theme to default to One Dark
or One Light (based on system appearance) rather than keeping a cached
version of the old theme.

Change summary

crates/theme/src/settings.rs | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

Detailed changes

crates/theme/src/settings.rs 🔗

@@ -40,9 +40,20 @@ impl ThemeSettings {
     /// taking into account the current [`SystemAppearance`].
     pub fn reload_current_theme(cx: &mut AppContext) {
         let mut theme_settings = ThemeSettings::get_global(cx).clone();
+        let system_appearance = SystemAppearance::global(cx);
 
         if let Some(theme_selection) = theme_settings.theme_selection.clone() {
-            let theme_name = theme_selection.theme(*SystemAppearance::global(cx));
+            let mut theme_name = theme_selection.theme(*system_appearance);
+
+            // If the selected theme doesn't exist, fall back to a default theme
+            // based on the system appearance.
+            let theme_registry = ThemeRegistry::global(cx);
+            if theme_registry.get(&theme_name).ok().is_none() {
+                theme_name = match *system_appearance {
+                    Appearance::Light => "One Light",
+                    Appearance::Dark => "One Dark",
+                };
+            };
 
             if let Some(_theme) = theme_settings.switch_theme(&theme_name, cx) {
                 ThemeSettings::override_global(theme_settings, cx);