From 9c31aaf12c2081fc81d1bc222c66bb2de55db562 Mon Sep 17 00:00:00 2001 From: Ari Suutari Date: Thu, 12 Nov 2026 20:33:54 +0200 Subject: [PATCH] macOS: report the cursor position with mouse button presses The first click into a window that isn't key did nothing in egui-baseview. The tracking area only reports mouse moves while the window is key (ActiveInKeyWindow), and ButtonPressed carries no position, so a click into an inactive window arrived with no known cursor position and handlers that need one dropped it. mouseDown:, rightMouseDown: and otherMouseDown: now send a CursorMoved with the event's position just before ButtonPressed, the same event mouseMoved: sends. Co-Authored-By: Claude Opus 5.5 --- src/platform/macos/view.rs | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/platform/macos/view.rs b/src/platform/macos/view.rs index 07cd39c6..90c07d11 100644 --- a/src/platform/macos/view.rs +++ b/src/platform/macos/view.rs @@ -278,6 +278,26 @@ impl BaseviewView { this.window_handler.use_handler(|h| h.on_event(event)).unwrap_or(EventStatus::Ignored) } + /// Reports the mouse position of `event` as a `CursorMoved` event. + /// + /// Button presses report it first too: mouse moves are only tracked while + /// the window is key, so without it the first click into an inactive window + /// would come with no known position, and handlers that need one (such as + /// egui-baseview) would drop it. + fn report_position(this: ViewRef, event: &NSEvent) { + let point = this.view.convertPoint_fromView(event.locationInWindow(), None); + + let position = LogicalPosition { x: point.x, y: point.y }; + + Self::trigger_event( + this, + Event::Mouse(MouseEvent::CursorMoved { + position: position.to_physical(this.state.scale_factor.get()), + modifiers: make_modifiers(event.modifierFlags()), + }), + ); + } + fn trigger_frame(this: ViewRef) { let result = this.window_handler.use_handler(|h| { this.state.redraw_requested.set(false); @@ -521,17 +541,7 @@ impl ViewImpl for BaseviewView { } fn mouse_moved(this: ViewRef, event: &NSEvent) { - let point = this.view.convertPoint_fromView(event.locationInWindow(), None); - - let position = LogicalPosition { x: point.x, y: point.y }; - - Self::trigger_event( - this, - Event::Mouse(MouseEvent::CursorMoved { - position: position.to_physical(this.state.scale_factor.get()), - modifiers: make_modifiers(event.modifierFlags()), - }), - ); + Self::report_position(this, event); // SAFETY: Our superclass is NSView let _: () = unsafe { msg_send![super(this.view, NSView::class()), mouseMoved: event] }; @@ -649,6 +659,7 @@ impl ViewImpl for BaseviewView { } fn mouse_down(this: ViewRef, event: &NSEvent) { + Self::report_position(this, event); Self::trigger_event( this, Event::Mouse(ButtonPressed { @@ -669,6 +680,7 @@ impl ViewImpl for BaseviewView { } fn right_mouse_down(this: ViewRef, event: &NSEvent) { + Self::report_position(this, event); Self::trigger_event( this, Event::Mouse(ButtonPressed { @@ -689,6 +701,7 @@ impl ViewImpl for BaseviewView { } fn other_mouse_down(this: ViewRef, event: &NSEvent) { + Self::report_position(this, event); Self::trigger_event( this, Event::Mouse(ButtonPressed {