Calculate hitbox based on visible bounds in `{Mouse}EventHandler`

Antonio Scandurra created

This is in contrast to not dispatching the event altogether in `Flex` when
the event is not contained in the flex element bounds. That approach was
problematic because it didn't give an opportunity to `MouseEventHandler`s
to handle mouse move events when they didn't intersect with the element bounds,
causing elements to never clear their hover state, cursor style, etc.

Change summary

crates/gpui/src/elements/event_handler.rs       | 9 ++++-----
crates/gpui/src/elements/flex.rs                | 6 ------
crates/gpui/src/elements/mouse_event_handler.rs | 6 +++---
3 files changed, 7 insertions(+), 14 deletions(-)

Detailed changes

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

@@ -84,7 +84,6 @@ impl Element for EventHandler {
     fn dispatch_event(
         &mut self,
         event: &Event,
-        bounds: RectF,
         _: RectF,
         visible_bounds: RectF,
         _: &mut Self::LayoutState,
@@ -92,7 +91,7 @@ impl Element for EventHandler {
         cx: &mut EventContext,
     ) -> bool {
         if let Some(capture) = self.capture.as_mut() {
-            if capture(event, bounds, cx) {
+            if capture(event, visible_bounds, cx) {
                 return true;
             }
         }
@@ -103,7 +102,7 @@ impl Element for EventHandler {
             match event {
                 Event::LeftMouseDown { position, .. } => {
                     if let Some(callback) = self.mouse_down.as_mut() {
-                        if bounds.contains_point(*position) {
+                        if visible_bounds.contains_point(*position) {
                             return callback(cx);
                         }
                     }
@@ -111,7 +110,7 @@ impl Element for EventHandler {
                 }
                 Event::RightMouseDown { position, .. } => {
                     if let Some(callback) = self.right_mouse_down.as_mut() {
-                        if bounds.contains_point(*position) {
+                        if visible_bounds.contains_point(*position) {
                             return callback(cx);
                         }
                     }
@@ -123,7 +122,7 @@ impl Element for EventHandler {
                     ..
                 } => {
                     if let Some(callback) = self.navigate_mouse_down.as_mut() {
-                        if bounds.contains_point(*position) {
+                        if visible_bounds.contains_point(*position) {
                             return callback(*direction, cx);
                         }
                     }

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

@@ -271,12 +271,6 @@ impl Element for Flex {
         _: &mut Self::PaintState,
         cx: &mut EventContext,
     ) -> bool {
-        if let Some(position) = event.position() {
-            if !bounds.contains_point(position) {
-                return false;
-            }
-        }
-
         let mut handled = false;
         for child in &mut self.children {
             handled = child.dispatch_event(event, cx) || handled;

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

@@ -99,8 +99,8 @@ impl Element for MouseEventHandler {
     fn dispatch_event(
         &mut self,
         event: &Event,
-        bounds: RectF,
         _: RectF,
+        visible_bounds: RectF,
         _: &mut Self::LayoutState,
         _: &mut Self::PaintState,
         cx: &mut EventContext,
@@ -113,8 +113,8 @@ impl Element for MouseEventHandler {
         let handled_in_child = self.child.dispatch_event(event, cx);
 
         let hit_bounds = RectF::from_points(
-            bounds.origin() - vec2f(self.padding.left, self.padding.top),
-            bounds.lower_right() + vec2f(self.padding.right, self.padding.bottom),
+            visible_bounds.origin() - vec2f(self.padding.left, self.padding.top),
+            visible_bounds.lower_right() + vec2f(self.padding.right, self.padding.bottom),
         )
         .round_out();