Combine platform mouse events to use common MouseEvent struct and remove MouseDragged event in favor of MouseMoved

Keith Simmons created

Change summary

crates/editor/src/element.rs              | 23 ++++--
crates/gpui/src/app.rs                    |  5 
crates/gpui/src/elements/event_handler.rs | 20 +++-
crates/gpui/src/platform/event.rs         | 90 +++++-------------------
crates/gpui/src/platform/mac/event.rs     | 73 +++++++++++++------
crates/gpui/src/platform/mac/window.rs    | 31 +++----
crates/gpui/src/presenter.rs              | 72 +++++++++++--------
crates/gpui/src/scene.rs                  | 13 +++
8 files changed, 168 insertions(+), 159 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -24,9 +24,9 @@ use gpui::{
     platform::CursorStyle,
     text_layout::{self, Line, RunStyle, TextLayoutCache},
     AppContext, Axis, Border, CursorRegion, Element, ElementBox, Event, EventContext, KeyDownEvent,
-    LayoutContext, LeftMouseDownEvent, LeftMouseDraggedEvent, LeftMouseUpEvent,
-    ModifiersChangedEvent, MouseMovedEvent, MutableAppContext, PaintContext, Quad, Scene,
-    ScrollWheelEvent, SizeConstraint, ViewContext, WeakViewHandle,
+    LayoutContext, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent,
+    MutableAppContext, PaintContext, Quad, Scene, ScrollWheelEvent, SizeConstraint, ViewContext,
+    WeakViewHandle,
 };
 use json::json;
 use language::{Bias, DiagnosticSeverity, Selection};
@@ -1464,7 +1464,8 @@ impl Element for EditorElement {
         }
 
         match event {
-            Event::LeftMouseDown(LeftMouseDownEvent {
+            Event::MouseDown(MouseEvent {
+                button: MouseButton::Left,
                 position,
                 cmd,
                 alt,
@@ -1481,10 +1482,16 @@ impl Element for EditorElement {
                 paint,
                 cx,
             ),
-            Event::LeftMouseUp(LeftMouseUpEvent { position, .. }) => self.mouse_up(*position, cx),
-            Event::LeftMouseDragged(LeftMouseDraggedEvent { position, .. }) => {
-                self.mouse_dragged(*position, layout, paint, cx)
-            }
+            Event::MouseUp(MouseEvent {
+                button: MouseButton::Left,
+                position,
+                ..
+            }) => self.mouse_up(*position, cx),
+            Event::MouseMoved(MouseMovedEvent {
+                pressed_button: Some(MouseButton::Left),
+                position,
+                ..
+            }) => self.mouse_dragged(*position, layout, paint, cx),
             Event::ScrollWheel(ScrollWheelEvent {
                 position,
                 delta,

crates/gpui/src/app.rs 🔗

@@ -5381,7 +5381,7 @@ impl RefCounts {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::{actions, elements::*, impl_actions, LeftMouseDownEvent};
+    use crate::{actions, elements::*, impl_actions, MouseButton, MouseEvent};
     use serde::Deserialize;
     use smol::future::poll_once;
     use std::{
@@ -5734,8 +5734,9 @@ mod tests {
         let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
         // Ensure window's root element is in a valid lifecycle state.
         presenter.borrow_mut().dispatch_event(
-            Event::LeftMouseDown(LeftMouseDownEvent {
+            Event::MouseDown(MouseEvent {
                 position: Default::default(),
+                button: MouseButton::Left,
                 ctrl: false,
                 alt: false,
                 shift: false,

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

@@ -1,7 +1,7 @@
 use crate::{
     geometry::vector::Vector2F, CursorRegion, DebugContext, Element, ElementBox, Event,
-    EventContext, LayoutContext, LeftMouseDownEvent, MouseRegion, NavigateMouseDownEvent,
-    NavigationDirection, PaintContext, RightMouseDownEvent, SizeConstraint,
+    EventContext, LayoutContext, MouseButton, MouseEvent, MouseRegion, NavigationDirection,
+    PaintContext, SizeConstraint,
 };
 use pathfinder_geometry::rect::RectF;
 use serde_json::json;
@@ -117,7 +117,11 @@ impl Element for EventHandler {
             true
         } else {
             match event {
-                Event::LeftMouseDown(LeftMouseDownEvent { position, .. }) => {
+                Event::MouseDown(MouseEvent {
+                    button: MouseButton::Left,
+                    position,
+                    ..
+                }) => {
                     if let Some(callback) = self.mouse_down.as_mut() {
                         if visible_bounds.contains_point(*position) {
                             return callback(cx);
@@ -125,7 +129,11 @@ impl Element for EventHandler {
                     }
                     false
                 }
-                Event::RightMouseDown(RightMouseDownEvent { position, .. }) => {
+                Event::MouseDown(MouseEvent {
+                    button: MouseButton::Right,
+                    position,
+                    ..
+                }) => {
                     if let Some(callback) = self.right_mouse_down.as_mut() {
                         if visible_bounds.contains_point(*position) {
                             return callback(cx);
@@ -133,9 +141,9 @@ impl Element for EventHandler {
                     }
                     false
                 }
-                Event::NavigateMouseDown(NavigateMouseDownEvent {
+                Event::MouseDown(MouseEvent {
+                    button: MouseButton::Navigate(direction),
                     position,
-                    direction,
                     ..
                 }) => {
                     if let Some(callback) = self.navigate_mouse_down.as_mut() {

crates/gpui/src/platform/event.rs 🔗

@@ -1,11 +1,5 @@
 use crate::{geometry::vector::Vector2F, keymap::Keystroke};
 
-#[derive(Copy, Clone, Debug)]
-pub enum NavigationDirection {
-    Back,
-    Forward,
-}
-
 #[derive(Clone, Debug)]
 pub struct KeyDownEvent {
     pub keystroke: Keystroke,
@@ -34,51 +28,24 @@ pub struct ScrollWheelEvent {
     pub precise: bool,
 }
 
-#[derive(Clone, Debug)]
-pub struct LeftMouseDownEvent {
-    pub position: Vector2F,
-    pub ctrl: bool,
-    pub alt: bool,
-    pub shift: bool,
-    pub cmd: bool,
-    pub click_count: usize,
-}
-
-#[derive(Clone, Debug)]
-pub struct LeftMouseUpEvent {
-    pub position: Vector2F,
-    pub click_count: usize,
-}
-
-#[derive(Clone, Debug)]
-pub struct LeftMouseDraggedEvent {
-    pub position: Vector2F,
-    pub ctrl: bool,
-    pub alt: bool,
-    pub shift: bool,
-    pub cmd: bool,
-}
-
-#[derive(Clone, Debug)]
-pub struct RightMouseDownEvent {
-    pub position: Vector2F,
-    pub ctrl: bool,
-    pub alt: bool,
-    pub shift: bool,
-    pub cmd: bool,
-    pub click_count: usize,
+#[derive(Copy, Clone, Debug)]
+pub enum NavigationDirection {
+    Back,
+    Forward,
 }
 
-#[derive(Clone, Debug)]
-pub struct RightMouseUpEvent {
-    pub position: Vector2F,
-    pub click_count: usize,
+#[derive(Copy, Clone, Debug)]
+pub enum MouseButton {
+    Left,
+    Right,
+    Middle,
+    Navigate(NavigationDirection),
 }
 
 #[derive(Clone, Debug)]
-pub struct NavigateMouseDownEvent {
+pub struct MouseEvent {
+    pub button: MouseButton,
     pub position: Vector2F,
-    pub direction: NavigationDirection,
     pub ctrl: bool,
     pub alt: bool,
     pub shift: bool,
@@ -86,16 +53,10 @@ pub struct NavigateMouseDownEvent {
     pub click_count: usize,
 }
 
-#[derive(Clone, Debug)]
-pub struct NavigateMouseUpEvent {
-    pub position: Vector2F,
-    pub direction: NavigationDirection,
-}
-
-#[derive(Clone, Debug)]
+#[derive(Clone, Copy, Debug)]
 pub struct MouseMovedEvent {
     pub position: Vector2F,
-    pub left_mouse_down: bool,
+    pub pressed_button: Option<MouseButton>,
     pub ctrl: bool,
     pub cmd: bool,
     pub alt: bool,
@@ -107,15 +68,10 @@ pub enum Event {
     KeyDown(KeyDownEvent),
     KeyUp(KeyUpEvent),
     ModifiersChanged(ModifiersChangedEvent),
-    ScrollWheel(ScrollWheelEvent),
-    LeftMouseDown(LeftMouseDownEvent),
-    LeftMouseUp(LeftMouseUpEvent),
-    LeftMouseDragged(LeftMouseDraggedEvent),
-    RightMouseDown(RightMouseDownEvent),
-    RightMouseUp(RightMouseUpEvent),
-    NavigateMouseDown(NavigateMouseDownEvent),
-    NavigateMouseUp(NavigateMouseUpEvent),
+    MouseDown(MouseEvent),
+    MouseUp(MouseEvent),
     MouseMoved(MouseMovedEvent),
+    ScrollWheel(ScrollWheelEvent),
 }
 
 impl Event {
@@ -124,15 +80,9 @@ impl Event {
             Event::KeyDown { .. } => None,
             Event::KeyUp { .. } => None,
             Event::ModifiersChanged { .. } => None,
-            Event::ScrollWheel(ScrollWheelEvent { position, .. })
-            | Event::LeftMouseDown(LeftMouseDownEvent { position, .. })
-            | Event::LeftMouseUp(LeftMouseUpEvent { position, .. })
-            | Event::LeftMouseDragged(LeftMouseDraggedEvent { position, .. })
-            | Event::RightMouseDown(RightMouseDownEvent { position, .. })
-            | Event::RightMouseUp(RightMouseUpEvent { position, .. })
-            | Event::NavigateMouseDown(NavigateMouseDownEvent { position, .. })
-            | Event::NavigateMouseUp(NavigateMouseUpEvent { position, .. })
-            | Event::MouseMoved(MouseMovedEvent { position, .. }) => Some(*position),
+            Event::MouseDown(event) | Event::MouseUp(event) => Some(event.position),
+            Event::MouseMoved(event) => Some(event.position),
+            Event::ScrollWheel(event) => Some(event.position),
         }
     }
 }

crates/gpui/src/platform/mac/event.rs 🔗

@@ -2,9 +2,8 @@ use crate::{
     geometry::vector::vec2f,
     keymap::Keystroke,
     platform::{Event, NavigationDirection},
-    KeyDownEvent, KeyUpEvent, LeftMouseDownEvent, LeftMouseDraggedEvent, LeftMouseUpEvent,
-    ModifiersChangedEvent, MouseMovedEvent, NavigateMouseDownEvent, NavigateMouseUpEvent,
-    RightMouseDownEvent, RightMouseUpEvent, ScrollWheelEvent,
+    KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent,
+    ScrollWheelEvent,
 };
 use cocoa::{
     appkit::{NSEvent, NSEventModifierFlags, NSEventType},
@@ -115,7 +114,8 @@ impl Event {
             NSEventType::NSLeftMouseDown => {
                 let modifiers = native_event.modifierFlags();
                 window_height.map(|window_height| {
-                    Self::LeftMouseDown(LeftMouseDownEvent {
+                    Self::MouseDown(MouseEvent {
+                        button: MouseButton::Left,
                         position: vec2f(
                             native_event.locationInWindow().x as f32,
                             window_height - native_event.locationInWindow().y as f32,
@@ -129,18 +129,25 @@ impl Event {
                 })
             }
             NSEventType::NSLeftMouseUp => window_height.map(|window_height| {
-                Self::LeftMouseUp(LeftMouseUpEvent {
+                let modifiers = native_event.modifierFlags();
+                Self::MouseUp(MouseEvent {
+                    button: MouseButton::Left,
                     position: vec2f(
                         native_event.locationInWindow().x as f32,
                         window_height - native_event.locationInWindow().y as f32,
                     ),
+                    ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
+                    alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
+                    shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),
+                    cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask),
                     click_count: native_event.clickCount() as usize,
                 })
             }),
             NSEventType::NSRightMouseDown => {
                 let modifiers = native_event.modifierFlags();
                 window_height.map(|window_height| {
-                    Self::RightMouseDown(RightMouseDownEvent {
+                    Self::MouseDown(MouseEvent {
+                        button: MouseButton::Right,
                         position: vec2f(
                             native_event.locationInWindow().x as f32,
                             window_height - native_event.locationInWindow().y as f32,
@@ -154,11 +161,17 @@ impl Event {
                 })
             }
             NSEventType::NSRightMouseUp => window_height.map(|window_height| {
-                Self::RightMouseUp(RightMouseUpEvent {
+                let modifiers = native_event.modifierFlags();
+                Self::MouseUp(MouseEvent {
+                    button: MouseButton::Right,
                     position: vec2f(
                         native_event.locationInWindow().x as f32,
                         window_height - native_event.locationInWindow().y as f32,
                     ),
+                    ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
+                    alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
+                    shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),
+                    cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask),
                     click_count: native_event.clickCount() as usize,
                 })
             }),
@@ -172,12 +185,12 @@ impl Event {
 
                 let modifiers = native_event.modifierFlags();
                 window_height.map(|window_height| {
-                    Self::NavigateMouseDown(NavigateMouseDownEvent {
+                    Self::MouseDown(MouseEvent {
+                        button: MouseButton::Navigate(direction),
                         position: vec2f(
                             native_event.locationInWindow().x as f32,
                             window_height - native_event.locationInWindow().y as f32,
                         ),
-                        direction,
                         ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
                         alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
                         shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),
@@ -194,29 +207,22 @@ impl Event {
                     _ => return None,
                 };
 
+                let modifiers = native_event.modifierFlags();
                 window_height.map(|window_height| {
-                    Self::NavigateMouseUp(NavigateMouseUpEvent {
+                    Self::MouseUp(MouseEvent {
+                        button: MouseButton::Navigate(direction),
                         position: vec2f(
                             native_event.locationInWindow().x as f32,
                             window_height - native_event.locationInWindow().y as f32,
                         ),
-                        direction,
+                        ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
+                        alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
+                        shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),
+                        cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask),
+                        click_count: native_event.clickCount() as usize,
                     })
                 })
             }
-            NSEventType::NSLeftMouseDragged => window_height.map(|window_height| {
-                let modifiers = native_event.modifierFlags();
-                Self::LeftMouseDragged(LeftMouseDraggedEvent {
-                    position: vec2f(
-                        native_event.locationInWindow().x as f32,
-                        window_height - native_event.locationInWindow().y as f32,
-                    ),
-                    ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
-                    alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
-                    shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),
-                    cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask),
-                })
-            }),
             NSEventType::NSScrollWheel => window_height.map(|window_height| {
                 Self::ScrollWheel(ScrollWheelEvent {
                     position: vec2f(
@@ -232,12 +238,29 @@ impl Event {
             }),
             NSEventType::NSMouseMoved => window_height.map(|window_height| {
                 let modifiers = native_event.modifierFlags();
+                let pressed_button_flags = NSEvent::pressedMouseButtons(nil);
+
+                // Pick the "strongest" button to report in mouse dragged events
+                let pressed_button = if pressed_button_flags & (1 << 0) != 0 {
+                    Some(MouseButton::Left)
+                } else if pressed_button_flags & (1 << 1) != 0 {
+                    Some(MouseButton::Right)
+                } else if pressed_button_flags & (1 << 2) != 0 {
+                    Some(MouseButton::Middle)
+                } else if pressed_button_flags & (1 << 3) != 0 {
+                    Some(MouseButton::Navigate(NavigationDirection::Back))
+                } else if pressed_button_flags & (1 << 4) != 0 {
+                    Some(MouseButton::Navigate(NavigationDirection::Forward))
+                } else {
+                    None
+                };
+
                 Self::MouseMoved(MouseMovedEvent {
                     position: vec2f(
                         native_event.locationInWindow().x as f32,
                         window_height - native_event.locationInWindow().y as f32,
                     ),
-                    left_mouse_down: NSEvent::pressedMouseButtons(nil) & 1 != 0,
+                    pressed_button,
                     ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
                     alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
                     shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),

crates/gpui/src/platform/mac/window.rs 🔗

@@ -6,7 +6,7 @@ use crate::{
     },
     keymap::Keystroke,
     platform::{self, Event, WindowBounds, WindowContext},
-    KeyDownEvent, LeftMouseDraggedEvent, ModifiersChangedEvent, Scene,
+    KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent, Scene,
 };
 use block::ConcreteBlock;
 use cocoa::{
@@ -127,10 +127,6 @@ unsafe fn build_classes() {
             sel!(mouseMoved:),
             handle_view_event as extern "C" fn(&Object, Sel, id),
         );
-        decl.add_method(
-            sel!(mouseDragged:),
-            handle_view_event as extern "C" fn(&Object, Sel, id),
-        );
         decl.add_method(
             sel!(scrollWheel:),
             handle_view_event as extern "C" fn(&Object, Sel, id),
@@ -603,18 +599,26 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
 
     if let Some(event) = event {
         match &event {
-            Event::LeftMouseDragged(LeftMouseDraggedEvent { position, .. }) => {
+            Event::MouseMoved(
+                event @ MouseMovedEvent {
+                    pressed_button: Some(_),
+                    ..
+                },
+            ) => {
                 window_state_borrow.synthetic_drag_counter += 1;
                 window_state_borrow
                     .executor
                     .spawn(synthetic_drag(
                         weak_window_state,
                         window_state_borrow.synthetic_drag_counter,
-                        *position,
+                        *event,
                     ))
                     .detach();
             }
-            Event::LeftMouseUp { .. } => {
+            Event::MouseUp(MouseEvent {
+                button: MouseButton::Left,
+                ..
+            }) => {
                 window_state_borrow.synthetic_drag_counter += 1;
             }
             Event::ModifiersChanged(ModifiersChangedEvent {
@@ -835,7 +839,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
 async fn synthetic_drag(
     window_state: Weak<RefCell<WindowState>>,
     drag_id: usize,
-    position: Vector2F,
+    event: MouseMovedEvent,
 ) {
     loop {
         Timer::after(Duration::from_millis(16)).await;
@@ -844,14 +848,7 @@ async fn synthetic_drag(
             if window_state_borrow.synthetic_drag_counter == drag_id {
                 if let Some(mut callback) = window_state_borrow.event_callback.take() {
                     drop(window_state_borrow);
-                    callback(Event::LeftMouseDragged(LeftMouseDraggedEvent {
-                        // TODO: Make sure empty modifiers is correct for this
-                        position,
-                        shift: false,
-                        ctrl: false,
-                        alt: false,
-                        cmd: false,
-                    }));
+                    callback(Event::MouseMoved(event));
                     window_state.borrow_mut().event_callback = Some(callback);
                 }
             } else {

crates/gpui/src/presenter.rs 🔗

@@ -9,10 +9,9 @@ use crate::{
     scene::CursorRegion,
     text_layout::TextLayoutCache,
     Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, Entity,
-    FontSystem, LeftMouseDownEvent, LeftMouseDraggedEvent, LeftMouseUpEvent, ModelHandle,
-    MouseMovedEvent, MouseRegion, MouseRegionId, ReadModel, ReadView, RenderContext, RenderParams,
-    RightMouseDownEvent, RightMouseUpEvent, Scene, UpgradeModelHandle, UpgradeViewHandle, View,
-    ViewHandle, WeakModelHandle, WeakViewHandle,
+    FontSystem, ModelHandle, MouseButton, MouseEvent, MouseMovedEvent, MouseRegion, MouseRegionId,
+    ReadModel, ReadView, RenderContext, RenderParams, Scene, UpgradeModelHandle, UpgradeViewHandle,
+    View, ViewHandle, WeakModelHandle, WeakViewHandle,
 };
 use pathfinder_geometry::vector::{vec2f, Vector2F};
 use serde_json::json;
@@ -236,7 +235,11 @@ impl Presenter {
             let mut dragged_region = None;
 
             match event {
-                Event::LeftMouseDown(LeftMouseDownEvent { position, .. }) => {
+                Event::MouseDown(MouseEvent {
+                    position,
+                    button: MouseButton::Left,
+                    ..
+                }) => {
                     let mut hit = false;
                     for (region, _) in self.mouse_regions.iter().rev() {
                         if region.bounds.contains_point(position) {
@@ -252,9 +255,10 @@ impl Presenter {
                         }
                     }
                 }
-                Event::LeftMouseUp(LeftMouseUpEvent {
+                Event::MouseUp(MouseEvent {
                     position,
                     click_count,
+                    button: MouseButton::Left,
                     ..
                 }) => {
                     self.prev_drag_position.take();
@@ -265,7 +269,11 @@ impl Presenter {
                         }
                     }
                 }
-                Event::RightMouseDown(RightMouseDownEvent { position, .. }) => {
+                Event::MouseDown(MouseEvent {
+                    position,
+                    button: MouseButton::Right,
+                    ..
+                }) => {
                     let mut hit = false;
                     for (region, _) in self.mouse_regions.iter().rev() {
                         if region.bounds.contains_point(position) {
@@ -280,9 +288,10 @@ impl Presenter {
                         }
                     }
                 }
-                Event::RightMouseUp(RightMouseUpEvent {
+                Event::MouseUp(MouseEvent {
                     position,
                     click_count,
+                    button: MouseButton::Right,
                     ..
                 }) => {
                     if let Some(region) = self.right_clicked_region.take() {
@@ -292,34 +301,37 @@ impl Presenter {
                         }
                     }
                 }
-                Event::MouseMoved { .. } => {
-                    self.last_mouse_moved_event = Some(event.clone());
-                }
-                Event::LeftMouseDragged(LeftMouseDraggedEvent {
+                Event::MouseMoved(MouseMovedEvent {
+                    pressed_button,
                     position,
                     shift,
                     ctrl,
                     alt,
                     cmd,
+                    ..
                 }) => {
-                    if let Some((clicked_region, prev_drag_position)) = self
-                        .clicked_region
-                        .as_ref()
-                        .zip(self.prev_drag_position.as_mut())
-                    {
-                        dragged_region =
-                            Some((clicked_region.clone(), position - *prev_drag_position));
-                        *prev_drag_position = position;
+                    if let Some(MouseButton::Left) = pressed_button {
+                        if let Some((clicked_region, prev_drag_position)) = self
+                            .clicked_region
+                            .as_ref()
+                            .zip(self.prev_drag_position.as_mut())
+                        {
+                            dragged_region =
+                                Some((clicked_region.clone(), position - *prev_drag_position));
+                            *prev_drag_position = position;
+                        }
+
+                        self.last_mouse_moved_event = Some(Event::MouseMoved(MouseMovedEvent {
+                            position,
+                            pressed_button: Some(MouseButton::Left),
+                            shift,
+                            ctrl,
+                            alt,
+                            cmd,
+                        }));
                     }
 
-                    self.last_mouse_moved_event = Some(Event::MouseMoved(MouseMovedEvent {
-                        position,
-                        left_mouse_down: true,
-                        shift,
-                        ctrl,
-                        alt,
-                        cmd,
-                    }));
+                    self.last_mouse_moved_event = Some(event.clone());
                 }
                 _ => {}
             }
@@ -413,11 +425,11 @@ impl Presenter {
 
         if let Event::MouseMoved(MouseMovedEvent {
             position,
-            left_mouse_down,
+            pressed_button,
             ..
         }) = event
         {
-            if !left_mouse_down {
+            if let None = pressed_button {
                 let mut style_to_assign = CursorStyle::Arrow;
                 for region in self.cursor_regions.iter().rev() {
                     if region.bounds.contains_point(*position) {

crates/gpui/src/scene.rs 🔗

@@ -8,7 +8,7 @@ use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::ToJson,
     platform::CursorStyle,
-    EventContext, ImageData,
+    EventContext, ImageData, MouseEvent, MouseMovedEvent, ScrollWheelEvent,
 };
 
 pub struct Scene {
@@ -44,11 +44,22 @@ pub struct CursorRegion {
     pub style: CursorStyle,
 }
 
+pub enum MouseRegionEvent {
+    Moved(MouseMovedEvent),
+    Hover(MouseEvent),
+    Down(MouseEvent),
+    Up(MouseEvent),
+    Click(MouseEvent),
+    DownOut(MouseEvent),
+    ScrollWheel(ScrollWheelEvent),
+}
+
 #[derive(Clone, Default)]
 pub struct MouseRegion {
     pub view_id: usize,
     pub discriminant: Option<(TypeId, usize)>,
     pub bounds: RectF,
+
     pub hover: Option<Rc<dyn Fn(Vector2F, bool, &mut EventContext)>>,
     pub mouse_down: Option<Rc<dyn Fn(Vector2F, &mut EventContext)>>,
     pub click: Option<Rc<dyn Fn(Vector2F, usize, &mut EventContext)>>,