diff --git a/extra/man/rio.5.scd b/extra/man/rio.5.scd index 7640d973cf..2ca31759c1 100644 --- a/extra/man/rio.5.scd +++ b/extra/man/rio.5.scd @@ -232,7 +232,7 @@ Colors are specified using their hexadecimal values with a _#_ prefix: _#RRGGBB_ *tabs-active* = _""_ - Active tab title color. + Active tab title color. Defaults to *foreground*. *split* = _""_ diff --git a/frontends/rioterm/src/renderer/mod.rs b/frontends/rioterm/src/renderer/mod.rs index 62f7c11145..f915de8d0a 100644 --- a/frontends/rioterm/src/renderer/mod.rs +++ b/frontends/rioterm/src/renderer/mod.rs @@ -230,7 +230,7 @@ impl Renderer { let island = if config.navigation.is_enabled() { Some(island::Island::new( named_colors.tabs, - named_colors.tabs_active, + named_colors.tabs_active_or_foreground(), config.navigation.hide_if_single, config.navigation.max_tab_width, )) diff --git a/frontends/rioterm/src/screen/mod.rs b/frontends/rioterm/src/screen/mod.rs index 1c13ed9fc0..b2675d2cca 100644 --- a/frontends/rioterm/src/screen/mod.rs +++ b/frontends/rioterm/src/screen/mod.rs @@ -555,7 +555,10 @@ impl Screen<'_> { self.renderer = Renderer::new(config); self.renderer.is_window_focused = was_focused; if let Some(mut island) = old_island { - island.update_colors(config.colors.tabs, config.colors.tabs_active); + island.update_colors( + config.colors.tabs, + config.colors.tabs_active_or_foreground(), + ); island.max_tab_width = config.navigation.max_tab_width; self.renderer.island = Some(island); } diff --git a/rio-backend/src/config/mod.rs b/rio-backend/src/config/mod.rs index d9f2ab128b..46ae50e212 100644 --- a/rio-backend/src/config/mod.rs +++ b/rio-backend/src/config/mod.rs @@ -819,7 +819,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -840,7 +840,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -860,7 +860,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -880,7 +880,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!( result.colors.selection_background, colors::defaults::selection_background() @@ -908,7 +908,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -927,7 +927,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -946,7 +946,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -1010,7 +1010,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -1028,7 +1028,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -1055,7 +1055,7 @@ mod tests { ); // Colors - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); assert_eq!(result.colors.foreground, hex_to_color_arr("#F8F8F2")); assert_eq!(result.colors.background.0, hex_to_color_arr("#2B3E50")); @@ -1073,10 +1073,42 @@ mod tests { assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, [0.0, 0.0, 0.0, 1.0]); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } + #[test] + fn test_tabs_active_falls_back_to_foreground() { + let result = create_temporary_config( + "tabs-active-fallback", + r#" + [colors] + background = '#EFF1F5' + foreground = '#4C4F69' + "#, + ); + + assert_eq!(result.colors.tabs_active, None); + assert_eq!( + result.colors.tabs_active_or_foreground(), + hex_to_color_arr("#4C4F69") + ); + + let result = create_temporary_config( + "tabs-active-explicit", + r#" + [colors] + foreground = '#4C4F69' + tabs-active = '#E6DB74' + "#, + ); + + assert_eq!( + result.colors.tabs_active_or_foreground(), + hex_to_color_arr("#E6DB74") + ); + } + #[test] fn test_change_colors() { let result = create_temporary_config( @@ -1130,7 +1162,7 @@ mod tests { assert_eq!(result.colors.background.1, hex_to_color_wgpu("#2B3E50")); assert_eq!(result.colors.cursor, hex_to_color_arr("#E6DB74")); assert_eq!(result.colors.foreground, hex_to_color_arr("#F8F8F2")); - assert_eq!(result.colors.tabs_active, hex_to_color_arr("#E6DB74")); + assert_eq!(result.colors.tabs_active, Some(hex_to_color_arr("#E6DB74"))); assert_eq!(result.colors.black, hex_to_color_arr("#FFFFFF")); assert_eq!(result.colors.blue, hex_to_color_arr("#030303")); assert_eq!(result.colors.cyan, hex_to_color_arr("#030303")); @@ -1170,7 +1202,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } @@ -1236,7 +1268,7 @@ mod tests { // Colors assert_eq!(result.colors.background, colors::defaults::background()); assert_eq!(result.colors.foreground, colors::defaults::foreground()); - assert_eq!(result.colors.tabs_active, colors::defaults::tabs_active()); + assert_eq!(result.colors.tabs_active, None); assert_eq!(result.colors.cursor, colors::defaults::cursor()); } diff --git a/rio-vt/src/config/colors/defaults.rs b/rio-vt/src/config/colors/defaults.rs index 4b0af2d40a..e6efa0bbf9 100644 --- a/rio-vt/src/config/colors/defaults.rs +++ b/rio-vt/src/config/colors/defaults.rs @@ -39,11 +39,6 @@ pub fn tabs() -> ColorArray { .to_arr() } -#[inline] -pub fn tabs_active() -> ColorArray { - [1., 1., 1., 1.] -} - #[inline] pub fn foreground() -> ColorArray { [1., 1., 1., 1.] diff --git a/rio-vt/src/config/colors/mod.rs b/rio-vt/src/config/colors/mod.rs index dac598de49..ebb1f9deac 100644 --- a/rio-vt/src/config/colors/mod.rs +++ b/rio-vt/src/config/colors/mod.rs @@ -116,12 +116,15 @@ pub struct Colors { pub red: ColorArray, #[serde(deserialize_with = "deserialize_to_arr", default = "defaults::yellow")] pub yellow: ColorArray, + /// Active tab title color. When unset, the title uses `foreground`, + /// which the theme already pairs with its background — a fixed + /// default can't suit both the dark and the light island fills. #[serde( - deserialize_with = "deserialize_to_arr", - default = "defaults::tabs_active", + default = "Option::default", + deserialize_with = "deserialize_to_arr_opt", rename = "tabs-active" )] - pub tabs_active: ColorArray, + pub tabs_active: Option, #[serde(default = "defaults::cursor", deserialize_with = "deserialize_to_arr")] pub cursor: ColorArray, #[serde( @@ -306,6 +309,14 @@ pub struct Colors { pub hint_background: ColorArray, } +impl Colors { + /// Resolved active tab title color: `tabs-active`, else `foreground`. + #[inline] + pub fn tabs_active_or_foreground(&self) -> ColorArray { + self.tabs_active.unwrap_or(self.foreground) + } +} + impl Default for Colors { fn default() -> Colors { Colors { @@ -316,7 +327,7 @@ impl Default for Colors { red: defaults::red(), yellow: defaults::yellow(), tabs: defaults::tabs(), - tabs_active: defaults::tabs_active(), + tabs_active: None, cursor: defaults::cursor(), split: defaults::split(), split_active: defaults::split_active(),