Skip to content

Commit

Permalink
Do fullscreen logic synchronously on main thread
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Nov 30, 2022
1 parent bf92f3e commit 90f71b3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 24 deletions.
24 changes: 11 additions & 13 deletions src/platform_impl/macos/util/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::ops::Deref;

use dispatch::Queue;
use objc2::foundation::{is_main_thread, CGFloat, NSPoint, NSSize, NSString};
use objc2::rc::{autoreleasepool, Id, Shared};
use objc2::rc::autoreleasepool;

use crate::{
dpi::LogicalSize,
Expand Down Expand Up @@ -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
// 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);
Queue::main().exec_async(move || {
run_on_main(move || {
// `toggleFullScreen` doesn't work if the `StyleMask` is none, so we
// set a normal style temporarily. The previous state will be
// restored in `WindowDelegate::window_did_exit_fullscreen`.
Expand All @@ -103,7 +103,7 @@ pub(crate) fn toggle_full_screen_async(window: Id<WinitWindow, Shared>, not_full
if !curr_mask.contains(required) {
set_style_mask(&window, required);
window
.lock_shared_state("toggle_full_screen_async")
.lock_shared_state("toggle_full_screen_sync")
.saved_style = Some(curr_mask);
}
}
Expand All @@ -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) {
Queue::main().exec_async(move || {
pub(crate) unsafe fn restore_display_mode_sync(ns_screen: u32) {
run_on_main(move || {
unsafe { ffi::CGRestorePermanentDisplayConfiguration() };
assert_eq!(
unsafe { ffi::CGDisplayRelease(ns_screen) },
Expand All @@ -126,14 +126,10 @@ pub(crate) unsafe fn restore_display_mode_async(ns_screen: u32) {
}

// `setMaximized` is not thread-safe
pub(crate) fn set_maximized_async(
window: Id<WinitWindow, Shared>,
is_zoomed: bool,
maximized: bool,
) {
pub(crate) fn set_maximized_sync(window: &WinitWindow, is_zoomed: bool, maximized: bool) {
let window = MainThreadSafe(window);
Queue::main().exec_async(move || {
let mut shared_state = window.lock_shared_state("set_maximized_async");
run_on_main(move || {
let mut shared_state = window.lock_shared_state("set_maximized_sync");
// Save the standard frame sized if it is not zoomed
if !is_zoomed {
shared_state.standard_frame = Some(window.frame());
Expand All @@ -150,6 +146,7 @@ pub(crate) fn set_maximized_async(
.styleMask()
.contains(NSWindowStyleMask::NSResizableWindowMask)
{
drop(shared_state);
// Just use the native zoom if resizable
window.zoom(None);
} else {
Expand All @@ -160,6 +157,7 @@ pub(crate) fn set_maximized_async(
} else {
shared_state.saved_standard_frame()
};
drop(shared_state);
window.setFrame_display(new_rect, false);
}
});
Expand Down
24 changes: 13 additions & 11 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ impl WinitWindow {
if is_zoomed == maximized {
return;
};
util::set_maximized_async(self.retain(), is_zoomed, maximized);
util::set_maximized_sync(self, is_zoomed, maximized);
}

#[inline]
Expand Down Expand Up @@ -956,23 +956,22 @@ impl WinitWindow {
}
}

let mut shared_state_lock = self.lock_shared_state("set_fullscreen");
shared_state_lock.fullscreen = fullscreen.clone();
self.lock_shared_state("set_fullscreen").fullscreen = fullscreen.clone();

match (&old_fullscreen, &fullscreen) {
(&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) => {
// 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) => {
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`
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(_))) => {
// If we're already in fullscreen mode, calling
Expand All @@ -984,7 +983,8 @@ impl WinitWindow {
// that the menu bar is disabled. This is done in the window
// delegate in `window:willUseFullScreenPresentationOptions:`.
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 =
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
Expand All @@ -997,16 +997,18 @@ impl WinitWindow {
self.setLevel(window_level);
}
(&Some(Fullscreen::Exclusive(ref video_mode)), &Some(Fullscreen::Borderless(_))) => {
let presentation_options =
shared_state_lock.save_presentation_opts.unwrap_or_else(|| {
let presentation_options = self
.lock_shared_state("set_fullscreen")
.save_presentation_opts
.unwrap_or_else(|| {
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar
});
NSApp().setPresentationOptions(presentation_options);

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
Expand Down

0 comments on commit 90f71b3

Please sign in to comment.