From 48b843e42d8b807e8147217b666a732db41db31a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 13 Sep 2022 21:11:18 +0200 Subject: [PATCH] Accepts first mouse (#2457) * MacOS: set value for `accepts_first_mouse` * Update CHANGELOG and FEATURES * Field doesn't need to be public * Convert `bool` to `BOOL` * Fix formatting * Move flag from window state to view instance * Feedback from PR * Fix changelog location --- CHANGELOG.md | 1 + FEATURES.md | 1 + src/platform/macos.rs | 8 ++++++++ src/platform_impl/macos/view.rs | 22 +++++++++++++++++----- src/platform_impl/macos/window.rs | 4 +++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c61f3bb947..9d6990eac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased +- On MacOS, made `accepts_first_mouse` configurable. - Migrated `WindowBuilderExtUnix::with_resize_increments` to `WindowBuilder`. - Added `Window::resize_increments`/`Window::set_resize_increments` to update resize increments at runtime for X11/macOS. - macOS/iOS: Use `objc2` instead of `objc` internally. diff --git a/FEATURES.md b/FEATURES.md index 4598e508fe..7e88997030 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -129,6 +129,7 @@ If your PR makes notable changes to Winit's features, please update this section * Hidden titlebar * Hidden titlebar buttons * Full-size content view +* Accepts first mouse ### Unix * Window urgency diff --git a/src/platform/macos.rs b/src/platform/macos.rs index cd687e83c8..88269150da 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -111,6 +111,8 @@ pub trait WindowBuilderExtMacOS { fn with_fullsize_content_view(self, fullsize_content_view: bool) -> WindowBuilder; fn with_disallow_hidpi(self, disallow_hidpi: bool) -> WindowBuilder; fn with_has_shadow(self, has_shadow: bool) -> WindowBuilder; + /// Window accepts click-through mouse events. + fn with_accepts_first_mouse(self, accepts_first_mouse: bool) -> WindowBuilder; } impl WindowBuilderExtMacOS for WindowBuilder { @@ -164,6 +166,12 @@ impl WindowBuilderExtMacOS for WindowBuilder { self.platform_specific.has_shadow = has_shadow; self } + + #[inline] + fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> WindowBuilder { + self.platform_specific.accepts_first_mouse = accepts_first_mouse; + self + } } pub trait EventLoopBuilderExtMacOS { diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 5726fb650c..dd1e17d511 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -136,6 +136,7 @@ declare_class!( _ns_window: IvarDrop>, pub(super) state: IvarDrop>, marked_text: IvarDrop>, + accepts_first_mouse: bool, } unsafe impl ClassType for WinitView { @@ -144,8 +145,12 @@ declare_class!( } unsafe impl WinitView { - #[sel(initWithId:)] - fn init_with_id(&mut self, window: *mut WinitWindow) -> Option<&mut Self> { + #[sel(initWithId:acceptsFirstMouse:)] + fn init_with_id( + &mut self, + window: *mut WinitWindow, + accepts_first_mouse: bool, + ) -> Option<&mut Self> { let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; this.map(|this| { let state = ViewState { @@ -165,6 +170,7 @@ declare_class!( ); Ivar::write(&mut this.state, Box::new(state)); Ivar::write(&mut this.marked_text, NSMutableAttributedString::new()); + Ivar::write(&mut this.accepts_first_mouse, accepts_first_mouse); this.setPostsFrameChangedNotifications(true); @@ -911,14 +917,20 @@ declare_class!( #[sel(acceptsFirstMouse:)] fn accepts_first_mouse(&self, _event: &NSEvent) -> bool { trace_scope!("acceptsFirstMouse:"); - true + *self.accepts_first_mouse } } ); impl WinitView { - pub(super) fn new(window: &WinitWindow) -> Id { - unsafe { msg_send_id![msg_send_id![Self::class(), alloc], initWithId: window] } + pub(super) fn new(window: &WinitWindow, accepts_first_mouse: bool) -> Id { + unsafe { + msg_send_id![ + msg_send_id![Self::class(), alloc], + initWithId: window, + acceptsFirstMouse: accepts_first_mouse, + ] + } } fn window(&self) -> Id { diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 4bc2902575..4fded71d88 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -79,6 +79,7 @@ pub struct PlatformSpecificWindowBuilderAttributes { pub fullsize_content_view: bool, pub disallow_hidpi: bool, pub has_shadow: bool, + pub accepts_first_mouse: bool, } impl Default for PlatformSpecificWindowBuilderAttributes { @@ -93,6 +94,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes { fullsize_content_view: false, disallow_hidpi: false, has_shadow: true, + accepts_first_mouse: true, } } } @@ -354,7 +356,7 @@ impl WinitWindow { }) .ok_or_else(|| os_error!(OsError::CreationError("Couldn't create `NSWindow`")))?; - let view = WinitView::new(&this); + let view = WinitView::new(&this, pl_attrs.accepts_first_mouse); // The default value of `setWantsBestResolutionOpenGLSurface:` was `false` until // macos 10.14 and `true` after 10.15, we should set it to `YES` or `NO` to avoid