fix merge conflicr

Mikayla Maki created

Change summary

crates/editor/src/element.rs              |  36 +++-
crates/gpui/src/app.rs                    |  15 +
crates/gpui/src/elements/event_handler.rs |  21 +
crates/gpui/src/elements/flex.rs          |   9 
crates/gpui/src/elements/list.rs          |   6 
crates/gpui/src/elements/uniform_list.rs  |   6 
crates/gpui/src/gpui.rs                   |   3 
crates/gpui/src/platform.rs               |   2 
crates/gpui/src/platform/event.rs         | 148 ++++++++----------
crates/gpui/src/platform/mac/event.rs     | 189 ++++++++++++------------
crates/gpui/src/platform/mac/window.rs    |  43 ++--
crates/gpui/src/presenter.rs              |  82 ++++++----
crates/gpui/src/scene.rs                  |  13 +
crates/terminal/src/terminal_element.rs   |  12 
crates/workspace/src/toolbar.rs           |  19 ++
15 files changed, 323 insertions(+), 281 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -23,8 +23,9 @@ use gpui::{
     json::{self, ToJson},
     platform::CursorStyle,
     text_layout::{self, Line, RunStyle, TextLayoutCache},
-    AppContext, Axis, Border, CursorRegion, Element, ElementBox, Event, EventContext,
-    LayoutContext, MutableAppContext, PaintContext, Quad, Scene, SizeConstraint, ViewContext,
+    AppContext, Axis, Border, CursorRegion, Element, ElementBox, Event, EventContext, KeyDownEvent,
+    LayoutContext, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent,
+    MutableAppContext, PaintContext, Quad, Scene, ScrollWheelEvent, SizeConstraint, ViewContext,
     WeakViewHandle,
 };
 use json::json;
@@ -1463,14 +1464,15 @@ impl Element for EditorElement {
         }
 
         match event {
-            Event::LeftMouseDown {
+            Event::MouseDown(MouseEvent {
+                button: MouseButton::Left,
                 position,
                 cmd,
                 alt,
                 shift,
                 click_count,
                 ..
-            } => self.mouse_down(
+            }) => self.mouse_down(
                 *position,
                 *cmd,
                 *alt,
@@ -1480,18 +1482,26 @@ impl Element for EditorElement {
                 paint,
                 cx,
             ),
-            Event::LeftMouseUp { position, .. } => self.mouse_up(*position, cx),
-            Event::LeftMouseDragged { position, .. } => {
-                self.mouse_dragged(*position, layout, paint, cx)
-            }
-            Event::ScrollWheel {
+            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,
                 precise,
-            } => self.scroll(*position, *delta, *precise, layout, paint, cx),
-            Event::KeyDown { input, .. } => self.key_down(input.as_deref(), cx),
-            Event::ModifiersChanged { cmd, .. } => self.modifiers_changed(*cmd, cx),
-            Event::MouseMoved { position, cmd, .. } => {
+            }) => self.scroll(*position, *delta, *precise, layout, paint, cx),
+            Event::KeyDown(KeyDownEvent { input, .. }) => self.key_down(input.as_deref(), cx),
+            Event::ModifiersChanged(ModifiersChangedEvent { cmd, .. }) => {
+                self.modifiers_changed(*cmd, cx)
+            }
+            Event::MouseMoved(MouseMovedEvent { position, cmd, .. }) => {
                 self.mouse_moved(*position, *cmd, layout, paint, cx)
             }
 

crates/gpui/src/app.rs 🔗

@@ -4,7 +4,7 @@ use crate::{
     elements::ElementBox,
     executor::{self, Task},
     keymap::{self, Binding, Keystroke},
-    platform::{self, Platform, PromptLevel, WindowOptions},
+    platform::{self, KeyDownEvent, Platform, PromptLevel, WindowOptions},
     presenter::Presenter,
     util::post_inc,
     AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId, PathPromptOptions,
@@ -379,11 +379,11 @@ impl TestAppContext {
 
             if !cx.dispatch_keystroke(window_id, dispatch_path, &keystroke) {
                 presenter.borrow_mut().dispatch_event(
-                    Event::KeyDown {
+                    Event::KeyDown(KeyDownEvent {
                         keystroke,
                         input,
                         is_held,
-                    },
+                    }),
                     cx,
                 );
             }
@@ -1843,7 +1843,7 @@ impl MutableAppContext {
             window.on_event(Box::new(move |event| {
                 app.update(|cx| {
                     if let Some(presenter) = presenter.upgrade() {
-                        if let Event::KeyDown { keystroke, .. } = &event {
+                        if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
                             if cx.dispatch_keystroke(
                                 window_id,
                                 presenter.borrow().dispatch_path(cx.as_ref()),
@@ -5400,7 +5400,7 @@ impl RefCounts {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::{actions, elements::*, impl_actions};
+    use crate::{actions, elements::*, impl_actions, MouseButton, MouseEvent};
     use serde::Deserialize;
     use smol::future::poll_once;
     use std::{
@@ -5753,14 +5753,15 @@ 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 {
+            Event::MouseDown(MouseEvent {
                 position: Default::default(),
+                button: MouseButton::Left,
                 ctrl: false,
                 alt: false,
                 shift: false,
                 cmd: false,
                 click_count: 1,
-            },
+            }),
             cx,
         );
         assert_eq!(mouse_down_count.load(SeqCst), 1);

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

@@ -1,6 +1,7 @@
 use crate::{
     geometry::vector::Vector2F, CursorRegion, DebugContext, Element, ElementBox, Event,
-    EventContext, LayoutContext, MouseRegion, NavigationDirection, PaintContext, SizeConstraint,
+    EventContext, LayoutContext, MouseButton, MouseEvent, MouseRegion, NavigationDirection,
+    PaintContext, SizeConstraint,
 };
 use pathfinder_geometry::rect::RectF;
 use serde_json::json;
@@ -116,7 +117,11 @@ impl Element for EventHandler {
             true
         } else {
             match event {
-                Event::LeftMouseDown { 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);
@@ -124,7 +129,11 @@ impl Element for EventHandler {
                     }
                     false
                 }
-                Event::RightMouseDown { 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);
@@ -132,11 +141,11 @@ impl Element for EventHandler {
                     }
                     false
                 }
-                Event::NavigateMouseDown {
+                Event::MouseDown(MouseEvent {
+                    button: MouseButton::Navigate(direction),
                     position,
-                    direction,
                     ..
-                } => {
+                }) => {
                     if let Some(callback) = self.navigate_mouse_down.as_mut() {
                         if visible_bounds.contains_point(*position) {
                             return callback(*direction, cx);

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

@@ -3,7 +3,8 @@ use std::{any::Any, f32::INFINITY};
 use crate::{
     json::{self, ToJson, Value},
     Axis, DebugContext, Element, ElementBox, ElementStateHandle, Event, EventContext,
-    LayoutContext, PaintContext, RenderContext, SizeConstraint, Vector2FExt, View,
+    LayoutContext, MouseMovedEvent, PaintContext, RenderContext, ScrollWheelEvent, SizeConstraint,
+    Vector2FExt, View,
 };
 use pathfinder_geometry::{
     rect::RectF,
@@ -287,11 +288,11 @@ impl Element for Flex {
             handled = child.dispatch_event(event, cx) || handled;
         }
         if !handled {
-            if let &Event::ScrollWheel {
+            if let &Event::ScrollWheel(ScrollWheelEvent {
                 position,
                 delta,
                 precise,
-            } = event
+            }) = event
             {
                 if *remaining_space < 0. && bounds.contains_point(position) {
                     if let Some(scroll_state) = self.scroll_state.as_ref() {
@@ -321,7 +322,7 @@ impl Element for Flex {
         }
 
         if !handled {
-            if let &Event::MouseMoved { position, .. } = event {
+            if let &Event::MouseMoved(MouseMovedEvent { position, .. }) = event {
                 // If this is a scrollable flex, and the mouse is over it, eat the scroll event to prevent
                 // propogating it to the element below.
                 if self.scroll_state.is_some() && bounds.contains_point(position) {

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

@@ -5,7 +5,7 @@ use crate::{
     },
     json::json,
     DebugContext, Element, ElementBox, ElementRc, Event, EventContext, LayoutContext, PaintContext,
-    RenderContext, SizeConstraint, View, ViewContext,
+    RenderContext, ScrollWheelEvent, SizeConstraint, View, ViewContext,
 };
 use std::{cell::RefCell, collections::VecDeque, ops::Range, rc::Rc};
 use sum_tree::{Bias, SumTree};
@@ -311,11 +311,11 @@ impl Element for List {
         state.items = new_items;
 
         match event {
-            Event::ScrollWheel {
+            Event::ScrollWheel(ScrollWheelEvent {
                 position,
                 delta,
                 precise,
-            } => {
+            }) => {
                 if bounds.contains_point(*position) {
                     if state.scroll(scroll_top, bounds.height(), *delta, *precise, cx) {
                         handled = true;

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

@@ -5,7 +5,7 @@ use crate::{
         vector::{vec2f, Vector2F},
     },
     json::{self, json},
-    ElementBox, RenderContext, View,
+    ElementBox, RenderContext, ScrollWheelEvent, View,
 };
 use json::ToJson;
 use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@@ -310,11 +310,11 @@ impl Element for UniformList {
         }
 
         match event {
-            Event::ScrollWheel {
+            Event::ScrollWheel(ScrollWheelEvent {
                 position,
                 delta,
                 precise,
-            } => {
+            }) => {
                 if bounds.contains_point(*position) {
                     if self.scroll(*position, *delta, *precise, layout.scroll_max, cx) {
                         handled = true;

crates/gpui/src/gpui.rs 🔗

@@ -28,8 +28,7 @@ pub mod json;
 pub mod keymap;
 pub mod platform;
 pub use gpui_macros::test;
-pub use platform::FontSystem;
-pub use platform::{Event, NavigationDirection, PathPromptOptions, Platform, PromptLevel};
+pub use platform::*;
 pub use presenter::{
     Axis, DebugContext, EventContext, LayoutContext, PaintContext, SizeConstraint, Vector2FExt,
 };

crates/gpui/src/platform.rs 🔗

@@ -20,7 +20,7 @@ use crate::{
 };
 use anyhow::{anyhow, Result};
 use async_task::Runnable;
-pub use event::{Event, NavigationDirection};
+pub use event::*;
 use postage::oneshot;
 use serde::Deserialize;
 use std::{

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

@@ -1,85 +1,77 @@
 use crate::{geometry::vector::Vector2F, keymap::Keystroke};
 
+#[derive(Clone, Debug)]
+pub struct KeyDownEvent {
+    pub keystroke: Keystroke,
+    pub input: Option<String>,
+    pub is_held: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct KeyUpEvent {
+    pub keystroke: Keystroke,
+    pub input: Option<String>,
+}
+
+#[derive(Clone, Debug)]
+pub struct ModifiersChangedEvent {
+    pub ctrl: bool,
+    pub alt: bool,
+    pub shift: bool,
+    pub cmd: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct ScrollWheelEvent {
+    pub position: Vector2F,
+    pub delta: Vector2F,
+    pub precise: bool,
+}
+
 #[derive(Copy, Clone, Debug)]
 pub enum NavigationDirection {
     Back,
     Forward,
 }
 
+#[derive(Copy, Clone, Debug)]
+pub enum MouseButton {
+    Left,
+    Right,
+    Middle,
+    Navigate(NavigationDirection),
+}
+
+#[derive(Clone, Debug)]
+pub struct MouseEvent {
+    pub button: MouseButton,
+    pub position: Vector2F,
+    pub ctrl: bool,
+    pub alt: bool,
+    pub shift: bool,
+    pub cmd: bool,
+    pub click_count: usize,
+}
+
+#[derive(Clone, Copy, Debug)]
+pub struct MouseMovedEvent {
+    pub position: Vector2F,
+    pub pressed_button: Option<MouseButton>,
+    pub ctrl: bool,
+    pub cmd: bool,
+    pub alt: bool,
+    pub shift: bool,
+}
+
 #[derive(Clone, Debug)]
 pub enum Event {
-    KeyDown {
-        keystroke: Keystroke,
-        input: Option<String>,
-        is_held: bool,
-    },
-    KeyUp {
-        keystroke: Keystroke,
-        input: Option<String>,
-    },
-    ModifiersChanged {
-        ctrl: bool,
-        alt: bool,
-        shift: bool,
-        cmd: bool,
-    },
-    ScrollWheel {
-        position: Vector2F,
-        delta: Vector2F,
-        precise: bool,
-    },
-    LeftMouseDown {
-        position: Vector2F,
-        ctrl: bool,
-        alt: bool,
-        shift: bool,
-        cmd: bool,
-        click_count: usize,
-    },
-    LeftMouseUp {
-        position: Vector2F,
-        click_count: usize,
-    },
-    LeftMouseDragged {
-        position: Vector2F,
-        ctrl: bool,
-        alt: bool,
-        shift: bool,
-        cmd: bool,
-    },
-    RightMouseDown {
-        position: Vector2F,
-        ctrl: bool,
-        alt: bool,
-        shift: bool,
-        cmd: bool,
-        click_count: usize,
-    },
-    RightMouseUp {
-        position: Vector2F,
-        click_count: usize,
-    },
-    NavigateMouseDown {
-        position: Vector2F,
-        direction: NavigationDirection,
-        ctrl: bool,
-        alt: bool,
-        shift: bool,
-        cmd: bool,
-        click_count: usize,
-    },
-    NavigateMouseUp {
-        position: Vector2F,
-        direction: NavigationDirection,
-    },
-    MouseMoved {
-        position: Vector2F,
-        left_mouse_down: bool,
-        ctrl: bool,
-        cmd: bool,
-        alt: bool,
-        shift: bool,
-    },
+    KeyDown(KeyDownEvent),
+    KeyUp(KeyUpEvent),
+    ModifiersChanged(ModifiersChangedEvent),
+    MouseDown(MouseEvent),
+    MouseUp(MouseEvent),
+    MouseMoved(MouseMovedEvent),
+    ScrollWheel(ScrollWheelEvent),
 }
 
 impl Event {
@@ -88,15 +80,9 @@ impl Event {
             Event::KeyDown { .. } => None,
             Event::KeyUp { .. } => None,
             Event::ModifiersChanged { .. } => None,
-            Event::ScrollWheel { position, .. }
-            | Event::LeftMouseDown { position, .. }
-            | Event::LeftMouseUp { position, .. }
-            | Event::LeftMouseDragged { position, .. }
-            | Event::RightMouseDown { position, .. }
-            | Event::RightMouseUp { position, .. }
-            | Event::NavigateMouseDown { position, .. }
-            | Event::NavigateMouseUp { position, .. }
-            | Event::MouseMoved { 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,10 +2,12 @@ use crate::{
     geometry::vector::vec2f,
     keymap::Keystroke,
     platform::{Event, NavigationDirection},
+    KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent,
+    ScrollWheelEvent,
 };
 use cocoa::{
     appkit::{NSEvent, NSEventModifierFlags, NSEventType},
-    base::{id, nil, YES},
+    base::{id, YES},
     foundation::NSString as _,
 };
 use std::{borrow::Cow, ffi::CStr, os::raw::c_char};
@@ -59,12 +61,12 @@ impl Event {
                 let shift = modifiers.contains(NSEventModifierFlags::NSShiftKeyMask);
                 let cmd = modifiers.contains(NSEventModifierFlags::NSCommandKeyMask);
 
-                Some(Self::ModifiersChanged {
+                Some(Self::ModifiersChanged(ModifiersChangedEvent {
                     ctrl,
                     alt,
                     shift,
                     cmd,
-                })
+                }))
             }
             NSEventType::NSKeyDown => {
                 let modifiers = native_event.modifierFlags();
@@ -76,7 +78,7 @@ impl Event {
 
                 let (unmodified_chars, input) = get_key_text(native_event, cmd, ctrl, function)?;
 
-                Some(Self::KeyDown {
+                Some(Self::KeyDown(KeyDownEvent {
                     keystroke: Keystroke {
                         ctrl,
                         alt,
@@ -86,7 +88,7 @@ impl Event {
                     },
                     input,
                     is_held: native_event.isARepeat() == YES,
-                })
+                }))
             }
             NSEventType::NSKeyUp => {
                 let modifiers = native_event.modifierFlags();
@@ -98,7 +100,7 @@ impl Event {
 
                 let (unmodified_chars, input) = get_key_text(native_event, cmd, ctrl, function)?;
 
-                Some(Self::KeyUp {
+                Some(Self::KeyUp(KeyUpEvent {
                     keystroke: Keystroke {
                         ctrl,
                         alt,
@@ -107,125 +109,120 @@ impl Event {
                         key: unmodified_chars.into(),
                     },
                     input,
-                })
-            }
-            NSEventType::NSLeftMouseDown => {
-                let modifiers = native_event.modifierFlags();
-                window_height.map(|window_height| Self::LeftMouseDown {
-                    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::NSLeftMouseUp => window_height.map(|window_height| Self::LeftMouseUp {
-                position: vec2f(
-                    native_event.locationInWindow().x as f32,
-                    window_height - native_event.locationInWindow().y as f32,
-                ),
-                click_count: native_event.clickCount() as usize,
-            }),
-            NSEventType::NSRightMouseDown => {
+            NSEventType::NSLeftMouseDown
+            | NSEventType::NSRightMouseDown
+            | NSEventType::NSOtherMouseDown => {
+                let button = match native_event.buttonNumber() {
+                    0 => MouseButton::Left,
+                    1 => MouseButton::Right,
+                    2 => MouseButton::Middle,
+                    3 => MouseButton::Navigate(NavigationDirection::Back),
+                    4 => MouseButton::Navigate(NavigationDirection::Forward),
+                    // Other mouse buttons aren't tracked currently
+                    _ => return None,
+                };
                 let modifiers = native_event.modifierFlags();
-                window_height.map(|window_height| Self::RightMouseDown {
-                    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,
+
+                window_height.map(|window_height| {
+                    Self::MouseDown(MouseEvent {
+                        button,
+                        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::NSRightMouseUp => window_height.map(|window_height| Self::RightMouseUp {
-                position: vec2f(
-                    native_event.locationInWindow().x as f32,
-                    window_height - native_event.locationInWindow().y as f32,
-                ),
-                click_count: native_event.clickCount() as usize,
-            }),
-            NSEventType::NSOtherMouseDown => {
-                let direction = match native_event.buttonNumber() {
-                    3 => NavigationDirection::Back,
-                    4 => NavigationDirection::Forward,
+            NSEventType::NSLeftMouseUp
+            | NSEventType::NSRightMouseUp
+            | NSEventType::NSOtherMouseUp => {
+                let button = match native_event.buttonNumber() {
+                    0 => MouseButton::Left,
+                    1 => MouseButton::Right,
+                    2 => MouseButton::Middle,
+                    3 => MouseButton::Navigate(NavigationDirection::Back),
+                    4 => MouseButton::Navigate(NavigationDirection::Forward),
                     // Other mouse buttons aren't tracked currently
                     _ => return None,
                 };
 
-                let modifiers = native_event.modifierFlags();
-                window_height.map(|window_height| Self::NavigateMouseDown {
+                window_height.map(|window_height| {
+                    let modifiers = native_event.modifierFlags();
+                    Self::MouseUp(MouseEvent {
+                        button,
+                        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::NSScrollWheel => window_height.map(|window_height| {
+                Self::ScrollWheel(ScrollWheelEvent {
                     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,
+                    delta: vec2f(
+                        native_event.scrollingDeltaX() as f32,
+                        native_event.scrollingDeltaY() as f32,
+                    ),
+                    precise: native_event.hasPreciseScrollingDeltas() == YES,
                 })
-            }
-            NSEventType::NSOtherMouseUp => {
-                let direction = match native_event.buttonNumber() {
-                    3 => NavigationDirection::Back,
-                    4 => NavigationDirection::Forward,
+            }),
+            NSEventType::NSLeftMouseDragged
+            | NSEventType::NSRightMouseDragged
+            | NSEventType::NSOtherMouseDragged => {
+                let pressed_button = match native_event.buttonNumber() {
+                    0 => MouseButton::Left,
+                    1 => MouseButton::Right,
+                    2 => MouseButton::Middle,
+                    3 => MouseButton::Navigate(NavigationDirection::Back),
+                    4 => MouseButton::Navigate(NavigationDirection::Forward),
                     // Other mouse buttons aren't tracked currently
                     _ => return None,
                 };
 
-                window_height.map(|window_height| Self::NavigateMouseUp {
-                    position: vec2f(
-                        native_event.locationInWindow().x as f32,
-                        window_height - native_event.locationInWindow().y as f32,
-                    ),
-                    direction,
+                window_height.map(|window_height| {
+                    let modifiers = native_event.modifierFlags();
+                    Self::MouseMoved(MouseMovedEvent {
+                        pressed_button: Some(pressed_button),
+                        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::NSLeftMouseDragged => window_height.map(|window_height| {
-                let modifiers = native_event.modifierFlags();
-                Self::LeftMouseDragged {
-                    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 {
-                position: vec2f(
-                    native_event.locationInWindow().x as f32,
-                    window_height - native_event.locationInWindow().y as f32,
-                ),
-                delta: vec2f(
-                    native_event.scrollingDeltaX() as f32,
-                    native_event.scrollingDeltaY() as f32,
-                ),
-                precise: native_event.hasPreciseScrollingDeltas() == YES,
-            }),
             NSEventType::NSMouseMoved => window_height.map(|window_height| {
                 let modifiers = native_event.modifierFlags();
-                Self::MouseMoved {
+                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: None,
                     ctrl: modifiers.contains(NSEventModifierFlags::NSControlKeyMask),
                     alt: modifiers.contains(NSEventModifierFlags::NSAlternateKeyMask),
                     shift: modifiers.contains(NSEventModifierFlags::NSShiftKeyMask),
                     cmd: modifiers.contains(NSEventModifierFlags::NSCommandKeyMask),
-                }
+                })
             }),
             _ => None,
         }

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

@@ -6,7 +6,7 @@ use crate::{
     },
     keymap::Keystroke,
     platform::{self, Event, WindowBounds, WindowContext},
-    Scene,
+    KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent, Scene,
 };
 use block::ConcreteBlock;
 use cocoa::{
@@ -562,11 +562,11 @@ extern "C" fn handle_key_equivalent(this: &Object, _: Sel, native_event: id) ->
     let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
     if let Some(event) = event {
         match &event {
-            Event::KeyDown {
+            Event::KeyDown(KeyDownEvent {
                 keystroke,
                 input,
                 is_held,
-            } => {
+            }) => {
                 let keydown = (keystroke.clone(), input.clone());
                 // Ignore events from held-down keys after some of the initially-pressed keys
                 // were released.
@@ -603,33 +603,41 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
 
     if let Some(event) = event {
         match &event {
-            Event::LeftMouseDragged { 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 {
+            Event::ModifiersChanged(ModifiersChangedEvent {
                 ctrl,
                 alt,
                 shift,
                 cmd,
-            } => {
+            }) => {
                 // Only raise modifiers changed event when they have actually changed
-                if let Some(Event::ModifiersChanged {
+                if let Some(Event::ModifiersChanged(ModifiersChangedEvent {
                     ctrl: prev_ctrl,
                     alt: prev_alt,
                     shift: prev_shift,
                     cmd: prev_cmd,
-                }) = &window_state_borrow.previous_modifiers_changed_event
+                })) = &window_state_borrow.previous_modifiers_changed_event
                 {
                     if prev_ctrl == ctrl
                         && prev_alt == alt
@@ -667,11 +675,11 @@ extern "C" fn cancel_operation(this: &Object, _sel: Sel, _sender: id) {
         shift: false,
         key: chars.clone(),
     };
-    let event = Event::KeyDown {
+    let event = Event::KeyDown(KeyDownEvent {
         keystroke: keystroke.clone(),
         input: Some(chars.clone()),
         is_held: false,
-    };
+    });
 
     window_state_borrow.last_fresh_keydown = Some((keystroke, Some(chars)));
     if let Some(mut callback) = window_state_borrow.event_callback.take() {
@@ -835,7 +843,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 +852,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 {
-                        // 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,9 +9,9 @@ use crate::{
     scene::CursorRegion,
     text_layout::TextLayoutCache,
     Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, Entity,
-    FontSystem, ModelHandle, MouseRegion, MouseRegionId, ReadModel, ReadView, RenderContext,
-    RenderParams, 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;
@@ -235,7 +235,11 @@ impl Presenter {
             let mut dragged_region = None;
 
             match event {
-                Event::LeftMouseDown { 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) {
@@ -251,11 +255,12 @@ impl Presenter {
                         }
                     }
                 }
-                Event::LeftMouseUp {
+                Event::MouseUp(MouseEvent {
                     position,
                     click_count,
+                    button: MouseButton::Left,
                     ..
-                } => {
+                }) => {
                     self.prev_drag_position.take();
                     if let Some(region) = self.clicked_region.take() {
                         invalidated_views.push(region.view_id);
@@ -264,7 +269,11 @@ impl Presenter {
                         }
                     }
                 }
-                Event::RightMouseDown { 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) {
@@ -279,11 +288,12 @@ impl Presenter {
                         }
                     }
                 }
-                Event::RightMouseUp {
+                Event::MouseUp(MouseEvent {
                     position,
                     click_count,
+                    button: MouseButton::Right,
                     ..
-                } => {
+                }) => {
                     if let Some(region) = self.right_clicked_region.take() {
                         invalidated_views.push(region.view_id);
                         if region.bounds.contains_point(position) {
@@ -291,37 +301,37 @@ impl Presenter {
                         }
                     }
                 }
-                Event::MouseMoved { .. } => {
-                    self.last_mouse_moved_event = Some(event.clone());
-                }
-                Event::LeftMouseDragged {
+                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,
+                    ..
+                }) => {
+                    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(), *prev_drag_position, position));
+                            *prev_drag_position = position;
+                        }
+
+                        self.last_mouse_moved_event = Some(Event::MouseMoved(MouseMovedEvent {
                             position,
-                        ));
-                        *prev_drag_position = position;
+                            pressed_button: Some(MouseButton::Left),
+                            shift,
+                            ctrl,
+                            alt,
+                            cmd,
+                        }));
                     }
 
-                    self.last_mouse_moved_event = Some(Event::MouseMoved {
-                        position,
-                        left_mouse_down: true,
-                        shift,
-                        ctrl,
-                        alt,
-                        cmd,
-                    });
+                    self.last_mouse_moved_event = Some(event.clone());
                 }
                 _ => {}
             }
@@ -413,13 +423,13 @@ impl Presenter {
         let mut unhovered_regions = Vec::new();
         let mut hovered_regions = Vec::new();
 
-        if let Event::MouseMoved {
+        if let Event::MouseMoved(MouseMovedEvent {
             position,
-            left_mouse_down,
+            pressed_button,
             ..
-        } = event
+        }) = 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)>>,

crates/terminal/src/terminal_element.rs 🔗

@@ -20,8 +20,8 @@ use gpui::{
     },
     json::json,
     text_layout::{Line, RunStyle},
-    Event, FontCache, MouseRegion, PaintContext, Quad, SizeConstraint, TextLayoutCache,
-    WeakViewHandle,
+    Event, FontCache, KeyDownEvent, MouseRegion, PaintContext, Quad, ScrollWheelEvent,
+    SizeConstraint, TextLayoutCache, WeakViewHandle,
 };
 use itertools::Itertools;
 use ordered_float::OrderedFloat;
@@ -344,9 +344,9 @@ impl Element for TerminalEl {
         cx: &mut gpui::EventContext,
     ) -> bool {
         match event {
-            Event::ScrollWheel {
+            Event::ScrollWheel(ScrollWheelEvent {
                 delta, position, ..
-            } => visible_bounds
+            }) => visible_bounds
                 .contains_point(*position)
                 .then(|| {
                     let vertical_scroll =
@@ -354,9 +354,9 @@ impl Element for TerminalEl {
                     cx.dispatch_action(ScrollTerminal(vertical_scroll.round() as i32));
                 })
                 .is_some(),
-            Event::KeyDown {
+            Event::KeyDown(KeyDownEvent {
                 input: Some(input), ..
-            } => cx
+            }) => cx
                 .is_parent_view_focused()
                 .then(|| {
                     cx.dispatch_action(Input(input.to_string()));

crates/workspace/src/toolbar.rs 🔗

@@ -112,6 +112,7 @@ impl View for Toolbar {
         let container_style = theme.container;
         let height = theme.height;
         let button_style = theme.nav_button;
+        let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
 
         Flex::column()
             .with_child(
@@ -119,21 +120,27 @@ impl View for Toolbar {
                     .with_child(nav_button(
                         "icons/arrow-left.svg",
                         button_style,
+                        tooltip_style.clone(),
                         enable_go_backward,
                         spacing,
                         super::GoBack {
                             pane: Some(pane.clone()),
                         },
+                        super::GoBack { pane: None },
+                        "Go Back",
                         cx,
                     ))
                     .with_child(nav_button(
                         "icons/arrow-right.svg",
                         button_style,
+                        tooltip_style.clone(),
                         enable_go_forward,
                         spacing,
                         super::GoForward {
                             pane: Some(pane.clone()),
                         },
+                        super::GoForward { pane: None },
+                        "Go Forward",
                         cx,
                     ))
                     .with_children(primary_left_items)
@@ -152,9 +159,12 @@ impl View for Toolbar {
 fn nav_button<A: Action + Clone>(
     svg_path: &'static str,
     style: theme::Interactive<theme::IconButton>,
+    tooltip_style: TooltipStyle,
     enabled: bool,
     spacing: f32,
     action: A,
+    tooltip_action: A,
+    action_name: &str,
     cx: &mut RenderContext<Toolbar>,
 ) -> ElementBox {
     MouseEventHandler::new::<A, _, _>(0, cx, |state, _| {
@@ -181,7 +191,14 @@ fn nav_button<A: Action + Clone>(
     } else {
         CursorStyle::default()
     })
-    .on_mouse_down(move |_, cx| cx.dispatch_action(action.clone()))
+    .on_click(move |_, _, cx| cx.dispatch_action(action.clone()))
+    .with_tooltip::<A, _>(
+        0,
+        action_name.to_string(),
+        Some(Box::new(tooltip_action)),
+        tooltip_style,
+        cx,
+    )
     .contained()
     .with_margin_right(spacing)
     .boxed()