diff --git a/CHANGELOG.md b/CHANGELOG.md index e92fb8fa..efbf56e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ - Removed `derivative` crate dependency. - On Wayland, add support for set_cursor_icon. - Use `impl Iterator` instead of `AvailableMonitorsIter` consistently. +- On macOS, fix fullscreen state being updated after entering fullscreen instead of before, + resulting in `Window::fullscreen` returning the old state in `Resized` events instead of + reflecting the new fullscreen state - On X11, fix use-after-free during window creation # 0.20.0 Alpha 3 (2019-08-14) diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 041edf61..cb1bf3c2 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -402,7 +402,24 @@ extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) { with_state(this, |state| { state.with_window(|window| { trace!("Locked shared state in `window_will_enter_fullscreen`"); - window.shared_state.lock().unwrap().maximized = window.is_zoomed(); + let mut shared_state = window.shared_state.lock().unwrap(); + shared_state.maximized = window.is_zoomed(); + match shared_state.fullscreen { + // Exclusive mode sets the state in `set_fullscreen` as the user + // can't enter exclusive mode by other means (like the + // fullscreen button on the window decorations) + Some(Fullscreen::Exclusive(_)) => (), + // `window_will_enter_fullscreen` was triggered and we're already + // in fullscreen, so we must've reached here by `set_fullscreen` + // as it updates the state + Some(Fullscreen::Borderless(_)) => (), + // Otherwise, we must've reached fullscreen by the user clicking + // on the green fullscreen button. Update state! + None => { + shared_state.fullscreen = Some(Fullscreen::Borderless(window.current_monitor())) + } + } + trace!("Unlocked shared state in `window_will_enter_fullscreen`"); }) }); @@ -433,25 +450,6 @@ extern "C" fn window_will_use_fullscreen_presentation_options( extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidEnterFullscreen:`"); with_state(this, |state| { - state.with_window(|window| { - let monitor = window.current_monitor(); - trace!("Locked shared state in `window_did_enter_fullscreen`"); - let mut shared_state = window.shared_state.lock().unwrap(); - match shared_state.fullscreen { - // Exclusive mode sets the state in `set_fullscreen` as the user - // can't enter exclusive mode by other means (like the - // fullscreen button on the window decorations) - Some(Fullscreen::Exclusive(_)) => (), - // `window_did_enter_fullscreen` was triggered and we're already - // in fullscreen, so we must've reached here by `set_fullscreen` - // as it updates the state - Some(Fullscreen::Borderless(_)) => (), - // Otherwise, we must've reached fullscreen by the user clicking - // on the green fullscreen button. Update state! - None => shared_state.fullscreen = Some(Fullscreen::Borderless(monitor)), - } - trace!("Unlocked shared state in `window_did_enter_fullscreen`"); - }); state.initial_fullscreen = false; }); trace!("Completed `windowDidEnterFullscreen:`");