Fix theme selector resetting the buffer size (#25425)

Kirill Bulatov created

Closes https://github.com/zed-industries/zed/issues/25413

As the issue points out well, themes do not need to alter any in-memory
state on load: that is done via settings file load.
Originally, it was introduced in
https://github.com/zed-industries/zed/pull/4064 and
https://github.com/zed-industries/zed/pull/24857 had restored that
behavior, which seems wrong to do.

Apart from removing that part, removes unnecessary methods and
emphasizes that in-memory state is the Buffer/UI size — no need to add
`Adjusted` there as the settings file presence is already enough.

Release Notes:

- Fixed theme selector resetting the buffer size

Change summary

crates/assistant2/src/message_editor.rs |  4 
crates/repl/src/outputs/plain.rs        |  3 
crates/theme/src/settings.rs            | 85 +++++++++-----------------
crates/theme/src/theme.rs               | 11 ---
crates/zed/src/zed.rs                   | 10 +-
5 files changed, 39 insertions(+), 74 deletions(-)

Detailed changes

crates/assistant2/src/message_editor.rs 🔗

@@ -13,7 +13,7 @@ use rope::Point;
 use settings::Settings;
 use std::time::Duration;
 use text::Bias;
-use theme::{get_ui_font_size, ThemeSettings};
+use theme::ThemeSettings;
 use ui::{
     prelude::*, ButtonLike, KeyBinding, PopoverMenu, PopoverMenuHandle, Switch, TintColor, Tooltip,
 };
@@ -369,7 +369,7 @@ impl Render for MessageEditor {
                             .anchor(gpui::Corner::BottomLeft)
                             .offset(gpui::Point {
                                 x: px(0.0),
-                                y: (-get_ui_font_size(cx) * 2) - px(4.0),
+                                y: (-ThemeSettings::get_global(cx).ui_font_size(cx) * 2) - px(4.0),
                             })
                             .with_handle(self.inline_context_picker_menu_handle.clone()),
                     )

crates/repl/src/outputs/plain.rs 🔗

@@ -59,6 +59,7 @@ const DEFAULT_NUM_COLUMNS: usize = 128;
 pub fn text_style(window: &mut Window, cx: &mut App) -> TextStyle {
     let settings = ThemeSettings::get_global(cx).clone();
 
+    let font_size = settings.buffer_font_size(cx).into();
     let font_family = settings.buffer_font.family;
     let font_features = settings.buffer_font.features;
     let font_weight = settings.buffer_font.weight;
@@ -71,7 +72,7 @@ pub fn text_style(window: &mut Window, cx: &mut App) -> TextStyle {
         font_features,
         font_weight,
         font_fallbacks,
-        font_size: theme::get_buffer_font_size(cx).into(),
+        font_size,
         font_style: FontStyle::Normal,
         line_height: window.line_height().into(),
         background_color: Some(theme.colors().terminal_ansi_background),

crates/theme/src/settings.rs 🔗

@@ -95,16 +95,12 @@ pub struct ThemeSettings {
     /// as well as the size of a [gpui::Rems] unit.
     ///
     /// Changing this will impact the size of all UI elements.
-    ///
-    /// Use [ThemeSettings::ui_font_size] to access this.
     ui_font_size: Pixels,
     /// The font used for UI elements.
     pub ui_font: Font,
     /// The font size used for buffers, and the terminal.
     ///
     /// The terminal font size can be overridden using it's own setting.
-    ///
-    /// Use [ThemeSettings::buffer_font_size] to access this.
     buffer_font_size: Pixels,
     /// The font used for buffers, and the terminal.
     ///
@@ -246,14 +242,14 @@ impl SystemAppearance {
 }
 
 #[derive(Default)]
-pub(crate) struct AdjustedBufferFontSize(Pixels);
+struct BufferFontSize(Pixels);
 
-impl Global for AdjustedBufferFontSize {}
+impl Global for BufferFontSize {}
 
 #[derive(Default)]
-pub(crate) struct AdjustedUiFontSize(Pixels);
+pub(crate) struct UiFontSize(Pixels);
 
-impl Global for AdjustedUiFontSize {}
+impl Global for UiFontSize {}
 
 /// Represents the selection of a theme, which can be either static or dynamic.
 #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@@ -568,16 +564,18 @@ impl ThemeSettings {
     /// Returns the buffer font size.
     pub fn buffer_font_size(&self, cx: &App) -> Pixels {
         let font_size = cx
-            .try_global::<AdjustedBufferFontSize>()
-            .map_or(self.buffer_font_size, |size| size.0);
+            .try_global::<BufferFontSize>()
+            .map(|size| size.0)
+            .unwrap_or(self.buffer_font_size);
         clamp_font_size(font_size)
     }
 
     /// Returns the UI font size.
     pub fn ui_font_size(&self, cx: &App) -> Pixels {
         let font_size = cx
-            .try_global::<AdjustedUiFontSize>()
-            .map_or(self.ui_font_size, |size| size.0);
+            .try_global::<UiFontSize>()
+            .map(|size| size.0)
+            .unwrap_or(self.ui_font_size);
         clamp_font_size(font_size)
     }
 
@@ -663,51 +661,38 @@ pub fn observe_buffer_font_size_adjustment<V: 'static>(
     cx: &mut Context<V>,
     f: impl 'static + Fn(&mut V, &mut Context<V>),
 ) -> Subscription {
-    cx.observe_global::<AdjustedBufferFontSize>(f)
+    cx.observe_global::<BufferFontSize>(f)
 }
 
-/// Sets the adjusted buffer font size.
+/// Gets the font size, adjusted by the difference between the current buffer font size and the one set in the settings.
 pub fn adjusted_font_size(size: Pixels, cx: &App) -> Pixels {
-    let adjusted_font_size = if let Some(AdjustedBufferFontSize(adjusted_size)) =
-        cx.try_global::<AdjustedBufferFontSize>()
-    {
-        let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
-        let delta = *adjusted_size - buffer_font_size;
-        size + delta
-    } else {
-        size
-    };
+    let adjusted_font_size =
+        if let Some(BufferFontSize(adjusted_size)) = cx.try_global::<BufferFontSize>() {
+            let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
+            let delta = *adjusted_size - buffer_font_size;
+            size + delta
+        } else {
+            size
+        };
     clamp_font_size(adjusted_font_size)
 }
 
-/// Returns the adjusted buffer font size.
-pub fn get_buffer_font_size(cx: &App) -> Pixels {
-    let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
-    cx.try_global::<AdjustedBufferFontSize>()
-        .map_or(buffer_font_size, |adjusted_size| adjusted_size.0)
-}
-
 /// Adjusts the buffer font size.
 pub fn adjust_buffer_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
     let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
     let mut adjusted_size = cx
-        .try_global::<AdjustedBufferFontSize>()
+        .try_global::<BufferFontSize>()
         .map_or(buffer_font_size, |adjusted_size| adjusted_size.0);
 
     f(&mut adjusted_size);
-    cx.set_global(AdjustedBufferFontSize(clamp_font_size(adjusted_size)));
+    cx.set_global(BufferFontSize(clamp_font_size(adjusted_size)));
     cx.refresh_windows();
 }
 
-/// Returns whether the buffer font size has been adjusted.
-pub fn has_adjusted_buffer_font_size(cx: &App) -> bool {
-    cx.has_global::<AdjustedBufferFontSize>()
-}
-
 /// Resets the buffer font size to the default value.
 pub fn reset_buffer_font_size(cx: &mut App) {
-    if cx.has_global::<AdjustedBufferFontSize>() {
-        cx.remove_global::<AdjustedBufferFontSize>();
+    if cx.has_global::<BufferFontSize>() {
+        cx.remove_global::<BufferFontSize>();
         cx.refresh_windows();
     }
 }
@@ -718,41 +703,29 @@ pub fn setup_ui_font(window: &mut Window, cx: &mut App) -> gpui::Font {
     let (ui_font, ui_font_size) = {
         let theme_settings = ThemeSettings::get_global(cx);
         let font = theme_settings.ui_font.clone();
-        (font, get_ui_font_size(cx))
+        (font, theme_settings.ui_font_size(cx))
     };
 
     window.set_rem_size(ui_font_size);
     ui_font
 }
 
-/// Gets the adjusted UI font size.
-pub fn get_ui_font_size(cx: &App) -> Pixels {
-    let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx);
-    cx.try_global::<AdjustedUiFontSize>()
-        .map_or(ui_font_size, |adjusted_size| adjusted_size.0)
-}
-
 /// Sets the adjusted UI font size.
 pub fn adjust_ui_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
     let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx);
     let mut adjusted_size = cx
-        .try_global::<AdjustedUiFontSize>()
+        .try_global::<UiFontSize>()
         .map_or(ui_font_size, |adjusted_size| adjusted_size.0);
 
     f(&mut adjusted_size);
-    cx.set_global(AdjustedUiFontSize(clamp_font_size(adjusted_size)));
+    cx.set_global(UiFontSize(clamp_font_size(adjusted_size)));
     cx.refresh_windows();
 }
 
-/// Returns whether the UI font size has been adjusted.
-pub fn has_adjusted_ui_font_size(cx: &App) -> bool {
-    cx.has_global::<AdjustedUiFontSize>()
-}
-
 /// Resets the UI font size to the default value.
 pub fn reset_ui_font_size(cx: &mut App) {
-    if cx.has_global::<AdjustedUiFontSize>() {
-        cx.remove_global::<AdjustedUiFontSize>();
+    if cx.has_global::<UiFontSize>() {
+        cx.remove_global::<UiFontSize>();
         cx.refresh_windows();
     }
 }

crates/theme/src/theme.rs 🔗

@@ -23,7 +23,6 @@ use std::path::Path;
 use std::sync::Arc;
 
 use ::settings::Settings;
-use ::settings::SettingsStore;
 use anyhow::Result;
 use fallback_themes::apply_status_color_defaults;
 use fs::Fs;
@@ -102,16 +101,6 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
 
     ThemeSettings::register(cx);
     FontFamilyCache::init_global(cx);
-
-    let mut prev_buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size(cx);
-    cx.observe_global::<SettingsStore>(move |cx| {
-        let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size(cx);
-        if buffer_font_size != prev_buffer_font_size {
-            prev_buffer_font_size = buffer_font_size;
-            reset_buffer_font_size(cx);
-        }
-    })
-    .detach();
 }
 
 /// Implementing this trait allows accessing the active theme.

crates/zed/src/zed.rs 🔗

@@ -563,7 +563,7 @@ fn register_actions(
             move |_, action: &zed_actions::IncreaseUiFontSize, _window, cx| {
                 if action.persist {
                     update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                        let ui_font_size = theme::get_ui_font_size(cx) + px(1.0);
+                        let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx) + px(1.0);
                         let _ = settings
                             .ui_font_size
                             .insert(theme::clamp_font_size(ui_font_size).0);
@@ -580,7 +580,7 @@ fn register_actions(
             move |_, action: &zed_actions::DecreaseUiFontSize, _window, cx| {
                 if action.persist {
                     update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                        let ui_font_size = theme::get_ui_font_size(cx) - px(1.0);
+                        let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx) - px(1.0);
                         let _ = settings
                             .ui_font_size
                             .insert(theme::clamp_font_size(ui_font_size).0);
@@ -609,7 +609,8 @@ fn register_actions(
             move |_, action: &zed_actions::IncreaseBufferFontSize, _window, cx| {
                 if action.persist {
                     update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                        let buffer_font_size = theme::get_buffer_font_size(cx) + px(1.0);
+                        let buffer_font_size =
+                            ThemeSettings::get_global(cx).buffer_font_size(cx) + px(1.0);
                         let _ = settings
                             .buffer_font_size
                             .insert(theme::clamp_font_size(buffer_font_size).0);
@@ -626,7 +627,8 @@ fn register_actions(
             move |_, action: &zed_actions::DecreaseBufferFontSize, _window, cx| {
                 if action.persist {
                     update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                        let buffer_font_size = theme::get_buffer_font_size(cx) - px(1.0);
+                        let buffer_font_size =
+                            ThemeSettings::get_global(cx).buffer_font_size(cx) - px(1.0);
                         let _ = settings
                             .buffer_font_size
                             .insert(theme::clamp_font_size(buffer_font_size).0);