Keep selected document text readable

This commit is contained in:
OmarGonD committed 2026-10-19 20:32:44 -05:00
1 parent d4c59706d8
commit e42f580510
2 files changed
+90 -1

No files matched your search

+3 -1
View File
@@ -46,7 +46,9 @@ impl Render for LokView {
let focus = self.focus.clone();
let colors = &cx.theme().colors;
let paper = super::paper();
let (selection_color, caret_color) = (colors.selection, colors.focus);
// Opaque overlays hide glyphs already painted in the tiles.
let selection_color = colors.selection.alpha(colors.selection.a.min(0.3));
let caret_color = colors.focus;
let canvas_color = colors.sunken;
let caret_width = cx.theme().caret_width().to_pixels(window.rem_size());
self.handle_size = cx.theme().handle_hit().to_pixels(window.rem_size());
+87
View File
@@ -83,6 +83,93 @@ fn a_dark_app_paints_the_page_white() {
assert!(light > 240, "the view paints the page white: {light}");
}
#[test]
fn selection_keeps_document_text_readable_across_themes() {
use ely_gpui_component::{
devtools::{contrast, over},
theme::{ActiveTheme, Mode, Palette, Theme},
};
let Some(install) = crate::client::tests::install() else {
eprintln!("SKIP: no pinned LOK build");
return;
};
let mut cx = TestAppContext::single();
cx.update(ely_gpui_component::init_for_tests);
let (view, worker) = cx.update(|app| live_view(app, &install));
let doc = cx.update(|app| view.read(app).doc.clone());
let shown = view.clone();
let window = cx.add_window(move |_, _| Host(shown));
worker
.lock()
.expect("the worker")
.run(&doc, "edit.select_all", &[])
.expect("select all");
assert!(
settle(&cx, |app| !view.read(app).selection.is_empty()),
"the selection arrives"
);
let mut themes = vec![
("dark".to_string(), Mode::Dark, None),
("light".to_string(), Mode::Light, None),
];
for (name, mode, color) in [
("omarchy dark", Mode::Dark, 0x292e42),
("omarchy light", Mode::Light, 0xccd0da),
] {
let mut palette = match mode {
Mode::Dark => Palette::dark(false),
Mode::Light => Palette::light(false),
};
palette.selection = gpui::rgb(color).into();
themes.push((name.to_string(), mode, Some(palette)));
}
let mut translucent = Palette::dark(false);
translucent.selection = gpui::rgb(0x292e42).into();
translucent.selection.a = 0.15;
themes.push(("translucent".to_string(), Mode::Dark, Some(translucent)));
for (name, mode, palette) in themes {
cx.update(|app| {
Theme::set_palette(mode, palette, app);
Theme::set_mode_now(mode, app);
});
cx.update_window(window.into(), |_, window, app| {
window.draw(app).clear(app);
let source = app.theme().colors.selection;
let selected: Vec<_> = window
.painted_quads()
.into_iter()
.filter_map(|quad| quad.background.as_solid())
.filter(|color| color.alpha(1.0) == source.alpha(1.0))
.collect();
assert!(!selected.is_empty(), "{name}: the selection is painted");
for color in selected {
for (text, background) in [(gpui::black(), paper()), (gpui::white(), gpui::black())]
{
let ratio = contrast(over(color, text), over(color, background));
assert!(
ratio >= 4.5,
"{name}: selected text stays readable: {ratio}"
);
}
assert!(
color.a > 0.0 && color.a <= source.a,
"{name}: the theme's opacity is respected"
);
if source.a < 0.3 {
assert_eq!(
color.a, source.a,
"{name}: a translucent theme stays unchanged"
);
}
}
})
.expect("the window lives");
}
}
#[test]
fn a_failed_tile_reports_and_retries_on_a_move() {
let Some(install) = crate::client::tests::install() else {