mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-03 07:10:05 -04:00
macOS: defer native transitions during event handling
This commit is contained in:
committed by
GitHub
parent
aa6410de30
commit
9e78b4c2a7
@@ -269,6 +269,10 @@ impl AppState {
|
||||
self.control_flow.set(value)
|
||||
}
|
||||
|
||||
pub(super) fn is_handling_event(&self) -> bool {
|
||||
self.event_handler.in_use()
|
||||
}
|
||||
|
||||
pub fn control_flow(&self) -> ControlFlow {
|
||||
self.control_flow.get()
|
||||
}
|
||||
|
||||
@@ -1102,6 +1102,20 @@ impl WindowDelegate {
|
||||
});
|
||||
}
|
||||
|
||||
fn defer_if_handling_event(&self, f: impl FnOnce(Retained<Self>) + 'static) -> bool {
|
||||
// AppKit state transitions such as zoom/fullscreen can synchronously run resize/display
|
||||
// callbacks. Starting them from inside a winit event callback prevents those callbacks
|
||||
// from being delivered immediately, so defer the transition to the next run-loop turn.
|
||||
if !self.ivars().app_state.is_handling_event() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mtm = MainThreadMarker::from(self);
|
||||
let this = self.retain();
|
||||
MainRunLoop::get(mtm).queue_closure(move || f(this));
|
||||
true
|
||||
}
|
||||
|
||||
fn handle_scale_factor_changed(&self, scale_factor: CGFloat) {
|
||||
let window = self.window();
|
||||
|
||||
@@ -1710,6 +1724,10 @@ impl WindowDelegate {
|
||||
|
||||
#[inline]
|
||||
pub fn set_maximized(&self, maximized: bool) {
|
||||
if self.defer_if_handling_event(move |this| this.set_maximized(maximized)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mtm = MainThreadMarker::from(self);
|
||||
let is_zoomed = self.is_zoomed();
|
||||
if is_zoomed == maximized {
|
||||
@@ -1755,9 +1773,6 @@ impl WindowDelegate {
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
||||
let mtm = MainThreadMarker::from(self);
|
||||
let app = NSApplication::sharedApplication(mtm);
|
||||
|
||||
if self.ivars().is_simple_fullscreen.get() {
|
||||
return;
|
||||
}
|
||||
@@ -1786,6 +1801,18 @@ impl WindowDelegate {
|
||||
return;
|
||||
}
|
||||
|
||||
if !self.ivars().initial_fullscreen.get()
|
||||
&& self.defer_if_handling_event({
|
||||
let fullscreen = fullscreen.clone();
|
||||
move |this| this.set_fullscreen(fullscreen)
|
||||
})
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let mtm = MainThreadMarker::from(self);
|
||||
let app = NSApplication::sharedApplication(mtm);
|
||||
|
||||
// If the fullscreen is on a different monitor, we must move the window
|
||||
// to that monitor before we toggle fullscreen (as `toggleFullScreen`
|
||||
// does not take a screen parameter, but uses the current screen)
|
||||
|
||||
Reference in New Issue
Block a user