Fix mouse interactions with the project and branch switchers (#9222)

Antonio Scandurra and Julia created

Previously, we were considering the mouse to be "out" of a div when its
hitbox wasn't hovered. However, if a parent listened for
"mouse_down_out" and a child occluded the parent, the parent would
always think the mouse was out even when the user clicked the child.

This commit changes the definition of "mouse out" to simply mean "does
not contain the point", without accounting for occlusion.

Release Notes:

- N/A

Co-authored-by: Julia <julia@zed.dev>

Change summary

crates/gpui/src/elements/div.rs              |  2 +-
crates/ui/src/components/popover_menu.rs     | 12 +++++++-----
crates/ui/src/components/right_click_menu.rs | 10 ++++++----
3 files changed, 14 insertions(+), 10 deletions(-)

Detailed changes

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

@@ -185,7 +185,7 @@ impl Interactivity {
     ) {
         self.mouse_down_listeners
             .push(Box::new(move |event, phase, hitbox, cx| {
-                if phase == DispatchPhase::Capture && !hitbox.is_hovered(cx) {
+                if phase == DispatchPhase::Capture && !hitbox.contains(&cx.mouse_position()) {
                     (listener)(event, cx)
                 }
             }));

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

@@ -1,10 +1,10 @@
 use std::{cell::RefCell, rc::Rc};
 
 use gpui::{
-    overlay, point, prelude::FluentBuilder, px, rems, AnchorCorner, AnyElement, Bounds,
-    DismissEvent, DispatchPhase, Element, ElementContext, ElementId, HitboxId, IntoElement,
-    LayoutId, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext,
-    WindowContext,
+    div, overlay, point, prelude::FluentBuilder, px, rems, AnchorCorner, AnyElement, Bounds,
+    DismissEvent, DispatchPhase, Element, ElementContext, ElementId, HitboxId, InteractiveElement,
+    IntoElement, LayoutId, ManagedView, MouseDownEvent, ParentElement, Pixels, Point, View,
+    VisualContext, WindowContext,
 };
 
 use crate::{Clickable, Selectable};
@@ -184,7 +184,9 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
                     );
                 }
 
-                let mut element = overlay.child(menu.clone()).into_any();
+                let mut element = overlay
+                    .child(div().occlude().child(menu.clone()))
+                    .into_any();
                 menu_layout_id = Some(element.before_layout(cx));
                 element
             });

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

@@ -1,9 +1,9 @@
 use std::{cell::RefCell, rc::Rc};
 
 use gpui::{
-    overlay, AnchorCorner, AnyElement, Bounds, DismissEvent, DispatchPhase, Element,
-    ElementContext, ElementId, Hitbox, IntoElement, LayoutId, ManagedView, MouseButton,
-    MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, WindowContext,
+    div, overlay, AnchorCorner, AnyElement, Bounds, DismissEvent, DispatchPhase, Element,
+    ElementContext, ElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, ManagedView,
+    MouseButton, MouseDownEvent, ParentElement, Pixels, Point, View, VisualContext, WindowContext,
 };
 
 pub struct RightClickMenu<M: ManagedView> {
@@ -109,7 +109,9 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
                 }
                 overlay = overlay.position(*element_state.position.borrow());
 
-                let mut element = overlay.child(menu.clone()).into_any();
+                let mut element = overlay
+                    .child(div().occlude().child(menu.clone()))
+                    .into_any();
                 menu_layout_id = Some(element.before_layout(cx));
                 element
             });