editor: Do not correct text contrast on non-opaque editor (#37471)

We don’t know the background color behind a non-opaque editor, so we
should skip contrast correction in that case. This prevents
single-editor mode (which is always transparent) from showing weird text
colors when text is selected.

We can’t account for the actual background during contrast correction
because we compute contrast outside gpui, while the actual color
blending happens inside gpui during drawing.

<img width="522" height="145" alt="image"
src="https://github.com/user-attachments/assets/6ee71475-f666-482d-87e6-15cf4c4fceef"
/>

Release Notes:

- Fixed an issue where Command Palette text looked faded when selected.
This commit is contained in:
Smit Barmase
2025-09-04 00:03:48 +05:30
committed by GitHub
parent c3480c3d6f
commit 13de400a2a
2 changed files with 11 additions and 2 deletions
+6 -2
View File
@@ -3284,6 +3284,10 @@ impl EditorElement {
if rows.start >= rows.end {
return Vec::new();
}
if !base_background.is_opaque() {
// We don't actually know what color is behind this editor.
return Vec::new();
}
let highlight_iter = highlight_ranges.iter().cloned();
let selection_iter = selections.iter().flat_map(|(player_color, layouts)| {
let color = player_color.selection;
@@ -11005,7 +11009,7 @@ mod tests {
#[gpui::test]
fn test_merge_overlapping_ranges() {
let base_bg = Hsla::default();
let base_bg = Hsla::white();
let color1 = Hsla {
h: 0.0,
s: 0.5,
@@ -11075,7 +11079,7 @@ mod tests {
#[gpui::test]
fn test_bg_segments_per_row() {
let base_bg = Hsla::default();
let base_bg = Hsla::white();
// Case A: selection spans three display rows: row 1 [5, end), full row 2, row 3 [0, 7)
{
+5
View File
@@ -473,6 +473,11 @@ impl Hsla {
self.a == 0.0
}
/// Returns true if the HSLA color is fully opaque, false otherwise.
pub fn is_opaque(&self) -> bool {
self.a == 1.0
}
/// Blends `other` on top of `self` based on `other`'s alpha value. The resulting color is a combination of `self`'s and `other`'s colors.
///
/// If `other`'s alpha value is 1.0 or greater, `other` color is fully opaque, thus `other` is returned as the output color.