diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-08-14 05:01:12 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-14 05:01:12 +0300 |
| commit | d2c317adc4b5fd73a7054d74f92d633a31069391 (patch) | |
| tree | c3db5184138d7eaaff9be05049d120a727a4e128 /src/app | |
| parent | 1af1a5b86f642ae7b053037bc472913cfbc1e206 (diff) | |
fix: keep active sidebar rows visible (#2794)
refs #2792
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/state.rs | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/src/app/state.rs b/src/app/state.rs index cb687363..ea550472 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -73,6 +73,8 @@ pub struct Palette { pub panel_bg: Color, /// Optional desktop sidebar background. Reset preserves the terminal background. pub sidebar_bg: Color, + /// Background for the active workspace and focused agent rows. + pub active_row_bg: Color, /// Subtle surface background for selected/focused items. pub surface0: Color, /// Slightly lighter surface for hover/active states. @@ -110,6 +112,7 @@ impl Palette { accent: Color::Rgb(137, 180, 250), // blue panel_bg: Color::Rgb(24, 24, 37), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(49, 50, 68), surface0: Color::Rgb(49, 50, 68), surface1: Color::Rgb(69, 71, 90), surface_dim: Color::Rgb(30, 30, 46), @@ -133,6 +136,7 @@ impl Palette { accent: Color::Rgb(30, 102, 245), panel_bg: Color::Rgb(239, 241, 245), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(204, 208, 218), surface0: Color::Rgb(204, 208, 218), surface1: Color::Rgb(188, 192, 204), surface_dim: Color::Rgb(230, 233, 239), @@ -156,6 +160,7 @@ impl Palette { accent: Color::Blue, panel_bg: Color::Reset, sidebar_bg: Color::Reset, + active_row_bg: Color::DarkGray, surface0: Color::Reset, surface1: Color::DarkGray, surface_dim: Color::DarkGray, @@ -179,6 +184,7 @@ impl Palette { accent: Color::Rgb(122, 162, 247), // blue panel_bg: Color::Rgb(26, 27, 38), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(47, 51, 77), surface0: Color::Rgb(36, 40, 59), surface1: Color::Rgb(65, 72, 104), surface_dim: Color::Rgb(26, 27, 38), @@ -202,6 +208,7 @@ impl Palette { accent: Color::Rgb(46, 125, 233), panel_bg: Color::Rgb(225, 226, 231), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(196, 200, 218), surface0: Color::Rgb(196, 200, 218), surface1: Color::Rgb(168, 174, 203), surface_dim: Color::Rgb(210, 211, 218), @@ -225,6 +232,7 @@ impl Palette { accent: Color::Rgb(189, 147, 249), // purple panel_bg: Color::Rgb(40, 42, 54), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(68, 71, 90), surface0: Color::Rgb(68, 71, 90), surface1: Color::Rgb(98, 114, 164), surface_dim: Color::Rgb(40, 42, 54), @@ -248,6 +256,7 @@ impl Palette { accent: Color::Rgb(136, 192, 208), // frost panel_bg: Color::Rgb(46, 52, 64), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(67, 76, 94), surface0: Color::Rgb(59, 66, 82), surface1: Color::Rgb(67, 76, 94), surface_dim: Color::Rgb(46, 52, 64), @@ -271,6 +280,7 @@ impl Palette { accent: Color::Rgb(215, 153, 33), // yellow panel_bg: Color::Rgb(40, 40, 40), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(80, 73, 69), surface0: Color::Rgb(60, 56, 54), surface1: Color::Rgb(80, 73, 69), surface_dim: Color::Rgb(40, 40, 40), @@ -294,6 +304,7 @@ impl Palette { accent: Color::Rgb(7, 102, 120), panel_bg: Color::Rgb(251, 241, 199), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(213, 196, 161), surface0: Color::Rgb(235, 219, 178), surface1: Color::Rgb(213, 196, 161), surface_dim: Color::Rgb(242, 229, 188), @@ -317,6 +328,7 @@ impl Palette { accent: Color::Rgb(97, 175, 239), // blue panel_bg: Color::Rgb(40, 44, 52), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(62, 68, 81), surface0: Color::Rgb(44, 49, 58), surface1: Color::Rgb(62, 68, 81), surface_dim: Color::Rgb(40, 44, 52), @@ -340,6 +352,7 @@ impl Palette { accent: Color::Rgb(64, 120, 242), panel_bg: Color::Rgb(250, 250, 250), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(216, 219, 226), surface0: Color::Rgb(240, 240, 241), surface1: Color::Rgb(229, 229, 230), surface_dim: Color::Rgb(245, 245, 246), @@ -363,6 +376,7 @@ impl Palette { accent: Color::Rgb(38, 139, 210), // blue panel_bg: Color::Rgb(0, 43, 54), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(22, 75, 87), surface0: Color::Rgb(7, 54, 66), surface1: Color::Rgb(88, 110, 117), surface_dim: Color::Rgb(0, 43, 54), @@ -386,6 +400,7 @@ impl Palette { accent: Color::Rgb(38, 139, 210), panel_bg: Color::Rgb(253, 246, 227), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(222, 216, 198), surface0: Color::Rgb(238, 232, 213), surface1: Color::Rgb(147, 161, 161), surface_dim: Color::Rgb(238, 232, 213), @@ -409,6 +424,7 @@ impl Palette { accent: Color::Rgb(126, 156, 216), // blue panel_bg: Color::Rgb(31, 31, 40), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(54, 54, 70), surface0: Color::Rgb(42, 42, 55), surface1: Color::Rgb(54, 54, 70), surface_dim: Color::Rgb(31, 31, 40), @@ -432,6 +448,7 @@ impl Palette { accent: Color::Rgb(77, 105, 155), panel_bg: Color::Rgb(242, 236, 188), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(201, 203, 209), surface0: Color::Rgb(220, 213, 172), surface1: Color::Rgb(201, 203, 209), surface_dim: Color::Rgb(213, 206, 163), @@ -455,6 +472,7 @@ impl Palette { accent: Color::Rgb(196, 167, 231), // iris panel_bg: Color::Rgb(25, 23, 36), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(64, 61, 82), surface0: Color::Rgb(31, 29, 46), surface1: Color::Rgb(38, 35, 58), surface_dim: Color::Rgb(38, 35, 58), @@ -478,6 +496,7 @@ impl Palette { accent: Color::Rgb(144, 122, 169), panel_bg: Color::Rgb(250, 244, 237), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(227, 217, 207), surface0: Color::Rgb(242, 233, 225), surface1: Color::Rgb(255, 250, 243), surface_dim: Color::Rgb(242, 233, 225), @@ -501,6 +520,7 @@ impl Palette { accent: Color::Rgb(255, 199, 153), panel_bg: Color::Rgb(26, 26, 26), sidebar_bg: Color::Reset, + active_row_bg: Color::Rgb(51, 51, 51), surface0: Color::Rgb(35, 35, 35), surface1: Color::Rgb(40, 40, 40), surface_dim: Color::Rgb(16, 16, 16), @@ -555,6 +575,9 @@ impl Palette { if let Some(c) = &custom.sidebar_bg { self.sidebar_bg = parse_color(c); } + if let Some(c) = &custom.active_row_bg { + self.active_row_bg = parse_color(c); + } if let Some(c) = &custom.surface0 { self.surface0 = parse_color(c); } @@ -2331,6 +2354,30 @@ mod tests { assert_eq!(navigator_first_row_at_or_after(&lines, 4), None); } + fn rgb_luminance(color: Color) -> f64 { + let Color::Rgb(r, g, b) = color else { + panic!("expected RGB color, got {color:?}"); + }; + let channel = |value: u8| { + let value = f64::from(value) / 255.0; + if value <= 0.04045 { + value / 12.92 + } else { + ((value + 0.055) / 1.055).powf(2.4) + } + }; + 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b) + } + + fn contrast_ratio(a: Color, b: Color) -> f64 { + let (lighter, darker) = { + let a = rgb_luminance(a); + let b = rgb_luminance(b); + (a.max(b), a.min(b)) + }; + (lighter + 0.05) / (darker + 0.05) + } + #[test] fn built_in_theme_names_resolve() { for name in THEME_NAMES { @@ -2342,6 +2389,32 @@ mod tests { } #[test] + fn built_in_active_rows_remain_visible_with_matching_terminal_backgrounds() { + for name in THEME_NAMES + .iter() + .copied() + .filter(|name| *name != "terminal") + { + let palette = Palette::from_name(name).unwrap(); + let background_contrast = contrast_ratio(palette.panel_bg, palette.active_row_bg); + assert!( + background_contrast >= 1.25, + "active row blends into the matching terminal background for {name}: {background_contrast:.2}:1" + ); + + let text_contrast = contrast_ratio(palette.text, palette.active_row_bg); + assert!( + text_contrast >= 3.0, + "active row text loses contrast for {name}: {text_contrast:.2}:1" + ); + assert_ne!( + palette.active_row_bg, palette.surface_dim, + "active row still shares the separator color for {name}" + ); + } + } + + #[test] fn built_in_themes_leave_sidebar_background_unset() { for name in THEME_NAMES { let palette = Palette::from_name(name).unwrap(); @@ -2354,16 +2427,16 @@ mod tests { } #[test] - fn custom_sidebar_background_overrides_the_default() { + fn custom_sidebar_colors_override_the_defaults() { let custom = crate::config::CustomThemeColors { sidebar_bg: Some("#181825".to_string()), + active_row_bg: Some("#313244".to_string()), ..Default::default() }; + let palette = Palette::catppuccin().with_overrides(&custom); - assert_eq!( - Palette::catppuccin().with_overrides(&custom).sidebar_bg, - Color::Rgb(24, 24, 37) - ); + assert_eq!(palette.sidebar_bg, Color::Rgb(24, 24, 37)); + assert_eq!(palette.active_row_bg, Color::Rgb(49, 50, 68)); } #[test] |
