From 8f0efe9f34d524345e293297ee4389a2378a453c Mon Sep 17 00:00:00 2001 From: Cameron Mcloughlin Date: Wed, 22 Apr 2026 11:22:14 +0100 Subject: [PATCH] editor: Don't render editor behind sticky scroll header (#54465) Previously, sticky scroll headers were painted on top of the main editor. This works, but only if the editor background is a solid color Bad: image Good: image Release Notes: - Fixed: Editor no longer renders behind sticky scroll headers while using a transparent theme --- crates/editor/src/element.rs | 67 +++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 4162bc9c99dd80ac12b6770d0f9d77c1d2286393..3c01c12b42c2b7b31158cbc0ad63ad7374bb9991 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -11127,33 +11127,58 @@ impl Element for EditorElement { window.with_text_style(Some(text_style), |window| { window.with_content_mask(Some(ContentMask { bounds }), |window| { self.paint_mouse_listeners(layout, window, cx); - self.paint_background(layout, window, cx); - self.paint_indent_guides(layout, window, cx); + // Mask the editor behind sticky scroll headers. Important + // for transparent backgrounds. + let below_sticky_headers_mask = layout + .sticky_headers + .as_ref() + .and_then(|h| h.lines.last()) + .map(|last| ContentMask { + bounds: Bounds { + origin: point( + bounds.origin.x, + bounds.origin.y + last.offset + layout.position_map.line_height, + ), + size: size( + bounds.size.width, + (bounds.size.height + - last.offset + - layout.position_map.line_height) + .max(Pixels::ZERO), + ), + }, + }); - if layout.gutter_hitbox.size.width > Pixels::ZERO { - self.paint_blamed_display_rows(layout, window, cx); - self.paint_line_numbers(layout, window, cx); - } + window.with_content_mask(below_sticky_headers_mask, |window| { + self.paint_background(layout, window, cx); - self.paint_text(layout, window, cx); + self.paint_indent_guides(layout, window, cx); - if !layout.spacer_blocks.is_empty() { - window.with_element_namespace("blocks", |window| { - self.paint_spacer_blocks(layout, window, cx); - }); - } + if layout.gutter_hitbox.size.width > Pixels::ZERO { + self.paint_blamed_display_rows(layout, window, cx); + self.paint_line_numbers(layout, window, cx); + } - if layout.gutter_hitbox.size.width > Pixels::ZERO { - self.paint_gutter_highlights(layout, window, cx); - self.paint_gutter_indicators(layout, window, cx); - } + self.paint_text(layout, window, cx); - if !layout.blocks.is_empty() { - window.with_element_namespace("blocks", |window| { - self.paint_non_spacer_blocks(layout, window, cx); - }); - } + if !layout.spacer_blocks.is_empty() { + window.with_element_namespace("blocks", |window| { + self.paint_spacer_blocks(layout, window, cx); + }); + } + + if layout.gutter_hitbox.size.width > Pixels::ZERO { + self.paint_gutter_highlights(layout, window, cx); + self.paint_gutter_indicators(layout, window, cx); + } + + if !layout.blocks.is_empty() { + window.with_element_namespace("blocks", |window| { + self.paint_non_spacer_blocks(layout, window, cx); + }); + } + }); window.with_element_namespace("blocks", |window| { if let Some(mut sticky_header) = layout.sticky_buffer_header.take() {