From 903935fd88a52b29f421e250a1cf9b632fe924d9 Mon Sep 17 00:00:00 2001 From: Eduardo Alba Date: Wed, 6 Aug 2025 00:14:45 -0400 Subject: [PATCH 1/4] Add theme mode toggle action Fixes #35552 --- crates/theme_selector/src/theme_selector.rs | 38 +++++++++++++++++++-- crates/zed/src/zed/app_menus.rs | 4 +++ crates/zed_actions/src/lib.rs | 6 ++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 022daced7a..7d4323b6a8 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -7,9 +7,9 @@ use gpui::{ Window, actions, }; use picker::{Picker, PickerDelegate}; -use settings::{SettingsStore, update_settings_file}; +use settings::{Settings as _, SettingsStore, update_settings_file}; use std::sync::Arc; -use theme::{Appearance, Theme, ThemeMeta, ThemeRegistry, ThemeSettings}; +use theme::{Appearance, Theme, ThemeMeta, ThemeMode, ThemeRegistry, ThemeSelection, ThemeSettings}; use ui::{ListItem, ListItemSpacing, prelude::*, v_flex}; use util::ResultExt; use workspace::{ModalView, Workspace, ui::HighlightedLabel, with_active_or_new_workspace}; @@ -38,6 +38,11 @@ pub fn init(cx: &mut App) { toggle_icon_theme_selector(workspace, &action, window, cx); }); }); + cx.on_action(|_: &zed_actions::theme_selector::ToggleMode, cx| { + with_active_or_new_workspace(cx, |workspace, window, cx| { + toggle_theme_mode(workspace, window, cx); + }); + }); } fn toggle_theme_selector( @@ -76,6 +81,35 @@ fn toggle_icon_theme_selector( }); } +fn toggle_theme_mode( + workspace: &mut Workspace, + _window: &mut Window, + cx: &mut Context, +) { + let current_settings = ThemeSettings::get_global(cx); + let current_selection = current_settings.theme_selection.as_ref(); + + let new_mode = match current_selection { + Some(ThemeSelection::Dynamic { mode, .. }) => { + match mode { + ThemeMode::Light => ThemeMode::Dark, + ThemeMode::Dark => ThemeMode::System, + ThemeMode::System => ThemeMode::Light, + } + } + Some(ThemeSelection::Static(_)) => ThemeMode::Light, + None => ThemeMode::Light + }; + + let fs = workspace.app_state().fs.clone(); + + update_settings_file::(fs, cx, move |settings, _| { + settings.set_mode(new_mode); + }); + + ThemeSettings::reload_current_theme(cx); +} + impl ModalView for ThemeSelector {} struct ThemeSelector { diff --git a/crates/zed/src/zed/app_menus.rs b/crates/zed/src/zed/app_menus.rs index 15d5659f03..398f35838e 100644 --- a/crates/zed/src/zed/app_menus.rs +++ b/crates/zed/src/zed/app_menus.rs @@ -32,6 +32,10 @@ pub fn app_menus() -> Vec { "Select Theme...", zed_actions::theme_selector::Toggle::default(), ), + MenuItem::action( + "Toggle Theme Mode", + zed_actions::theme_selector::ToggleMode, + ), ], }), MenuItem::separator(), diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 64891b6973..1c2fbef797 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -243,6 +243,12 @@ pub mod theme_selector { /// A list of theme names to filter the theme selector down to. pub themes_filter: Option>, } + + /// Toggles between light, dark, and system theme modes. + #[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)] + #[action(namespace = theme_selector)] + #[serde(deny_unknown_fields)] + pub struct ToggleMode; } pub mod icon_theme_selector { From 4d46f74470e7685da9a020716c8049ac5a8c2f8a Mon Sep 17 00:00:00 2001 From: Eduardo Alba Date: Wed, 6 Aug 2025 02:01:32 -0400 Subject: [PATCH 2/4] Format code with rustfmt --- crates/theme_selector/src/theme_selector.rs | 32 +++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 7d4323b6a8..8fcdb4930a 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -9,7 +9,9 @@ use gpui::{ use picker::{Picker, PickerDelegate}; use settings::{Settings as _, SettingsStore, update_settings_file}; use std::sync::Arc; -use theme::{Appearance, Theme, ThemeMeta, ThemeMode, ThemeRegistry, ThemeSelection, ThemeSettings}; +use theme::{ + Appearance, Theme, ThemeMeta, ThemeMode, ThemeRegistry, ThemeSelection, ThemeSettings, +}; use ui::{ListItem, ListItemSpacing, prelude::*, v_flex}; use util::ResultExt; use workspace::{ModalView, Workspace, ui::HighlightedLabel, with_active_or_new_workspace}; @@ -81,32 +83,26 @@ fn toggle_icon_theme_selector( }); } -fn toggle_theme_mode( - workspace: &mut Workspace, - _window: &mut Window, - cx: &mut Context, -) { +fn toggle_theme_mode(workspace: &mut Workspace, _window: &mut Window, cx: &mut Context) { let current_settings = ThemeSettings::get_global(cx); let current_selection = current_settings.theme_selection.as_ref(); - + let new_mode = match current_selection { - Some(ThemeSelection::Dynamic { mode, .. }) => { - match mode { - ThemeMode::Light => ThemeMode::Dark, - ThemeMode::Dark => ThemeMode::System, - ThemeMode::System => ThemeMode::Light, - } - } + Some(ThemeSelection::Dynamic { mode, .. }) => match mode { + ThemeMode::Light => ThemeMode::Dark, + ThemeMode::Dark => ThemeMode::System, + ThemeMode::System => ThemeMode::Light, + }, Some(ThemeSelection::Static(_)) => ThemeMode::Light, - None => ThemeMode::Light + None => ThemeMode::Light, }; - + let fs = workspace.app_state().fs.clone(); - + update_settings_file::(fs, cx, move |settings, _| { settings.set_mode(new_mode); }); - + ThemeSettings::reload_current_theme(cx); } From 427f799018f73663be3677b19d18bd0705d57550 Mon Sep 17 00:00:00 2001 From: Eduardo Alba Date: Wed, 6 Aug 2025 10:28:41 -0400 Subject: [PATCH 3/4] Rename 'toggle theme mode' to 'cycle theme mode' --- crates/theme_selector/src/theme_selector.rs | 6 +++--- crates/zed/src/zed/app_menus.rs | 4 ++-- crates/zed_actions/src/lib.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 8fcdb4930a..90606fedc3 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -40,9 +40,9 @@ pub fn init(cx: &mut App) { toggle_icon_theme_selector(workspace, &action, window, cx); }); }); - cx.on_action(|_: &zed_actions::theme_selector::ToggleMode, cx| { + cx.on_action(|_: &zed_actions::theme_selector::CycleMode, cx| { with_active_or_new_workspace(cx, |workspace, window, cx| { - toggle_theme_mode(workspace, window, cx); + cycle_theme_mode(workspace, window, cx); }); }); } @@ -83,7 +83,7 @@ fn toggle_icon_theme_selector( }); } -fn toggle_theme_mode(workspace: &mut Workspace, _window: &mut Window, cx: &mut Context) { +fn cycle_theme_mode(workspace: &mut Workspace, _window: &mut Window, cx: &mut Context) { let current_settings = ThemeSettings::get_global(cx); let current_selection = current_settings.theme_selection.as_ref(); diff --git a/crates/zed/src/zed/app_menus.rs b/crates/zed/src/zed/app_menus.rs index 398f35838e..bcd2372105 100644 --- a/crates/zed/src/zed/app_menus.rs +++ b/crates/zed/src/zed/app_menus.rs @@ -33,8 +33,8 @@ pub fn app_menus() -> Vec { zed_actions::theme_selector::Toggle::default(), ), MenuItem::action( - "Toggle Theme Mode", - zed_actions::theme_selector::ToggleMode, + "Cycle Theme Mode", + zed_actions::theme_selector::CycleMode, ), ], }), diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 1c2fbef797..75debcb8f3 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -244,11 +244,11 @@ pub mod theme_selector { pub themes_filter: Option>, } - /// Toggles between light, dark, and system theme modes. + /// Cycles between light, dark, and system theme modes. #[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)] #[action(namespace = theme_selector)] #[serde(deny_unknown_fields)] - pub struct ToggleMode; + pub struct CycleMode; } pub mod icon_theme_selector { From e9c2796034ac9a91d0835bc4b9525727ca58b688 Mon Sep 17 00:00:00 2001 From: Eduardo Alba Date: Tue, 12 Aug 2025 19:09:29 -0400 Subject: [PATCH 4/4] Rename 'cycle theme mode' to 'toggle theme mode' and toggle only between light and dark --- crates/theme_selector/src/theme_selector.rs | 16 +++++++++++----- crates/zed/src/zed/app_menus.rs | 4 ++-- crates/zed_actions/src/lib.rs | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 90606fedc3..ebbda6115f 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -40,9 +40,9 @@ pub fn init(cx: &mut App) { toggle_icon_theme_selector(workspace, &action, window, cx); }); }); - cx.on_action(|_: &zed_actions::theme_selector::CycleMode, cx| { + cx.on_action(|_: &zed_actions::theme_selector::ToggleMode, cx| { with_active_or_new_workspace(cx, |workspace, window, cx| { - cycle_theme_mode(workspace, window, cx); + toggle_theme_mode(workspace, window, cx); }); }); } @@ -83,15 +83,21 @@ fn toggle_icon_theme_selector( }); } -fn cycle_theme_mode(workspace: &mut Workspace, _window: &mut Window, cx: &mut Context) { +fn toggle_theme_mode(workspace: &mut Workspace, _window: &mut Window, cx: &mut Context) { let current_settings = ThemeSettings::get_global(cx); let current_selection = current_settings.theme_selection.as_ref(); let new_mode = match current_selection { Some(ThemeSelection::Dynamic { mode, .. }) => match mode { ThemeMode::Light => ThemeMode::Dark, - ThemeMode::Dark => ThemeMode::System, - ThemeMode::System => ThemeMode::Light, + ThemeMode::Dark => ThemeMode::Light, + ThemeMode::System => { + if cx.theme().appearance().is_light() { + ThemeMode::Dark + } else { + ThemeMode::Light + } + } }, Some(ThemeSelection::Static(_)) => ThemeMode::Light, None => ThemeMode::Light, diff --git a/crates/zed/src/zed/app_menus.rs b/crates/zed/src/zed/app_menus.rs index bcd2372105..398f35838e 100644 --- a/crates/zed/src/zed/app_menus.rs +++ b/crates/zed/src/zed/app_menus.rs @@ -33,8 +33,8 @@ pub fn app_menus() -> Vec { zed_actions::theme_selector::Toggle::default(), ), MenuItem::action( - "Cycle Theme Mode", - zed_actions::theme_selector::CycleMode, + "Toggle Theme Mode", + zed_actions::theme_selector::ToggleMode, ), ], }), diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 75debcb8f3..c243687b98 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -244,11 +244,11 @@ pub mod theme_selector { pub themes_filter: Option>, } - /// Cycles between light, dark, and system theme modes. + /// Toggles between light and dark theme modes. #[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)] #[action(namespace = theme_selector)] #[serde(deny_unknown_fields)] - pub struct CycleMode; + pub struct ToggleMode; } pub mod icon_theme_selector {