Skip to content

Commit

Permalink
macOS: use common maybe_queue_with_user_app
Browse files Browse the repository at this point in the history
  • Loading branch information
kchibisov committed Jun 17, 2024
1 parent a2cf090 commit e99f7b5
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 49 deletions.
39 changes: 29 additions & 10 deletions src/platform_impl/macos/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down Expand Up @@ -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,
})
});
},
_ => (),
Expand Down
43 changes: 9 additions & 34 deletions src/platform_impl/macos/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -251,48 +251,23 @@ 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.
//
// However, it is not documented which actions do this, and which ones are done immediately,
// 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);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/macos/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
}
Expand Down
10 changes: 8 additions & 2 deletions src/platform_impl/macos/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
7 changes: 5 additions & 2 deletions src/platform_impl/macos/window_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit e99f7b5

Please sign in to comment.