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:
<img width="603" height="319" alt="image"
src="https://github.com/user-attachments/assets/bf438003-a416-46a6-85bc-dfa767be067e"
/>


Good:
<img width="603" height="319" alt="image"
src="https://github.com/user-attachments/assets/e644e54a-6667-41e1-86d0-16e659bea844"
/>

Release Notes:

- Fixed: Editor no longer renders behind sticky scroll headers while
using a transparent theme
This commit is contained in:
Cameron Mcloughlin 2026-04-22 11:22:14 +01:00 committed by GitHub
parent 25036ba8bc
commit 8f0efe9f34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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);
if layout.gutter_hitbox.size.width > Pixels::ZERO {
self.paint_blamed_display_rows(layout, window, cx);
self.paint_line_numbers(layout, window, cx);
}
self.paint_text(layout, window, cx);
if !layout.spacer_blocks.is_empty() {
window.with_element_namespace("blocks", |window| {
self.paint_spacer_blocks(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_gutter_highlights(layout, window, cx);
self.paint_gutter_indicators(layout, window, cx);
}
window.with_content_mask(below_sticky_headers_mask, |window| {
self.paint_background(layout, window, cx);
if !layout.blocks.is_empty() {
window.with_element_namespace("blocks", |window| {
self.paint_non_spacer_blocks(layout, window, cx);
});
}
self.paint_indent_guides(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);
}
self.paint_text(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() {