From edf0bacea607645d7f7e7f01e9c03c0a7fa0f006 Mon Sep 17 00:00:00 2001 From: Madis Liias Date: Thu, 27 Oct 2022 02:32:39 +0300 Subject: [PATCH] Fix mouse enter/leave events on macos 13 fixes #2280 macOS 13 introduces an issue that mouse events are not fired anymore. This is caused by `NSView.addTrackingArea` being called too soon and is fixed here to be done after `NSView.initWithFrame` has been called. The docs at https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/TrackingAreaObjects/TrackingAreaObjects.html does say that you can create an `NSTrackingArea` instance and add it to a view at any point because successful creation does not depend on the view being added to a window. But it seems there are still some undocumented preconditions. --- druid-shell/src/backend/mac/window.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/druid-shell/src/backend/mac/window.rs b/druid-shell/src/backend/mac/window.rs index 23f0f17ccd..f444ecaae2 100644 --- a/druid-shell/src/backend/mac/window.rs +++ b/druid-shell/src/backend/mac/window.rs @@ -290,6 +290,18 @@ impl WindowBuilder { let frame = NSView::frame(content_view); view.initWithFrame_(frame); + // The rect of the tracking area doesn't matter, because + // we use the InVisibleRect option where the OS syncs the size automatically. + let rect = NSRect::new(NSPoint::new(0., 0.), NSSize::new(0., 0.)); + let opts = NSTrackingAreaOptions::MouseEnteredAndExited + | NSTrackingAreaOptions::MouseMoved + | NSTrackingAreaOptions::ActiveAlways + | NSTrackingAreaOptions::InVisibleRect; + let tracking_area = NSTrackingArea::alloc(nil) + .initWithRect_options_owner_userInfo(rect, opts, view, nil) + .autorelease(); + view.addTrackingArea(tracking_area); + let () = msg_send![window, setDelegate: view]; if let Some(menu) = self.menu { @@ -578,18 +590,6 @@ fn make_view(handler: Box) -> (id, Weak>>) { let options: NSAutoresizingMaskOptions = NSViewWidthSizable | NSViewHeightSizable; view.setAutoresizingMask_(options); - // The rect of the tracking area doesn't matter, because - // we use the InVisibleRect option where the OS syncs the size automatically. - let rect = NSRect::new(NSPoint::new(0., 0.), NSSize::new(0., 0.)); - let opts = NSTrackingAreaOptions::MouseEnteredAndExited - | NSTrackingAreaOptions::MouseMoved - | NSTrackingAreaOptions::ActiveAlways - | NSTrackingAreaOptions::InVisibleRect; - let tracking_area = NSTrackingArea::alloc(nil) - .initWithRect_options_owner_userInfo(rect, opts, view, nil) - .autorelease(); - view.addTrackingArea(tracking_area); - (view.autorelease(), queue_handle) } }