From 7e3defe5cd503aa2ecf5f781b96a25f8f1931cb6 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Thu, 1 Sep 2022 14:55:36 +0300 Subject: [PATCH 1/7] MacOS: set value for `accepts_first_mouse` --- src/platform/macos.rs | 8 ++++++++ src/platform_impl/macos/view.rs | 18 ++++++++++++++---- src/platform_impl/macos/window.rs | 4 +++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/platform/macos.rs b/src/platform/macos.rs index d7fe84a257..c25bf1342d 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -113,6 +113,8 @@ pub trait WindowBuilderExtMacOS { fn with_resize_increments(self, increments: LogicalSize) -> 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 { @@ -172,6 +174,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 16bc457ecc..2517d4686c 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -34,7 +34,7 @@ use crate::{ }, ffi::*, util::{self, id_to_string_lossy, IdRef}, - window::get_window_id, + window::{get_window_id, PlatformSpecificWindowBuilderAttributes}, DEVICE_ID, }, window::WindowId, @@ -86,6 +86,7 @@ pub(super) struct ViewState { /// True if the current key event should be forwarded /// to the application, even during IME forward_key_to_app: bool, + pub accepts_first_mouse: bool, } impl ViewState { @@ -98,7 +99,10 @@ impl ViewState { } } -pub fn new_view(ns_window: id) -> (IdRef, Weak>) { +pub fn new_view( + ns_window: id, + pl_attribs: &PlatformSpecificWindowBuilderAttributes, +) -> (IdRef, Weak>) { let cursor_state = Default::default(); let cursor_access = Arc::downgrade(&cursor_state); let state = ViewState { @@ -111,6 +115,7 @@ pub fn new_view(ns_window: id) -> (IdRef, Weak>) { input_source: String::new(), ime_allowed: false, forward_key_to_app: false, + accepts_first_mouse: pl_attribs.accepts_first_mouse, }; unsafe { // This is free'd in `dealloc` @@ -1295,7 +1300,12 @@ extern "C" fn wants_key_down_for_event(_this: &Object, _sel: Sel, _event: id) -> YES } -extern "C" fn accepts_first_mouse(_this: &Object, _sel: Sel, _event: id) -> BOOL { +extern "C" fn accepts_first_mouse(this: &Object, _sel: Sel, _event: id) -> BOOL { trace_scope!("acceptsFirstMouse:"); - YES + unsafe { + let state_ptr: *const c_void = *this.get_ivar("winitState"); + let state = &*(state_ptr as *const ViewState); + + state.accepts_first_mouse + } } diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index f804a275f2..17d6e9fdcc 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -90,6 +90,7 @@ pub struct PlatformSpecificWindowBuilderAttributes { pub resize_increments: Option>, pub disallow_hidpi: bool, pub has_shadow: bool, + pub accepts_first_mouse: bool, } impl Default for PlatformSpecificWindowBuilderAttributes { @@ -105,6 +106,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes { resize_increments: None, disallow_hidpi: false, has_shadow: true, + accepts_first_mouse: true, } } } @@ -113,7 +115,7 @@ unsafe fn create_view( ns_window: id, pl_attribs: &PlatformSpecificWindowBuilderAttributes, ) -> Option<(IdRef, Weak>)> { - let (ns_view, cursor_state) = new_view(ns_window); + let (ns_view, cursor_state) = new_view(ns_window, pl_attribs); ns_view.non_nil().map(|ns_view| { // 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 From abff0d4c08cf635a078b37659e7257fb18422b86 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Fri, 2 Sep 2022 14:46:47 +0300 Subject: [PATCH 2/7] Update CHANGELOG and FEATURES --- CHANGELOG.md | 1 + FEATURES.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28ad9b358d..a3779bde68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ And please only add new entries to the top of this list, right below the `# Unre - On Wayland, a new `wayland-csd-adwaita-crossfont` feature was added to use `crossfont` instead of `ab_glyph` for decorations. - On Wayland, if not otherwise specified use upstream automatic CSD theme selection. - On Windows, fixed ALT+Space shortcut to open window menu. +- On MacOS, made `accepts_first_mouse` configurable. # 0.27.2 (2022-8-12) diff --git a/FEATURES.md b/FEATURES.md index 3610f4b793..8e7bd75003 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 From 974bfeaafed0d801917daef0dbe01581fa6ae89f Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Fri, 2 Sep 2022 14:53:27 +0300 Subject: [PATCH 3/7] Field doesn't need to be public --- src/platform_impl/macos/view.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 2517d4686c..1de6787d29 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -86,7 +86,7 @@ pub(super) struct ViewState { /// True if the current key event should be forwarded /// to the application, even during IME forward_key_to_app: bool, - pub accepts_first_mouse: bool, + accepts_first_mouse: bool, } impl ViewState { From d2268318182aab06f05623098f97c887a65c26ba Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Fri, 2 Sep 2022 15:19:25 +0300 Subject: [PATCH 4/7] Convert `bool` to `BOOL` --- src/platform_impl/macos/view.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 1de6787d29..b1dee9d75d 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -1306,6 +1306,6 @@ extern "C" fn accepts_first_mouse(this: &Object, _sel: Sel, _event: id) -> BOOL let state_ptr: *const c_void = *this.get_ivar("winitState"); let state = &*(state_ptr as *const ViewState); - state.accepts_first_mouse + state.accepts_first_mouse as BOOL } } From 581dca727d197a17c2499adacccf9df9fd35230d Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Tue, 6 Sep 2022 14:44:11 +0300 Subject: [PATCH 5/7] Fix formatting --- src/platform_impl/macos/view.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 44e1c97fb5..8d8f79f900 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -99,10 +99,7 @@ impl ViewState { } } -pub fn new_view( - ns_window: id, - pl_attribs: &PlatformSpecificWindowBuilderAttributes, -) -> IdRef { +pub fn new_view(ns_window: id, pl_attribs: &PlatformSpecificWindowBuilderAttributes) -> IdRef { let state = ViewState { ns_window, cursor_state: Default::default(), From 9849a6e70263d863504fe50693bc3e9bf8361927 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Mon, 12 Sep 2022 22:35:37 +0300 Subject: [PATCH 6/7] Move flag from window state to view instance --- src/platform_impl/macos/view.rs | 23 ++++++++++++++++++----- src/platform_impl/macos/window.rs | 10 +--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index a086913794..1d068b8b51 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 { @@ -185,6 +190,7 @@ declare_class!( } this.state.input_source = this.current_input_source(); + Ivar::write(&mut this.accepts_first_mouse, accepts_first_mouse); this }) } @@ -907,14 +913,21 @@ declare_class!( #[sel(acceptsFirstMouse:)] fn accepts_first_mouse(&self, _event: &NSEvent) -> bool { trace_scope!("acceptsFirstMouse:"); - self.window().accepts_first_mouse() + println!("acceptsFirstMouse = {}", *self.accepts_first_mouse); + *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 b360fdb196..4fded71d88 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -151,7 +151,6 @@ pub struct SharedState { /// bar in exclusive fullscreen but want to restore the original options when /// transitioning back to borderless fullscreen. save_presentation_opts: Option, - accepts_first_mouse: bool, } impl SharedState { @@ -290,7 +289,6 @@ impl WinitWindow { let state = SharedState { resizable: attrs.resizable, maximized: attrs.maximized, - accepts_first_mouse: pl_attrs.accepts_first_mouse, ..Default::default() }; Ivar::write( @@ -358,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 @@ -1110,12 +1108,6 @@ impl WinitWindow { util::set_style_mask_sync(self, current_style_mask & (!mask)); } } - - #[inline] - pub fn accepts_first_mouse(&self) -> bool { - let shared_state_lock = self.shared_state.lock().unwrap(); - shared_state_lock.accepts_first_mouse - } } impl WindowExtMacOS for WinitWindow { From 88b1e6e8542cfd666f83262322bae984f19aeab3 Mon Sep 17 00:00:00 2001 From: Alex Morega Date: Tue, 13 Sep 2022 16:40:47 +0300 Subject: [PATCH 7/7] Feedback from PR --- src/platform_impl/macos/view.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 694783c3ca..dd1e17d511 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -170,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); @@ -190,7 +191,6 @@ declare_class!( } this.state.input_source = this.current_input_source(); - Ivar::write(&mut this.accepts_first_mouse, accepts_first_mouse); this }) } @@ -917,7 +917,6 @@ declare_class!( #[sel(acceptsFirstMouse:)] fn accepts_first_mouse(&self, _event: &NSEvent) -> bool { trace_scope!("acceptsFirstMouse:"); - println!("acceptsFirstMouse = {}", *self.accepts_first_mouse); *self.accepts_first_mouse } }