mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-23 02:16:33 +11:00
Fix freeze upon exiting exclusive fullscreen on macOS 10.15 (#1127)
This commit is contained in:
parent
57a53bda74
commit
28a5feef28
3 changed files with 53 additions and 47 deletions
|
@ -9,6 +9,7 @@
|
||||||
- On macOS, differentiate between `CursorIcon::Grab` and `CursorIcon::Grabbing`.
|
- On macOS, differentiate between `CursorIcon::Grab` and `CursorIcon::Grabbing`.
|
||||||
- On Wayland, fix event processing sometimes stalling when using OpenGL with vsync.
|
- On Wayland, fix event processing sometimes stalling when using OpenGL with vsync.
|
||||||
- Officially remove the Emscripten backend
|
- Officially remove the Emscripten backend
|
||||||
|
- On macOS 10.15, fix freeze upon exiting exclusive fullscreen mode.
|
||||||
|
|
||||||
# 0.20.0 Alpha 3 (2019-08-14)
|
# 0.20.0 Alpha 3 (2019-08-14)
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,21 @@ pub unsafe fn toggle_full_screen_async(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn restore_display_mode_callback(screen: *mut c_void) {
|
||||||
|
unsafe {
|
||||||
|
let screen = Box::from_raw(screen as *mut u32);
|
||||||
|
ffi::CGRestorePermanentDisplayConfiguration();
|
||||||
|
assert_eq!(ffi::CGDisplayRelease(*screen), ffi::kCGErrorSuccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub unsafe fn restore_display_mode_async(ns_screen: u32) {
|
||||||
|
dispatch_async_f(
|
||||||
|
dispatch_get_main_queue(),
|
||||||
|
Box::into_raw(Box::new(ns_screen)) as *mut _,
|
||||||
|
restore_display_mode_callback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
struct SetMaximizedData {
|
struct SetMaximizedData {
|
||||||
ns_window: id,
|
ns_window: id,
|
||||||
is_zoomed: bool,
|
is_zoomed: bool,
|
||||||
|
|
|
@ -617,25 +617,6 @@ impl UnownedWindow {
|
||||||
self.set_maximized(maximized);
|
self.set_maximized(maximized);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore_display_mode(&self) {
|
|
||||||
trace!("Locked shared state in `restore_display_mode`");
|
|
||||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
|
||||||
|
|
||||||
if let Some(Fullscreen::Exclusive(RootVideoMode { ref video_mode })) =
|
|
||||||
shared_state_lock.fullscreen
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
ffi::CGRestorePermanentDisplayConfiguration();
|
|
||||||
assert_eq!(
|
|
||||||
ffi::CGDisplayRelease(video_mode.monitor().inner.native_identifier()),
|
|
||||||
ffi::kCGErrorSuccess
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trace!("Unlocked shared state in `restore_display_mode`");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_maximized(&self, maximized: bool) {
|
pub fn set_maximized(&self, maximized: bool) {
|
||||||
let is_zoomed = self.is_zoomed();
|
let is_zoomed = self.is_zoomed();
|
||||||
|
@ -763,7 +744,39 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!("Locked shared state in `set_fullscreen`");
|
||||||
|
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||||
|
shared_state_lock.fullscreen = fullscreen.clone();
|
||||||
|
trace!("Unlocked shared state in `set_fullscreen`");
|
||||||
|
|
||||||
match (&old_fullscreen, &fullscreen) {
|
match (&old_fullscreen, &fullscreen) {
|
||||||
|
(&None, &Some(_)) => unsafe {
|
||||||
|
util::toggle_full_screen_async(
|
||||||
|
*self.ns_window,
|
||||||
|
*self.ns_view,
|
||||||
|
old_fullscreen.is_none(),
|
||||||
|
Arc::downgrade(&self.shared_state),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(&Some(Fullscreen::Borderless(_)), &None) => unsafe {
|
||||||
|
// State is restored by `window_did_exit_fullscreen`
|
||||||
|
util::toggle_full_screen_async(
|
||||||
|
*self.ns_window,
|
||||||
|
*self.ns_view,
|
||||||
|
old_fullscreen.is_none(),
|
||||||
|
Arc::downgrade(&self.shared_state),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(&Some(Fullscreen::Exclusive(RootVideoMode { ref video_mode })), &None) => unsafe {
|
||||||
|
util::restore_display_mode_async(video_mode.monitor().inner.native_identifier());
|
||||||
|
// Rest of the state is restored by `window_did_exit_fullscreen`
|
||||||
|
util::toggle_full_screen_async(
|
||||||
|
*self.ns_window,
|
||||||
|
*self.ns_view,
|
||||||
|
old_fullscreen.is_none(),
|
||||||
|
Arc::downgrade(&self.shared_state),
|
||||||
|
);
|
||||||
|
},
|
||||||
(&Some(Fullscreen::Borderless(_)), &Some(Fullscreen::Exclusive(_))) => unsafe {
|
(&Some(Fullscreen::Borderless(_)), &Some(Fullscreen::Exclusive(_))) => unsafe {
|
||||||
// If we're already in fullscreen mode, calling
|
// If we're already in fullscreen mode, calling
|
||||||
// `CGDisplayCapture` will place the shielding window on top of
|
// `CGDisplayCapture` will place the shielding window on top of
|
||||||
|
@ -775,37 +788,14 @@ impl UnownedWindow {
|
||||||
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
||||||
msg_send![*self.ns_window, setLevel: ffi::CGShieldingWindowLevel() + 1];
|
msg_send![*self.ns_window, setLevel: ffi::CGShieldingWindowLevel() + 1];
|
||||||
},
|
},
|
||||||
(&Some(Fullscreen::Exclusive(_)), &None) => unsafe {
|
(
|
||||||
self.restore_display_mode();
|
&Some(Fullscreen::Exclusive(RootVideoMode { ref video_mode })),
|
||||||
|
&Some(Fullscreen::Borderless(_)),
|
||||||
util::toggle_full_screen_async(
|
) => unsafe {
|
||||||
*self.ns_window,
|
util::restore_display_mode_async(video_mode.monitor().inner.native_identifier());
|
||||||
*self.ns_view,
|
|
||||||
old_fullscreen.is_none(),
|
|
||||||
Arc::downgrade(&self.shared_state),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
(&Some(Fullscreen::Exclusive(_)), &Some(Fullscreen::Borderless(_))) => {
|
|
||||||
self.restore_display_mode();
|
|
||||||
}
|
|
||||||
(&None, &Some(Fullscreen::Exclusive(_)))
|
|
||||||
| (&None, &Some(Fullscreen::Borderless(_)))
|
|
||||||
| (&Some(Fullscreen::Borderless(_)), &None) => unsafe {
|
|
||||||
// Wish it were this simple for all cases
|
|
||||||
util::toggle_full_screen_async(
|
|
||||||
*self.ns_window,
|
|
||||||
*self.ns_view,
|
|
||||||
old_fullscreen.is_none(),
|
|
||||||
Arc::downgrade(&self.shared_state),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("Locked shared state in `set_fullscreen`");
|
|
||||||
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
|
||||||
shared_state_lock.fullscreen = fullscreen.clone();
|
|
||||||
trace!("Unlocked shared state in `set_fullscreen`");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Add table
Reference in a new issue