diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 976f932e58..56f664566e 100644 --- a/crates/editor/src/element.rs +++ b/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) } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 26c4fe01a8..901c131d03 100644 --- a/crates/gpui/src/app.rs +++ b/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); diff --git a/crates/gpui/src/elements/event_handler.rs b/crates/gpui/src/elements/event_handler.rs index 1b025c3d35..1fec838788 100644 --- a/crates/gpui/src/elements/event_handler.rs +++ b/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); diff --git a/crates/gpui/src/elements/flex.rs b/crates/gpui/src/elements/flex.rs index 82a6299d10..cb43c1db68 100644 --- a/crates/gpui/src/elements/flex.rs +++ b/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) { diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index 6479f2ee28..e368b45288 100644 --- a/crates/gpui/src/elements/list.rs +++ b/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; diff --git a/crates/gpui/src/elements/uniform_list.rs b/crates/gpui/src/elements/uniform_list.rs index de217a017c..9b2d966a7d 100644 --- a/crates/gpui/src/elements/uniform_list.rs +++ b/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; diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 5a1fc2fe14..723e25c55d 100644 --- a/crates/gpui/src/gpui.rs +++ b/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, }; diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index b4875df3f5..cf508a5634 100644 --- a/crates/gpui/src/platform.rs +++ b/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::{ diff --git a/crates/gpui/src/platform/event.rs b/crates/gpui/src/platform/event.rs index f43d5bea49..90b5d21fc2 100644 --- a/crates/gpui/src/platform/event.rs +++ b/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, + pub is_held: bool, +} + +#[derive(Clone, Debug)] +pub struct KeyUpEvent { + pub keystroke: Keystroke, + pub input: Option, +} + +#[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, + pub ctrl: bool, + pub cmd: bool, + pub alt: bool, + pub shift: bool, +} + #[derive(Clone, Debug)] pub enum Event { - KeyDown { - keystroke: Keystroke, - input: Option, - is_held: bool, - }, - KeyUp { - keystroke: Keystroke, - input: Option, - }, - 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), } } } diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index ed880513e8..5e23859675 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/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 => { + 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::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, + + 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::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 => { - 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, - }) - } - 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, } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index c845693ba9..5e6b3b9c19 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/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>, 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 { diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 9810277a87..51672e25c7 100644 --- a/crates/gpui/src/presenter.rs +++ b/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) { diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index a413d96981..769eabe7e5 100644 --- a/crates/gpui/src/scene.rs +++ b/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>, pub mouse_down: Option>, pub click: Option>, diff --git a/crates/terminal/src/terminal_element.rs b/crates/terminal/src/terminal_element.rs index 525d9f4066..1ad6aed6ae 100644 --- a/crates/terminal/src/terminal_element.rs +++ b/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())); diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index 9e0c085b1f..636df9a039 100644 --- a/crates/workspace/src/toolbar.rs +++ b/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::().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( svg_path: &'static str, style: theme::Interactive, + tooltip_style: TooltipStyle, enabled: bool, spacing: f32, action: A, + tooltip_action: A, + action_name: &str, cx: &mut RenderContext, ) -> ElementBox { MouseEventHandler::new::(0, cx, |state, _| { @@ -181,7 +191,14 @@ fn nav_button( } else { CursorStyle::default() }) - .on_mouse_down(move |_, cx| cx.dispatch_action(action.clone())) + .on_click(move |_, _, cx| cx.dispatch_action(action.clone())) + .with_tooltip::( + 0, + action_name.to_string(), + Some(Box::new(tooltip_action)), + tooltip_style, + cx, + ) .contained() .with_margin_right(spacing) .boxed()