Z index shenanigans (#4089)

Julia created

Release Notes:

- Fixed a bug allowing certain UI elements to render incorrectly when
overlapping.

Change summary

crates/editor/src/hover_popover.rs       | 1 +
crates/gpui/src/style.rs                 | 6 +++---
crates/gpui/src/window.rs                | 8 ++++++++
crates/ui/src/components/context_menu.rs | 1 +
4 files changed, 13 insertions(+), 3 deletions(-)

Detailed changes

crates/gpui/src/style.rs 🔗

@@ -386,7 +386,7 @@ impl Style {
 
         let background_color = self.background.as_ref().and_then(Fill::color);
         if background_color.map_or(false, |color| !color.is_transparent()) {
-            cx.with_z_index(1, |cx| {
+            cx.with_z_index(0, |cx| {
                 let mut border_color = background_color.unwrap_or_default();
                 border_color.a = 0.;
                 cx.paint_quad(quad(
@@ -399,12 +399,12 @@ impl Style {
             });
         }
 
-        cx.with_z_index(2, |cx| {
+        cx.with_z_index(0, |cx| {
             continuation(cx);
         });
 
         if self.is_border_visible() {
-            cx.with_z_index(3, |cx| {
+            cx.with_z_index(0, |cx| {
                 let corner_radii = self.corner_radii.to_pixels(bounds.size, rem_size);
                 let border_widths = self.border_widths.to_pixels(rem_size);
                 let max_border_width = border_widths.max();

crates/gpui/src/window.rs 🔗

@@ -315,6 +315,7 @@ pub(crate) struct Frame {
     pub(crate) depth_map: Vec<(StackingOrder, EntityId, Bounds<Pixels>)>,
     pub(crate) z_index_stack: StackingOrder,
     pub(crate) next_stacking_order_id: u32,
+    next_root_z_index: u8,
     content_mask_stack: Vec<ContentMask<Pixels>>,
     element_offset_stack: Vec<Point<Pixels>>,
     requested_input_handler: Option<RequestedInputHandler>,
@@ -337,6 +338,7 @@ impl Frame {
             depth_map: Vec::new(),
             z_index_stack: StackingOrder::default(),
             next_stacking_order_id: 0,
+            next_root_z_index: 0,
             content_mask_stack: Vec::new(),
             element_offset_stack: Vec::new(),
             requested_input_handler: None,
@@ -354,6 +356,7 @@ impl Frame {
         self.dispatch_tree.clear();
         self.depth_map.clear();
         self.next_stacking_order_id = 0;
+        self.next_root_z_index = 0;
         self.reused_views.clear();
         self.scene.clear();
         self.requested_input_handler.take();
@@ -2450,8 +2453,13 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
         };
         let new_stacking_order_id =
             post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
+        let new_root_z_index = post_inc(&mut self.window_mut().next_frame.next_root_z_index);
         let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
         self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
+        self.window_mut()
+            .next_frame
+            .z_index_stack
+            .push(new_root_z_index);
         self.window_mut().next_frame.content_mask_stack.push(mask);
         let result = f(self);
         self.window_mut().next_frame.content_mask_stack.pop();

crates/ui/src/components/context_menu.rs 🔗

@@ -51,6 +51,7 @@ impl ContextMenu {
             let _on_blur_subscription = cx.on_blur(&focus_handle, |this: &mut ContextMenu, cx| {
                 this.cancel(&menu::Cancel, cx)
             });
+            cx.refresh();
             f(
                 Self {
                     items: Default::default(),