diff --git a/src/platform_impl/macos/app.rs b/src/platform_impl/macos/app.rs index 38372f4297..dba211ad64 100644 --- a/src/platform_impl/macos/app.rs +++ b/src/platform_impl/macos/app.rs @@ -5,6 +5,7 @@ use objc2_app_kit::{NSApplication, NSEvent, NSEventModifierFlags, NSEventType, N use objc2_foundation::{MainThreadMarker, NSObject}; use super::app_state::ApplicationDelegate; +use super::DEVICE_ID; use crate::event::{DeviceEvent, ElementState}; declare_class!( @@ -57,29 +58,47 @@ fn maybe_dispatch_device_event(delegate: &ApplicationDelegate, event: &NSEvent) let delta_y = unsafe { event.deltaY() } as f64; if delta_x != 0.0 { - delegate.maybe_queue_device_event(DeviceEvent::Motion { axis: 0, value: delta_x }); + delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.device_event(event_loop, DEVICE_ID, DeviceEvent::Motion { + axis: 0, + value: delta_x, + }) + }); } if delta_y != 0.0 { - delegate.maybe_queue_device_event(DeviceEvent::Motion { axis: 1, value: delta_y }) + delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.device_event(event_loop, DEVICE_ID, DeviceEvent::Motion { + axis: 1, + value: delta_y, + }) + }) } if delta_x != 0.0 || delta_y != 0.0 { - delegate.maybe_queue_device_event(DeviceEvent::MouseMotion { - delta: (delta_x, delta_y), + delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.device_event(event_loop, DEVICE_ID, DeviceEvent::MouseMotion { + delta: (delta_x, delta_y), + }) }); } }, NSEventType::LeftMouseDown | NSEventType::RightMouseDown | NSEventType::OtherMouseDown => { - delegate.maybe_queue_device_event(DeviceEvent::Button { - button: unsafe { event.buttonNumber() } as u32, - state: ElementState::Pressed, + let button = unsafe { event.buttonNumber() } as u32; + delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.device_event(event_loop, DEVICE_ID, DeviceEvent::Button { + button, + state: ElementState::Pressed, + }) }); }, NSEventType::LeftMouseUp | NSEventType::RightMouseUp | NSEventType::OtherMouseUp => { - delegate.maybe_queue_device_event(DeviceEvent::Button { - button: unsafe { event.buttonNumber() } as u32, - state: ElementState::Released, + let button = unsafe { event.buttonNumber() } as u32; + delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.device_event(event_loop, DEVICE_ID, DeviceEvent::Button { + button, + state: ElementState::Released, + }) }); }, _ => (), diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index d574521b6a..d61dcd8585 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -11,14 +11,14 @@ use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSApplicationD use objc2_foundation::{MainThreadMarker, NSNotification, NSObject, NSObjectProtocol}; use crate::application::ApplicationHandler; -use crate::event::{DeviceEvent, StartCause, WindowEvent}; +use crate::event::{StartCause, WindowEvent}; use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow}; use crate::window::WindowId as RootWindowId; use super::event_handler::EventHandler; use super::event_loop::{stop_app_immediately, ActiveEventLoop, PanicInfo}; use super::observer::{EventLoopWaker, RunLoop}; -use super::{menu, WindowId, DEVICE_ID}; +use super::{menu, WindowId}; #[derive(Debug)] pub(super) struct AppState { @@ -251,7 +251,10 @@ impl ApplicationDelegate { } #[track_caller] - pub fn maybe_queue_window_event(&self, window_id: WindowId, event: WindowEvent) { + pub fn maybe_queue_with_user_app( + &self, + callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop) + 'static, + ) { // Most programmer actions in AppKit (e.g. change window fullscreen, set focused, etc.) // result in an event being queued, and applied at a later point. // @@ -259,40 +262,12 @@ impl ApplicationDelegate { // so to make sure that we don't encounter re-entrancy issues, we first check if we're // currently handling another event, and if we are, we queue the event instead. if !self.ivars().event_handler.in_use() { - self.with_user_app(|app, event_loop| { - app.window_event(event_loop, RootWindowId(window_id), event); - }); - } else { - tracing::debug!( - ?event, - "had to queue window event since another is currently being handled" - ); - let this = self.retain(); - self.ivars().run_loop.queue_closure(move || { - this.with_user_app(|app, event_loop| { - app.window_event(event_loop, RootWindowId(window_id), event); - }) - }); - } - } - - #[track_caller] - pub fn maybe_queue_device_event(&self, event: DeviceEvent) { - // The same as in maybe_queue_window_event. - if !self.ivars().event_handler.in_use() { - self.with_user_app(|app, event_loop| { - app.device_event(event_loop, DEVICE_ID, event); - }); + self.with_user_app(callback); } else { - tracing::debug!( - ?event, - "had to queue device event since another is currently being handled" - ); + tracing::debug!("had to queue event since another is currently being handled"); let this = self.retain(); self.ivars().run_loop.queue_closure(move || { - this.with_user_app(|app, event_loop| { - app.device_event(event_loop, DEVICE_ID, event); - }) + this.with_user_app(callback); }); } } diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index ec9c7eb69b..167ee9c5e8 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -236,7 +236,7 @@ impl EventLoop { p: ActiveEventLoop { delegate, mtm }, _marker: PhantomData, }, - user_wake_up: Arc::new(AtomicBool::new(false)), + user_wake_up, panic_info, }) } diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 50cffcee67..a3520db9be 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -31,6 +31,7 @@ use crate::event::{ }; use crate::keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NamedKey}; use crate::platform::macos::OptionAsAlt; +use crate::window::WindowId as RootWindowId; #[derive(Debug)] struct CursorState { @@ -686,7 +687,9 @@ declare_class!( self.update_modifiers(event, false); - self.ivars().app_delegate.maybe_queue_device_event(DeviceEvent::MouseWheel { delta }); + self.ivars().app_delegate.maybe_queue_with_user_app(move |app, event_loop| + app.device_event(event_loop, DEVICE_ID, DeviceEvent::MouseWheel { delta }) + ); self.queue_event(WindowEvent::MouseWheel { device_id: DEVICE_ID, delta, @@ -830,7 +833,10 @@ impl WinitView { } fn queue_event(&self, event: WindowEvent) { - self.ivars().app_delegate.maybe_queue_window_event(self.window().id(), event); + let window_id = RootWindowId(self.window().id()); + self.ivars().app_delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.window_event(event_loop, window_id, event) + }); } fn scale_factor(&self) -> f64 { diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 07ad35dac7..0a26d91a13 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -35,7 +35,7 @@ use crate::event::{InnerSizeWriter, WindowEvent}; use crate::platform::macos::{OptionAsAlt, WindowExtMacOS}; use crate::window::{ Cursor, CursorGrabMode, Icon, ImePurpose, ResizeDirection, Theme, UserAttentionType, - WindowAttributes, WindowButtons, WindowLevel, + WindowAttributes, WindowButtons, WindowId as RootWindowId, WindowLevel, }; #[derive(Clone, Debug)] @@ -771,7 +771,10 @@ impl WindowDelegate { } pub(crate) fn queue_event(&self, event: WindowEvent) { - self.ivars().app_delegate.maybe_queue_window_event(self.window().id(), event); + let window_id = RootWindowId(self.window().id()); + self.ivars().app_delegate.maybe_queue_with_user_app(move |app, event_loop| { + app.window_event(event_loop, window_id, event) + }); } fn handle_scale_factor_changed(&self, scale_factor: CGFloat) {