From 684db11afd2ae5e557cfd74109e4f089268a6d68 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 23 Aug 2023 12:57:33 -0600 Subject: [PATCH] Use platform API to request mouse position Co-Authored-By: Conrad Irwin --- crates/gpui/playground/src/hoverable.rs | 2 +- crates/gpui/src/app.rs | 9 +-------- crates/gpui/src/app/window.rs | 7 ++++--- crates/gpui/src/platform.rs | 2 +- crates/gpui/src/platform/mac/platform.rs | 9 ++------- crates/gpui/src/platform/mac/status_item.rs | 4 ++++ crates/gpui/src/platform/mac/window.rs | 18 ++++++++++++++++++ crates/gpui/src/platform/test.rs | 8 ++++---- 8 files changed, 35 insertions(+), 24 deletions(-) diff --git a/crates/gpui/playground/src/hoverable.rs b/crates/gpui/playground/src/hoverable.rs index 6cfd0c75b0..5aec6dd85e 100644 --- a/crates/gpui/playground/src/hoverable.rs +++ b/crates/gpui/playground/src/hoverable.rs @@ -66,7 +66,7 @@ impl + Styleable> Element for Hoverable { let hovered = self.hovered.clone(); cx.on_event(order, move |view, event: &MouseMovedEvent, cx| { - if bounds.contains_point(event.position) != hovered.get() { + if bounds.contains_point(cx.mouse_position()) != hovered.get() { cx.repaint(); } }); diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index d630d792d6..5b3dc438c6 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1363,14 +1363,7 @@ impl AppContext { window: handle, })); - let mouse_position = self.platform.mouse_position(); - let mut window = Window::new( - handle, - platform_window, - mouse_position, - self, - build_root_view, - ); + let mut window = Window::new(handle, platform_window, self, build_root_view); let mut cx = WindowContext::mutable(self, &mut window, handle); cx.layout(false).expect("initial layout should not error"); let scene = cx.paint().expect("initial paint should not error"); diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index e0d53401a8..b1a758b049 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -70,7 +70,6 @@ impl Window { pub fn new( handle: AnyWindowHandle, platform_window: Box, - mouse_position: Vector2F, cx: &mut AppContext, build_view: F, ) -> Self @@ -98,7 +97,7 @@ impl Window { hovered_region_ids: Default::default(), clicked_region_ids: Default::default(), clicked_region: None, - mouse_position, + mouse_position: Default::default(), titlebar_height, appearance, }; @@ -508,7 +507,9 @@ impl<'a> WindowContext<'a> { } pub(crate) fn dispatch_event(&mut self, event: Event, event_reused: bool) -> bool { - self.dispatch_to_new_event_handlers(&event); + if !event_reused { + self.dispatch_to_new_event_handlers(&event); + } let mut mouse_events = SmallVec::<[_; 2]>::new(); let mut notified_views: HashSet = Default::default(); diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 2ac7ec54c7..f6711b4374 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -75,7 +75,6 @@ pub trait Platform: Send + Sync { fn read_credentials(&self, url: &str) -> Result)>>; fn delete_credentials(&self, url: &str) -> Result<()>; - fn mouse_position(&self) -> Vector2F; fn set_cursor_style(&self, style: CursorStyle); fn should_auto_hide_scrollbars(&self) -> bool; @@ -147,6 +146,7 @@ pub trait Window { fn titlebar_height(&self) -> f32; fn appearance(&self) -> Appearance; fn screen(&self) -> Rc; + fn mouse_position(&self) -> Vector2F; fn as_any_mut(&mut self) -> &mut dyn Any; fn set_input_handler(&mut self, input_handler: Box); diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index af4eaa2a40..656f2e4475 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -18,7 +18,7 @@ use cocoa::{ }, base::{id, nil, selector, BOOL, YES}, foundation::{ - NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSPoint, NSProcessInfo, NSString, + NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSProcessInfo, NSString, NSUInteger, NSURL, }, }; @@ -37,7 +37,7 @@ use objc::{ runtime::{Class, Object, Sel}, sel, sel_impl, }; -use pathfinder_geometry::vector::{vec2f, Vector2F}; + use postage::oneshot; use ptr::null_mut; use std::{ @@ -785,11 +785,6 @@ impl platform::Platform for MacPlatform { Ok(()) } - fn mouse_position(&self) -> Vector2F { - let position: NSPoint = unsafe { msg_send![class!(NSEvent), mouseLocation] }; - vec2f(position.x as f32, position.y as f32) - } - fn set_cursor_style(&self, style: CursorStyle) { unsafe { let new_cursor: id = match style { diff --git a/crates/gpui/src/platform/mac/status_item.rs b/crates/gpui/src/platform/mac/status_item.rs index 955b2b659a..9c7903a0fc 100644 --- a/crates/gpui/src/platform/mac/status_item.rs +++ b/crates/gpui/src/platform/mac/status_item.rs @@ -202,6 +202,10 @@ impl platform::Window for StatusItem { } } + fn mouse_position(&self) -> Vector2F { + unimplemented!() + } + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 3be425d312..a6d57e5140 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -221,6 +221,14 @@ unsafe fn build_classes() { }; } +pub fn convert_mouse_position(position: NSPoint, window_height: f32) -> Vector2F { + vec2f( + position.x as f32, + // MacOS screen coordinates are relative to bottom left + window_height - position.y as f32, + ) +} + unsafe fn build_window_class(name: &'static str, superclass: &Class) -> *const Class { let mut decl = ClassDecl::new(name, superclass).unwrap(); decl.add_ivar::<*mut c_void>(WINDOW_STATE_IVAR); @@ -661,6 +669,16 @@ impl platform::Window for MacWindow { } } + fn mouse_position(&self) -> Vector2F { + let position = unsafe { + self.0 + .borrow() + .native_window + .mouseLocationOutsideOfEventStream() + }; + convert_mouse_position(position, self.content_size().y()) + } + fn as_any_mut(&mut self) -> &mut dyn Any { self } diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index 5b6f299f9c..e8579a0006 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -195,10 +195,6 @@ impl super::Platform for Platform { Ok(()) } - fn mouse_position(&self) -> Vector2F { - Vector2F::zero() - } - fn set_cursor_style(&self, style: CursorStyle) { *self.cursor.lock() = style; } @@ -336,6 +332,10 @@ impl super::Window for Window { Rc::new(Screen) } + fn mouse_position(&self) -> Vector2F { + Vector2F::zero() + } + fn as_any_mut(&mut self) -> &mut dyn Any { self }