Allow specifying a custom height for stacking contexts

Antonio Scandurra created

Change summary

crates/editor/src/element.rs                       |  4 ++--
crates/gpui/src/elements/overlay.rs                |  9 ++++++++-
crates/gpui/src/elements/resizable.rs              |  2 +-
crates/gpui/src/presenter.rs                       | 10 +++++++---
crates/gpui/src/scene.rs                           |  4 ++--
crates/workspace/src/pane/dragged_item_receiver.rs |  2 +-
6 files changed, 21 insertions(+), 10 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -791,7 +791,7 @@ impl EditorElement {
         cx.scene.pop_layer();
 
         if let Some((position, context_menu)) = layout.context_menu.as_mut() {
-            cx.scene.push_stacking_context(None);
+            cx.scene.push_stacking_context(None, None);
             let cursor_row_layout =
                 &layout.position_map.line_layouts[(position.row() - start_row) as usize];
             let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
@@ -820,7 +820,7 @@ impl EditorElement {
         }
 
         if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() {
-            cx.scene.push_stacking_context(None);
+            cx.scene.push_stacking_context(None, None);
 
             // This is safe because we check on layout whether the required row is available
             let hovered_row_layout =

crates/gpui/src/elements/overlay.rs 🔗

@@ -16,6 +16,7 @@ pub struct Overlay {
     fit_mode: OverlayFitMode,
     position_mode: OverlayPositionMode,
     hoverable: bool,
+    height: Option<usize>,
 }
 
 #[derive(Copy, Clone)]
@@ -82,6 +83,7 @@ impl Overlay {
             fit_mode: OverlayFitMode::None,
             position_mode: OverlayPositionMode::Window,
             hoverable: false,
+            height: None,
         }
     }
 
@@ -109,6 +111,11 @@ impl Overlay {
         self.hoverable = hoverable;
         self
     }
+
+    pub fn with_height(mut self, height: usize) -> Self {
+        self.height = Some(height);
+        self
+    }
 }
 
 impl Element for Overlay {
@@ -204,7 +211,7 @@ impl Element for Overlay {
             OverlayFitMode::None => {}
         }
 
-        cx.paint_stacking_context(None, |cx| {
+        cx.paint_stacking_context(None, self.height, |cx| {
             if self.hoverable {
                 enum OverlayHoverCapture {}
                 // Block hovers in lower stacking contexts

crates/gpui/src/elements/resizable.rs 🔗

@@ -149,7 +149,7 @@ impl Element for Resizable {
         _child_size: &mut Self::LayoutState,
         cx: &mut crate::PaintContext,
     ) -> Self::PaintState {
-        cx.scene.push_stacking_context(None);
+        cx.scene.push_stacking_context(None, None);
 
         let handle_region = self.side.of_rect(bounds, self.handle_size);
 

crates/gpui/src/presenter.rs 🔗

@@ -709,11 +709,15 @@ impl<'a> PaintContext<'a> {
     }
 
     #[inline]
-    pub fn paint_stacking_context<F>(&mut self, clip_bounds: Option<RectF>, f: F)
-    where
+    pub fn paint_stacking_context<F>(
+        &mut self,
+        clip_bounds: Option<RectF>,
+        height: Option<usize>,
+        f: F,
+    ) where
         F: FnOnce(&mut Self),
     {
-        self.scene.push_stacking_context(clip_bounds);
+        self.scene.push_stacking_context(clip_bounds, height);
         f(self);
         self.scene.pop_stacking_context();
     }

crates/gpui/src/scene.rs 🔗

@@ -235,8 +235,8 @@ impl SceneBuilder {
         self.scale_factor
     }
 
-    pub fn push_stacking_context(&mut self, clip_bounds: Option<RectF>) {
-        let height = self.active_stacking_context().height + 1;
+    pub fn push_stacking_context(&mut self, clip_bounds: Option<RectF>, height: Option<usize>) {
+        let height = height.unwrap_or_else(|| self.active_stacking_context().height + 1);
         self.active_stacking_context_stack
             .push(self.stacking_contexts.len());
         self.stacking_contexts

crates/workspace/src/pane/dragged_item_receiver.rs 🔗

@@ -48,7 +48,7 @@ where
                             .map(|(dir, margin)| dir.along_edge(bounds, margin))
                             .unwrap_or(bounds);
 
-                        cx.paint_stacking_context(None, |cx| {
+                        cx.paint_stacking_context(None, None, |cx| {
                             cx.scene.push_quad(Quad {
                                 bounds: overlay_region,
                                 background: Some(overlay_color(cx)),