Move workspace overlay elements into an actual overlay in order to get proper stacking context depths

Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
K Simmons 2022-09-09 18:17:17 -07:00
parent 6b26965074
commit 444417203b
4 changed files with 50 additions and 41 deletions

View file

@ -2,7 +2,7 @@ use std::{any::Any, rc::Rc};
use collections::HashSet; use collections::HashSet;
use gpui::{ use gpui::{
elements::{Container, MouseEventHandler}, elements::{Container, MouseEventHandler, Overlay},
geometry::vector::Vector2F, geometry::vector::Vector2F,
scene::DragRegionEvent, scene::DragRegionEvent,
CursorStyle, Element, ElementBox, EventContext, MouseButton, MutableAppContext, RenderContext, CursorStyle, Element, ElementBox, EventContext, MouseButton, MutableAppContext, RenderContext,
@ -116,29 +116,27 @@ impl<V: View> DragAndDrop<V> {
enum DraggedElementHandler {} enum DraggedElementHandler {}
Some( Some(
MouseEventHandler::<DraggedElementHandler>::new(0, cx, |_, cx| { Overlay::new(
Container::new(render(payload, cx)) MouseEventHandler::<DraggedElementHandler>::new(0, cx, |_, cx| {
.with_margin_left(position.x()) render(payload, cx)
.with_margin_top(position.y()) })
.aligned() .with_cursor_style(CursorStyle::Arrow)
.top() .on_up(MouseButton::Left, |_, cx| {
.left() cx.defer(|cx| {
.boxed() cx.update_global::<Self, _, _>(|this, cx| this.stop_dragging(cx));
}) });
.with_cursor_style(CursorStyle::Arrow) cx.propogate_event();
.on_up(MouseButton::Left, |_, cx| { })
cx.defer(|cx| { .on_up_out(MouseButton::Left, |_, cx| {
cx.update_global::<Self, _, _>(|this, cx| this.stop_dragging(cx)); cx.defer(|cx| {
}); cx.update_global::<Self, _, _>(|this, cx| this.stop_dragging(cx));
cx.propogate_event(); });
}) })
.on_up_out(MouseButton::Left, |_, cx| { // Don't block hover events or invalidations
cx.defer(|cx| { .with_hoverable(false)
cx.update_global::<Self, _, _>(|this, cx| this.stop_dragging(cx)); .boxed(),
}); )
}) .with_anchor_position(position)
// Don't block hover events or invalidations
.with_hoverable(false)
.boxed(), .boxed(),
) )
}, },

View file

@ -12,8 +12,8 @@ use serde_json::json;
pub struct Overlay { pub struct Overlay {
child: ElementBox, child: ElementBox,
anchor_position: Option<Vector2F>, anchor_position: Option<Vector2F>,
fit_mode: OverlayFitMode,
anchor_corner: AnchorCorner, anchor_corner: AnchorCorner,
fit_mode: OverlayFitMode,
hoverable: bool, hoverable: bool,
} }
@ -71,8 +71,8 @@ impl Overlay {
Self { Self {
child, child,
anchor_position: None, anchor_position: None,
fit_mode: OverlayFitMode::None,
anchor_corner: AnchorCorner::TopLeft, anchor_corner: AnchorCorner::TopLeft,
fit_mode: OverlayFitMode::None,
hoverable: false, hoverable: false,
} }
} }
@ -183,14 +183,13 @@ impl Element for Overlay {
if self.hoverable { if self.hoverable {
enum OverlayHoverCapture {} enum OverlayHoverCapture {}
cx.scene.push_mouse_region( // Block hovers in lower stacking contexts
MouseRegion::new::<OverlayHoverCapture>( cx.scene
.push_mouse_region(MouseRegion::new::<OverlayHoverCapture>(
cx.current_view_id(), cx.current_view_id(),
cx.current_view_id(), cx.current_view_id(),
bounds, bounds,
) ));
.with_hoverable(true),
);
} }
self.child.paint(bounds.origin(), bounds, cx); self.child.paint(bounds.origin(), bounds, cx);

View file

@ -150,6 +150,7 @@ impl Dock {
cx: &mut RenderContext<Workspace>, cx: &mut RenderContext<Workspace>,
) -> Option<ElementBox> { ) -> Option<ElementBox> {
let style = &theme.workspace.dock; let style = &theme.workspace.dock;
self.position self.position
.visible() .visible()
.filter(|current_anchor| *current_anchor == anchor) .filter(|current_anchor| *current_anchor == anchor)

View file

@ -2618,16 +2618,27 @@ impl View for Workspace {
) )
.boxed() .boxed()
}) })
.with_children(self.dock.render(&theme, DockAnchor::Expanded, cx)) .with_child(
.with_children(self.modal.as_ref().map(|m| { Overlay::new(
ChildView::new(m) Stack::new()
.contained() .with_children(self.dock.render(
.with_style(theme.workspace.modal) &theme,
.aligned() DockAnchor::Expanded,
.top() cx,
.boxed() ))
})) .with_children(self.modal.as_ref().map(|m| {
.with_children(self.render_notifications(&theme.workspace)) ChildView::new(m)
.contained()
.with_style(theme.workspace.modal)
.aligned()
.top()
.boxed()
}))
.with_children(self.render_notifications(&theme.workspace))
.boxed(),
)
.boxed(),
)
.flex(1.0, true) .flex(1.0, true)
.boxed(), .boxed(),
) )