diff --git a/src/ui/presets.rs b/src/ui/presets.rs index 63def966..240de247 100644 --- a/src/ui/presets.rs +++ b/src/ui/presets.rs @@ -438,6 +438,13 @@ pub(crate) fn needs_edge(fill: u32, surface: Hsla) -> bool { contrast(fill, packed) < 1.25 } +/// Whether a surface is dark enough that a halo cut in its own colour stops +/// reading as a ring and starts reading as a hole. +pub(crate) fn surface_is_dark(surface: Hsla) -> bool { + let rgb = crate::terminal::palette::hsla_to_rgb(surface); + is_dark((rgb.r as u32) << 16 | (rgb.g as u32) << 8 | rgb.b as u32) +} + pub(crate) fn mix(a: u32, b: u32, t: f32) -> u32 { let (ar, ag, ab) = (a >> 16 & 0xff, a >> 8 & 0xff, a & 0xff); let (br, bg, bb) = (b >> 16 & 0xff, b >> 8 & 0xff, b & 0xff); diff --git a/src/ui/tab_strip.rs b/src/ui/tab_strip.rs index 751395e1..cecbc858 100644 --- a/src/ui/tab_strip.rs +++ b/src/ui/tab_strip.rs @@ -837,7 +837,15 @@ impl Tty7App { hollow: bool, ) -> gpui::AnyElement { let d = (size * 0.42).max(7.); - let bg = ring; + // The halo was the surface itself, which is only a ring while the + // surface is light — on a dark theme it went near-black and read as a + // notch bitten out of the avatar rather than a badge sitting on it. + // Light themes already ring the dot in white; give the dark ones the + // same white edge, and the hollow Waiting dot the same white hole. + let bg = match crate::ui::presets::surface_is_dark(ring) { + true => gpui::white(), + false => ring, + }; if unread > 0 { let nd = (size * 0.72).max(13.0); let label = unread.min(9).to_string();