diff --git a/docs/next/CHANGELOG.md b/docs/next/CHANGELOG.md index 428a973d3a..567a70e361 100644 --- a/docs/next/CHANGELOG.md +++ b/docs/next/CHANGELOG.md @@ -19,6 +19,7 @@ - Experimental pane graphics now support bounded named layers, acknowledged full-RGBA primary-layer direct file frames on audited local terminals, owned BGRA fallback, exact pixel mouse input, and placement-only resize replay. ### Fixed +- Text selections remain visible over Mosh and other terminals that do not report their background color. (#2708) - Prefix keybindings now disambiguate layout-aware shifted punctuation, so a shifted `\` no longer triggers `prefix+|` on keyboard layouts where the same key produces both characters. (#2674) - Remote clients now continue redrawing at very large terminal sizes instead of freezing when a full ANSI frame exceeds the transport limit. (#2670) - OpenCode panes now track the root conversation selected in their own TUI for native restore without adopting activity from attached clients. (#2450) diff --git a/src/ui/panes.rs b/src/ui/panes.rs index f20b55b588..91c4b5abf6 100644 --- a/src/ui/panes.rs +++ b/src/ui/panes.rs @@ -875,8 +875,13 @@ fn automatic_selection_style( } fn automatic_selection_bg(p: &Palette, host_theme: crate::terminal_theme::TerminalTheme) -> Color { - let Some(background) = host_theme.background.map(terminal_theme_to_rgb) else { - return selection_palette_background(p); + let fallback = selection_palette_background(p); + let Some(background) = host_theme + .background + .map(terminal_theme_to_rgb) + .or_else(|| color_to_rgb(fallback)) + else { + return fallback; }; let target = if relative_luminance(background) < 0.5 { @@ -1604,4 +1609,33 @@ mod tests { }; assert!(relative_luminance((r, g, b)) > relative_luminance((12, 14, 16))); } + + #[test] + fn automatic_selection_background_contrasts_when_host_background_is_unknown() { + for (panel_bg, should_lighten) in [ + (Color::Rgb(0x2d, 0x35, 0x3b), true), + (Color::Rgb(239, 241, 245), false), + ] { + let mut palette = Palette::catppuccin(); + palette.panel_bg = panel_bg; + let Color::Rgb(r, g, b) = panel_bg else { + unreachable!("test backgrounds are rgb"); + }; + + let selected = + automatic_selection_bg(&palette, crate::terminal_theme::TerminalTheme::default()); + let known_host_selected = automatic_selection_bg( + &palette, + crate::terminal_theme::TerminalTheme { + background: Some(crate::terminal_theme::RgbColor { r, g, b }), + ..Default::default() + }, + ); + let base_luminance = relative_luminance((r, g, b)); + let selected_luminance = relative_luminance(color_to_rgb(selected).unwrap()); + + assert_eq!(selected, known_host_selected); + assert_eq!(selected_luminance > base_luminance, should_lighten); + } + } }