From 9c1b2afa492755a1e8cb0a77f929845941c97cdc Mon Sep 17 00:00:00 2001 From: Finn Evers Date: Wed, 7 May 2025 22:15:32 +0200 Subject: [PATCH] theme: Add `scrollbar_thumb_active_background` color (#30177) Follow-up to #28064 This PR adds the `scrollbar_thumb_active_background` to themes and uses it for the editor scrollbars to color these whilst they are being dragged. This way, we provide the best customizabiliy for the scrollbars and enable theme authors to add good contrasts between all the three states `ScrollbarThumbState::Idle`, `ScrollbarThumbState::Hovered` and ScrollbarThumbState::Dragging`. It also adds this to the VsCode theme importer so any future imported themes will have this set as well. Whenever the property is not set, I decided it is best to fall back to the normal `thumb_background` for the time being, as this way the distinction and contrast between hovered and active state is better than having the same color for hovering and dragging the scrollbar. Example with active color set via `experimental.theme_overrides` in the settings: https://github.com/user-attachments/assets/9934e75b-6e0a-4a41-90ba-bfffb89865e7 Release Notes: - Added the `scrollbar.thumb.active_background` color to themes. Theme authors can use this property in combination with `scrollbar.thumb.hover_background` to customize the color of the editor scrollbar thumbs while these are hovered or being dragged. --- crates/editor/src/element.rs | 5 +++- crates/theme/src/default_colors.rs | 2 ++ crates/theme/src/fallback_themes.rs | 6 ++++ crates/theme/src/schema.rs | 28 +++++++++++++------ crates/theme/src/styles/colors.rs | 6 ++++ crates/theme_importer/src/vscode/converter.rs | 4 +++ 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 24e833c1e6735d85bce5393dffe35cb2a9f44454..0f20ac626eee94e2a3ea7022f88a7249e9e763c1 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -5280,7 +5280,10 @@ impl EditorElement { } let scrollbar_thumb_color = match scrollbar_layout.thumb_state { - ScrollbarThumbState::Dragging | ScrollbarThumbState::Hovered => { + ScrollbarThumbState::Dragging => { + cx.theme().colors().scrollbar_thumb_active_background + } + ScrollbarThumbState::Hovered => { cx.theme().colors().scrollbar_thumb_hover_background } ScrollbarThumbState::Idle => cx.theme().colors().scrollbar_thumb_background, diff --git a/crates/theme/src/default_colors.rs b/crates/theme/src/default_colors.rs index 6eca890bdfbe5c0f98466d5a13e66a4a2d53e93f..d6580fe2e136ff32fb58932629c40426c0d330d8 100644 --- a/crates/theme/src/default_colors.rs +++ b/crates/theme/src/default_colors.rs @@ -86,6 +86,7 @@ impl ThemeColors { pane_group_border: neutral().light().step_6(), scrollbar_thumb_background: neutral().light_alpha().step_3(), scrollbar_thumb_hover_background: neutral().light_alpha().step_4(), + scrollbar_thumb_active_background: neutral().light_alpha().step_5(), scrollbar_thumb_border: gpui::transparent_black(), scrollbar_track_background: gpui::transparent_black(), scrollbar_track_border: neutral().light().step_5(), @@ -206,6 +207,7 @@ impl ThemeColors { pane_group_border: neutral().dark().step_6(), scrollbar_thumb_background: neutral().dark_alpha().step_3(), scrollbar_thumb_hover_background: neutral().dark_alpha().step_4(), + scrollbar_thumb_active_background: neutral().dark_alpha().step_5(), scrollbar_thumb_border: gpui::transparent_black(), scrollbar_track_background: gpui::transparent_black(), scrollbar_track_border: neutral().dark().step_5(), diff --git a/crates/theme/src/fallback_themes.rs b/crates/theme/src/fallback_themes.rs index 624cb3aabfc7f5ac732dd2ef98ce19a4b0c48e0c..d907da645b55c68ccd425baacbf7832fc615ba45 100644 --- a/crates/theme/src/fallback_themes.rs +++ b/crates/theme/src/fallback_themes.rs @@ -190,6 +190,12 @@ pub(crate) fn zed_default_dark() -> Theme { pane_group_border: hsla(225. / 360., 13. / 100., 12. / 100., 1.), scrollbar_thumb_background: gpui::transparent_black(), scrollbar_thumb_hover_background: hsla(225.0 / 360., 11.8 / 100., 26.7 / 100., 1.0), + scrollbar_thumb_active_background: hsla( + 225.0 / 360., + 11.8 / 100., + 26.7 / 100., + 1.0, + ), scrollbar_thumb_border: hsla(228. / 360., 8. / 100., 25. / 100., 1.), scrollbar_track_background: gpui::transparent_black(), scrollbar_track_border: hsla(228. / 360., 8. / 100., 25. / 100., 1.), diff --git a/crates/theme/src/schema.rs b/crates/theme/src/schema.rs index 551308eafb0d588320713590e75d062454fa208a..242091d40a01ffe64ff76dc9dbf901c2d13042e0 100644 --- a/crates/theme/src/schema.rs +++ b/crates/theme/src/schema.rs @@ -358,6 +358,10 @@ pub struct ThemeColorsContent { #[serde(rename = "scrollbar.thumb.hover_background")] pub scrollbar_thumb_hover_background: Option, + /// The color of the scrollbar thumb whilst being actively dragged. + #[serde(rename = "scrollbar.thumb.active_background")] + pub scrollbar_thumb_active_background: Option, + /// The border color of the scrollbar thumb. #[serde(rename = "scrollbar.thumb.border")] pub scrollbar_thumb_border: Option, @@ -622,6 +626,15 @@ impl ThemeColorsContent { .editor_document_highlight_read_background .as_ref() .and_then(|color| try_parse_color(color).ok()); + let scrollbar_thumb_background = self + .scrollbar_thumb_background + .as_ref() + .and_then(|color| try_parse_color(color).ok()) + .or_else(|| { + self.deprecated_scrollbar_thumb_background + .as_ref() + .and_then(|color| try_parse_color(color).ok()) + }); ThemeColorsRefinement { border, border_variant: self @@ -805,19 +818,16 @@ impl ThemeColorsContent { .as_ref() .and_then(|color| try_parse_color(color).ok()) .or(border), - scrollbar_thumb_background: self - .scrollbar_thumb_background - .as_ref() - .and_then(|color| try_parse_color(color).ok()) - .or_else(|| { - self.deprecated_scrollbar_thumb_background - .as_ref() - .and_then(|color| try_parse_color(color).ok()) - }), + scrollbar_thumb_background, scrollbar_thumb_hover_background: self .scrollbar_thumb_hover_background .as_ref() .and_then(|color| try_parse_color(color).ok()), + scrollbar_thumb_active_background: self + .scrollbar_thumb_active_background + .as_ref() + .and_then(|color| try_parse_color(color).ok()) + .or(scrollbar_thumb_background), scrollbar_thumb_border: self .scrollbar_thumb_border .as_ref() diff --git a/crates/theme/src/styles/colors.rs b/crates/theme/src/styles/colors.rs index 0310ca698caa67db31a75ef5e588a531cfc2999f..3d0df27985269c534ac80a8bc38d056d97fddb42 100644 --- a/crates/theme/src/styles/colors.rs +++ b/crates/theme/src/styles/colors.rs @@ -135,6 +135,8 @@ pub struct ThemeColors { pub scrollbar_thumb_background: Hsla, /// The color of the scrollbar thumb when hovered over. pub scrollbar_thumb_hover_background: Hsla, + /// The color of the scrollbar thumb whilst being actively dragged. + pub scrollbar_thumb_active_background: Hsla, /// The border color of the scrollbar thumb. pub scrollbar_thumb_border: Hsla, /// The background color of the scrollbar track. @@ -321,6 +323,7 @@ pub enum ThemeColorField { PaneGroupBorder, ScrollbarThumbBackground, ScrollbarThumbHoverBackground, + ScrollbarThumbActiveBackground, ScrollbarThumbBorder, ScrollbarTrackBackground, ScrollbarTrackBorder, @@ -428,6 +431,9 @@ impl ThemeColors { ThemeColorField::PaneGroupBorder => self.pane_group_border, ThemeColorField::ScrollbarThumbBackground => self.scrollbar_thumb_background, ThemeColorField::ScrollbarThumbHoverBackground => self.scrollbar_thumb_hover_background, + ThemeColorField::ScrollbarThumbActiveBackground => { + self.scrollbar_thumb_active_background + } ThemeColorField::ScrollbarThumbBorder => self.scrollbar_thumb_border, ThemeColorField::ScrollbarTrackBackground => self.scrollbar_track_background, ThemeColorField::ScrollbarTrackBorder => self.scrollbar_track_border, diff --git a/crates/theme_importer/src/vscode/converter.rs b/crates/theme_importer/src/vscode/converter.rs index 85ebe0376786d819897fb0ff8a7f1366b48d70a8..99f762589690834f006e27639b5d004adba7bb79 100644 --- a/crates/theme_importer/src/vscode/converter.rs +++ b/crates/theme_importer/src/vscode/converter.rs @@ -167,6 +167,10 @@ impl VsCodeThemeConverter { .scrollbar_slider .hover_background .clone(), + scrollbar_thumb_active_background: vscode_colors + .scrollbar_slider + .active_background + .clone(), scrollbar_thumb_border: vscode_scrollbar_slider_background.clone(), scrollbar_track_background: vscode_editor_background.clone(), scrollbar_track_border: vscode_colors.editor_overview_ruler.border.clone(),