Adds a way to toggle font size without settings adjustments (#24857)

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

Now `zed::IncreaseBufferFontSize` (and all the same UI- and
Buffer-related settings) action is parameterized with `{ "persist": true
}` (default).
Using `"persist": false` brings back resizing behavior prior to
https://github.com/zed-industries/zed/pull/23265


Release Notes:

- Added a way to toggle font size without settings adjustments
This commit is contained in:
Kirill Bulatov 2025-02-14 13:27:48 +02:00 committed by GitHub
parent 2f734cbd5e
commit 3b91de8003
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 251 additions and 80 deletions

View file

@ -6,7 +6,8 @@ use crate::{
use anyhow::Result;
use derive_more::{Deref, DerefMut};
use gpui::{
px, App, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels, Window,
px, App, Context, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels,
Subscription, Window,
};
use refineable::Refineable;
use schemars::{
@ -234,6 +235,16 @@ impl SystemAppearance {
}
}
#[derive(Default)]
pub(crate) struct AdjustedBufferFontSize(Pixels);
impl Global for AdjustedBufferFontSize {}
#[derive(Default)]
pub(crate) struct AdjustedUiFontSize(Pixels);
impl Global for AdjustedUiFontSize {}
/// Represents the selection of a theme, which can be either static or dynamic.
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[serde(untagged)]
@ -545,13 +556,10 @@ impl BufferLineHeight {
impl ThemeSettings {
/// Returns the buffer font size.
pub fn buffer_font_size(&self) -> Pixels {
Self::clamp_font_size(self.buffer_font_size)
}
/// Ensures that the font size is within the valid range.
pub fn clamp_font_size(size: Pixels) -> Pixels {
size.max(MIN_FONT_SIZE)
pub fn buffer_font_size(&self, cx: &App) -> Pixels {
cx.try_global::<AdjustedBufferFontSize>()
.map_or(self.buffer_font_size, |size| size.0)
.max(MIN_FONT_SIZE)
}
// TODO: Rename: `line_height` -> `buffer_line_height`
@ -626,19 +634,105 @@ impl ThemeSettings {
}
}
/// Observe changes to the adjusted buffer font size.
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)
}
/// Sets the adjusted buffer font size.
pub fn adjusted_font_size(size: Pixels, cx: &App) -> Pixels {
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
}
.max(MIN_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>()
.map_or(buffer_font_size, |adjusted_size| adjusted_size.0);
f(&mut adjusted_size);
adjusted_size = adjusted_size.max(MIN_FONT_SIZE);
cx.set_global(AdjustedBufferFontSize(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>();
cx.refresh_windows();
}
}
// TODO: Make private, change usages to use `get_ui_font_size` instead.
#[allow(missing_docs)]
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, theme_settings.ui_font_size)
(font, get_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.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;
let mut adjusted_size = cx
.try_global::<AdjustedUiFontSize>()
.map_or(ui_font_size, |adjusted_size| adjusted_size.0);
f(&mut adjusted_size);
adjusted_size = adjusted_size.max(MIN_FONT_SIZE);
cx.set_global(AdjustedUiFontSize(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>();
cx.refresh_windows();
}
}
fn clamp_font_weight(weight: f32) -> FontWeight {
FontWeight(weight.clamp(100., 950.))
}

View file

@ -23,6 +23,7 @@ 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;
@ -101,6 +102,16 @@ 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.observe_global::<SettingsStore>(move |cx| {
let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
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.