mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
macOS: Don't change fullscreen state during fullscreen transition (#1331)
* Register windowWillExitFullScreen * On macOS: Do not toggle fullscreen during fullscreen transition * Add CHANGELOG Co-authored-by: Freya Gentz <zegentzy@protonmail.com>
This commit is contained in:
parent
d59eec4633
commit
5d99316c96
|
@ -1,5 +1,6 @@
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- On macOS, fix error when `set_fullscreen` is called during fullscreen transition.
|
||||||
- On all platforms except mobile and WASM, implement `Window::set_minimized`.
|
- On all platforms except mobile and WASM, implement `Window::set_minimized`.
|
||||||
- On X11, fix `CursorEntered` event being generated for non-winit windows.
|
- On X11, fix `CursorEntered` event being generated for non-winit windows.
|
||||||
- On macOS, fix crash when starting maximized without decorations.
|
- On macOS, fix crash when starting maximized without decorations.
|
||||||
|
|
|
@ -243,6 +243,13 @@ lazy_static! {
|
||||||
pub struct SharedState {
|
pub struct SharedState {
|
||||||
pub resizable: bool,
|
pub resizable: bool,
|
||||||
pub fullscreen: Option<Fullscreen>,
|
pub fullscreen: Option<Fullscreen>,
|
||||||
|
// This is true between windowWillEnterFullScreen and windowDidEnterFullScreen
|
||||||
|
// or windowWillExitFullScreen and windowDidExitFullScreen.
|
||||||
|
// We must not toggle fullscreen when this is true.
|
||||||
|
pub in_fullscreen_transition: bool,
|
||||||
|
// If it is attempted to toggle fullscreen when in_fullscreen_transition is true,
|
||||||
|
// Set target_fullscreen and do after fullscreen transition is end.
|
||||||
|
pub target_fullscreen: Option<Option<Fullscreen>>,
|
||||||
pub maximized: bool,
|
pub maximized: bool,
|
||||||
pub standard_frame: Option<NSRect>,
|
pub standard_frame: Option<NSRect>,
|
||||||
is_simple_fullscreen: bool,
|
is_simple_fullscreen: bool,
|
||||||
|
@ -661,11 +668,18 @@ impl UnownedWindow {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
||||||
trace!("Locked shared state in `set_fullscreen`");
|
trace!("Locked shared state in `set_fullscreen`");
|
||||||
let shared_state_lock = self.shared_state.lock().unwrap();
|
let mut shared_state_lock = self.shared_state.lock().unwrap();
|
||||||
if shared_state_lock.is_simple_fullscreen {
|
if shared_state_lock.is_simple_fullscreen {
|
||||||
trace!("Unlocked shared state in `set_fullscreen`");
|
trace!("Unlocked shared state in `set_fullscreen`");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if shared_state_lock.in_fullscreen_transition {
|
||||||
|
// We can't set fullscreen here.
|
||||||
|
// Set fullscreen after transition.
|
||||||
|
shared_state_lock.target_fullscreen = Some(fullscreen);
|
||||||
|
trace!("Unlocked shared state in `set_fullscreen`");
|
||||||
|
return;
|
||||||
|
}
|
||||||
let old_fullscreen = shared_state_lock.fullscreen.clone();
|
let old_fullscreen = shared_state_lock.fullscreen.clone();
|
||||||
if fullscreen == old_fullscreen {
|
if fullscreen == old_fullscreen {
|
||||||
trace!("Unlocked shared state in `set_fullscreen`");
|
trace!("Unlocked shared state in `set_fullscreen`");
|
||||||
|
|
|
@ -195,6 +195,10 @@ lazy_static! {
|
||||||
sel!(windowDidExitFullScreen:),
|
sel!(windowDidExitFullScreen:),
|
||||||
window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id),
|
window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id),
|
||||||
);
|
);
|
||||||
|
decl.add_method(
|
||||||
|
sel!(windowWillExitFullScreen:),
|
||||||
|
window_will_exit_fullscreen as extern "C" fn(&Object, Sel, id),
|
||||||
|
);
|
||||||
decl.add_method(
|
decl.add_method(
|
||||||
sel!(windowDidFailToEnterFullScreen:),
|
sel!(windowDidFailToEnterFullScreen:),
|
||||||
window_did_fail_to_enter_fullscreen as extern "C" fn(&Object, Sel, id),
|
window_did_fail_to_enter_fullscreen as extern "C" fn(&Object, Sel, id),
|
||||||
|
@ -419,13 +423,27 @@ extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
shared_state.fullscreen = Some(Fullscreen::Borderless(window.current_monitor()))
|
shared_state.fullscreen = Some(Fullscreen::Borderless(window.current_monitor()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
shared_state.in_fullscreen_transition = true;
|
||||||
trace!("Unlocked shared state in `window_will_enter_fullscreen`");
|
trace!("Unlocked shared state in `window_will_enter_fullscreen`");
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
trace!("Completed `windowWillEnterFullscreen:`");
|
trace!("Completed `windowWillEnterFullscreen:`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Invoked when before exit fullscreen
|
||||||
|
extern "C" fn window_will_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
|
trace!("Triggered `windowWillExitFullScreen:`");
|
||||||
|
with_state(this, |state| {
|
||||||
|
state.with_window(|window| {
|
||||||
|
trace!("Locked shared state in `window_will_exit_fullscreen`");
|
||||||
|
let mut shared_state = window.shared_state.lock().unwrap();
|
||||||
|
shared_state.in_fullscreen_transition = true;
|
||||||
|
trace!("Unlocked shared state in `window_will_exit_fullscreen`");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
trace!("Completed `windowWillExitFullScreen:`");
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn window_will_use_fullscreen_presentation_options(
|
extern "C" fn window_will_use_fullscreen_presentation_options(
|
||||||
_this: &Object,
|
_this: &Object,
|
||||||
_: Sel,
|
_: Sel,
|
||||||
|
@ -451,6 +469,17 @@ extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
trace!("Triggered `windowDidEnterFullscreen:`");
|
trace!("Triggered `windowDidEnterFullscreen:`");
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.initial_fullscreen = false;
|
state.initial_fullscreen = false;
|
||||||
|
state.with_window(|window| {
|
||||||
|
trace!("Locked shared state in `window_did_enter_fullscreen`");
|
||||||
|
let mut shared_state = window.shared_state.lock().unwrap();
|
||||||
|
shared_state.in_fullscreen_transition = false;
|
||||||
|
let target_fullscreen = shared_state.target_fullscreen.take();
|
||||||
|
trace!("Unlocked shared state in `window_did_enter_fullscreen`");
|
||||||
|
drop(shared_state);
|
||||||
|
if let Some(target_fullscreen) = target_fullscreen {
|
||||||
|
window.set_fullscreen(target_fullscreen);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
trace!("Completed `windowDidEnterFullscreen:`");
|
trace!("Completed `windowDidEnterFullscreen:`");
|
||||||
}
|
}
|
||||||
|
@ -461,6 +490,15 @@ extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
state.with_window(|window| {
|
state.with_window(|window| {
|
||||||
window.restore_state_from_fullscreen();
|
window.restore_state_from_fullscreen();
|
||||||
|
trace!("Locked shared state in `window_did_exit_fullscreen`");
|
||||||
|
let mut shared_state = window.shared_state.lock().unwrap();
|
||||||
|
shared_state.in_fullscreen_transition = false;
|
||||||
|
let target_fullscreen = shared_state.target_fullscreen.take();
|
||||||
|
trace!("Unlocked shared state in `window_did_exit_fullscreen`");
|
||||||
|
drop(shared_state);
|
||||||
|
if let Some(target_fullscreen) = target_fullscreen {
|
||||||
|
window.set_fullscreen(target_fullscreen);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
trace!("Completed `windowDidExitFullscreen:`");
|
trace!("Completed `windowDidExitFullscreen:`");
|
||||||
|
@ -485,6 +523,13 @@ extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
extern "C" fn window_did_fail_to_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
extern "C" fn window_did_fail_to_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||||
trace!("Triggered `windowDidFailToEnterFullscreen:`");
|
trace!("Triggered `windowDidFailToEnterFullscreen:`");
|
||||||
with_state(this, |state| {
|
with_state(this, |state| {
|
||||||
|
state.with_window(|window| {
|
||||||
|
trace!("Locked shared state in `window_did_fail_to_enter_fullscreen`");
|
||||||
|
let mut shared_state = window.shared_state.lock().unwrap();
|
||||||
|
shared_state.in_fullscreen_transition = false;
|
||||||
|
shared_state.target_fullscreen = None;
|
||||||
|
trace!("Unlocked shared state in `window_did_fail_to_enter_fullscreen`");
|
||||||
|
});
|
||||||
if state.initial_fullscreen {
|
if state.initial_fullscreen {
|
||||||
let _: () = unsafe {
|
let _: () = unsafe {
|
||||||
msg_send![*state.ns_window,
|
msg_send![*state.ns_window,
|
||||||
|
|
Loading…
Reference in a new issue