mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Do fullscreen logic synchronously on main thread (#2575)
This commit is contained in:
parent
bf92f3e97b
commit
2e4d79f57a
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
||||||
|
|
||||||
use dispatch::Queue;
|
use dispatch::Queue;
|
||||||
use objc2::foundation::{is_main_thread, CGFloat, NSPoint, NSSize, NSString};
|
use objc2::foundation::{is_main_thread, CGFloat, NSPoint, NSSize, NSString};
|
||||||
use objc2::rc::{autoreleasepool, Id, Shared};
|
use objc2::rc::autoreleasepool;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
|
@ -90,9 +90,9 @@ pub(crate) fn set_ignore_mouse_events_sync(window: &NSWindow, ignore: bool) {
|
||||||
|
|
||||||
// `toggleFullScreen` is thread-safe, but our additional logic to account for
|
// `toggleFullScreen` is thread-safe, but our additional logic to account for
|
||||||
// window styles isn't.
|
// window styles isn't.
|
||||||
pub(crate) fn toggle_full_screen_async(window: Id<WinitWindow, Shared>, not_fullscreen: bool) {
|
pub(crate) fn toggle_full_screen_sync(window: &WinitWindow, not_fullscreen: bool) {
|
||||||
let window = MainThreadSafe(window);
|
let window = MainThreadSafe(window);
|
||||||
Queue::main().exec_async(move || {
|
run_on_main(move || {
|
||||||
// `toggleFullScreen` doesn't work if the `StyleMask` is none, so we
|
// `toggleFullScreen` doesn't work if the `StyleMask` is none, so we
|
||||||
// set a normal style temporarily. The previous state will be
|
// set a normal style temporarily. The previous state will be
|
||||||
// restored in `WindowDelegate::window_did_exit_fullscreen`.
|
// restored in `WindowDelegate::window_did_exit_fullscreen`.
|
||||||
|
@ -103,7 +103,7 @@ pub(crate) fn toggle_full_screen_async(window: Id<WinitWindow, Shared>, not_full
|
||||||
if !curr_mask.contains(required) {
|
if !curr_mask.contains(required) {
|
||||||
set_style_mask(&window, required);
|
set_style_mask(&window, required);
|
||||||
window
|
window
|
||||||
.lock_shared_state("toggle_full_screen_async")
|
.lock_shared_state("toggle_full_screen_sync")
|
||||||
.saved_style = Some(curr_mask);
|
.saved_style = Some(curr_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,8 +115,8 @@ pub(crate) fn toggle_full_screen_async(window: Id<WinitWindow, Shared>, not_full
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn restore_display_mode_async(ns_screen: u32) {
|
pub(crate) unsafe fn restore_display_mode_sync(ns_screen: u32) {
|
||||||
Queue::main().exec_async(move || {
|
run_on_main(move || {
|
||||||
unsafe { ffi::CGRestorePermanentDisplayConfiguration() };
|
unsafe { ffi::CGRestorePermanentDisplayConfiguration() };
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsafe { ffi::CGDisplayRelease(ns_screen) },
|
unsafe { ffi::CGDisplayRelease(ns_screen) },
|
||||||
|
@ -126,14 +126,10 @@ pub(crate) unsafe fn restore_display_mode_async(ns_screen: u32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// `setMaximized` is not thread-safe
|
// `setMaximized` is not thread-safe
|
||||||
pub(crate) fn set_maximized_async(
|
pub(crate) fn set_maximized_sync(window: &WinitWindow, is_zoomed: bool, maximized: bool) {
|
||||||
window: Id<WinitWindow, Shared>,
|
|
||||||
is_zoomed: bool,
|
|
||||||
maximized: bool,
|
|
||||||
) {
|
|
||||||
let window = MainThreadSafe(window);
|
let window = MainThreadSafe(window);
|
||||||
Queue::main().exec_async(move || {
|
run_on_main(move || {
|
||||||
let mut shared_state = window.lock_shared_state("set_maximized_async");
|
let mut shared_state = window.lock_shared_state("set_maximized_sync");
|
||||||
// Save the standard frame sized if it is not zoomed
|
// Save the standard frame sized if it is not zoomed
|
||||||
if !is_zoomed {
|
if !is_zoomed {
|
||||||
shared_state.standard_frame = Some(window.frame());
|
shared_state.standard_frame = Some(window.frame());
|
||||||
|
@ -150,6 +146,7 @@ pub(crate) fn set_maximized_async(
|
||||||
.styleMask()
|
.styleMask()
|
||||||
.contains(NSWindowStyleMask::NSResizableWindowMask)
|
.contains(NSWindowStyleMask::NSResizableWindowMask)
|
||||||
{
|
{
|
||||||
|
drop(shared_state);
|
||||||
// Just use the native zoom if resizable
|
// Just use the native zoom if resizable
|
||||||
window.zoom(None);
|
window.zoom(None);
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,6 +157,7 @@ pub(crate) fn set_maximized_async(
|
||||||
} else {
|
} else {
|
||||||
shared_state.saved_standard_frame()
|
shared_state.saved_standard_frame()
|
||||||
};
|
};
|
||||||
|
drop(shared_state);
|
||||||
window.setFrame_display(new_rect, false);
|
window.setFrame_display(new_rect, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -826,7 +826,7 @@ impl WinitWindow {
|
||||||
if is_zoomed == maximized {
|
if is_zoomed == maximized {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
util::set_maximized_async(self.retain(), is_zoomed, maximized);
|
util::set_maximized_sync(self, is_zoomed, maximized);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -956,23 +956,22 @@ impl WinitWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
|
self.lock_shared_state("set_fullscreen").fullscreen = fullscreen.clone();
|
||||||
shared_state_lock.fullscreen = fullscreen.clone();
|
|
||||||
|
|
||||||
match (&old_fullscreen, &fullscreen) {
|
match (&old_fullscreen, &fullscreen) {
|
||||||
(&None, &Some(_)) => {
|
(&None, &Some(_)) => {
|
||||||
util::toggle_full_screen_async(self.retain(), old_fullscreen.is_none());
|
util::toggle_full_screen_sync(self, old_fullscreen.is_none());
|
||||||
}
|
}
|
||||||
(&Some(Fullscreen::Borderless(_)), &None) => {
|
(&Some(Fullscreen::Borderless(_)), &None) => {
|
||||||
// State is restored by `window_did_exit_fullscreen`
|
// State is restored by `window_did_exit_fullscreen`
|
||||||
util::toggle_full_screen_async(self.retain(), old_fullscreen.is_none());
|
util::toggle_full_screen_sync(self, old_fullscreen.is_none());
|
||||||
}
|
}
|
||||||
(&Some(Fullscreen::Exclusive(ref video_mode)), &None) => {
|
(&Some(Fullscreen::Exclusive(ref video_mode)), &None) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
util::restore_display_mode_async(video_mode.monitor().native_identifier())
|
util::restore_display_mode_sync(video_mode.monitor().native_identifier())
|
||||||
};
|
};
|
||||||
// Rest of the state is restored by `window_did_exit_fullscreen`
|
// Rest of the state is restored by `window_did_exit_fullscreen`
|
||||||
util::toggle_full_screen_async(self.retain(), old_fullscreen.is_none());
|
util::toggle_full_screen_sync(self, old_fullscreen.is_none());
|
||||||
}
|
}
|
||||||
(&Some(Fullscreen::Borderless(_)), &Some(Fullscreen::Exclusive(_))) => {
|
(&Some(Fullscreen::Borderless(_)), &Some(Fullscreen::Exclusive(_))) => {
|
||||||
// If we're already in fullscreen mode, calling
|
// If we're already in fullscreen mode, calling
|
||||||
|
@ -984,7 +983,8 @@ impl WinitWindow {
|
||||||
// that the menu bar is disabled. This is done in the window
|
// that the menu bar is disabled. This is done in the window
|
||||||
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
||||||
let app = NSApp();
|
let app = NSApp();
|
||||||
shared_state_lock.save_presentation_opts = Some(app.presentationOptions());
|
self.lock_shared_state("set_fullscreen")
|
||||||
|
.save_presentation_opts = Some(app.presentationOptions());
|
||||||
|
|
||||||
let presentation_options =
|
let presentation_options =
|
||||||
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
||||||
|
@ -997,8 +997,10 @@ impl WinitWindow {
|
||||||
self.setLevel(window_level);
|
self.setLevel(window_level);
|
||||||
}
|
}
|
||||||
(&Some(Fullscreen::Exclusive(ref video_mode)), &Some(Fullscreen::Borderless(_))) => {
|
(&Some(Fullscreen::Exclusive(ref video_mode)), &Some(Fullscreen::Borderless(_))) => {
|
||||||
let presentation_options =
|
let presentation_options = self
|
||||||
shared_state_lock.save_presentation_opts.unwrap_or_else(|| {
|
.lock_shared_state("set_fullscreen")
|
||||||
|
.save_presentation_opts
|
||||||
|
.unwrap_or_else(|| {
|
||||||
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock
|
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar
|
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar
|
||||||
|
@ -1006,7 +1008,7 @@ impl WinitWindow {
|
||||||
NSApp().setPresentationOptions(presentation_options);
|
NSApp().setPresentationOptions(presentation_options);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
util::restore_display_mode_async(video_mode.monitor().native_identifier())
|
util::restore_display_mode_sync(video_mode.monitor().native_identifier())
|
||||||
};
|
};
|
||||||
|
|
||||||
// Restore the normal window level following the Borderless fullscreen
|
// Restore the normal window level following the Borderless fullscreen
|
||||||
|
|
Loading…
Reference in a new issue