From 6e28ba8927d71f9170e7d77bbe0b4af085d1e04c Mon Sep 17 00:00:00 2001 From: Johan Andersson Date: Sat, 26 Mar 2022 16:43:13 +0100 Subject: [PATCH] Fix fullscreen window messaging race on Windows (#2225) --- CHANGELOG.md | 19 +++++++-------- src/platform_impl/windows/window.rs | 36 ++++++++++++++++------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beca7e5a5d..65da9e8df1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ And please only add new entries to the top of this list, right below the `# Unre - The internal bindings to the [Windows API](https://docs.microsoft.com/en-us/windows/) were changed from the unofficial [winapi](https://github.com/retep998/winapi-rs) bindings to the official Microsoft [windows-sys](https://github.com/microsoft/windows-rs) bindings. - On Wayland, fix resize and scale factor changes not being propagated properly. - On Wayland, fix polling during consecutive `EventLoop::run_return` invocations. +- On Windows, fix race issue creating fullscreen windows with `WindowBuilder::with_fullscreen` # 0.26.1 (2022-01-05) @@ -251,13 +252,13 @@ And please only add new entries to the top of this list, right below the `# Unre - On X11, fix `ModifiersChanged` emitting incorrect modifier change events - **Breaking**: Overhaul how Winit handles DPI: - + Window functions and events now return `PhysicalSize` instead of `LogicalSize`. - + Functions that take `Size` or `Position` types can now take either `Logical` or `Physical` types. - + `hidpi_factor` has been renamed to `scale_factor`. - + `HiDpiFactorChanged` has been renamed to `ScaleFactorChanged`, and lets you control how the OS + - Window functions and events now return `PhysicalSize` instead of `LogicalSize`. + - Functions that take `Size` or `Position` types can now take either `Logical` or `Physical` types. + - `hidpi_factor` has been renamed to `scale_factor`. + - `HiDpiFactorChanged` has been renamed to `ScaleFactorChanged`, and lets you control how the OS resizes the window in response to the change. - + On X11, deprecate `WINIT_HIDPI_FACTOR` environment variable in favor of `WINIT_X11_SCALE_FACTOR`. - + `Size` and `Position` types are now generic over their exact pixel type. + - On X11, deprecate `WINIT_HIDPI_FACTOR` environment variable in favor of `WINIT_X11_SCALE_FACTOR`. + - `Size` and `Position` types are now generic over their exact pixel type. # 0.20.0 Alpha 6 (2020-01-03) @@ -362,7 +363,7 @@ And please only add new entries to the top of this list, right below the `# Unre - `Window::set_fullscreen` now takes `Option` where `Fullscreen` consists of `Fullscreen::Exclusive(VideoMode)` and `Fullscreen::Borderless(MonitorHandle)` variants. - - Adds support for exclusive fullscreen mode. + - Adds support for exclusive fullscreen mode. - On iOS, add support for hiding the home indicator. - On iOS, add support for deferring system gestures. - On iOS, fix a crash that occurred while acquiring a monitor's name. @@ -561,7 +562,7 @@ and `WindowEvent::HoveredFile`. # Version 0.16.1 (2018-07-02) - Added logging through `log`. Logging will become more extensive over time. -- On X11 and Windows, the window's DPI factor is guessed before creating the window. This *greatly* cuts back on unsightly auto-resizing that would occur immediately after window creation. +- On X11 and Windows, the window's DPI factor is guessed before creating the window. This _greatly_ cuts back on unsightly auto-resizing that would occur immediately after window creation. - Fixed X11 backend compilation for environments where `c_char` is unsigned. # Version 0.16.0 (2018-06-25) @@ -711,7 +712,7 @@ and `WindowEvent::HoveredFile`. # Version 0.10.1 (2018-02-05) -*Yanked* +_Yanked_ # Version 0.10.0 (2017-12-27) diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 91d9467eba..8e77d5f4d6 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -62,8 +62,7 @@ use crate::{ monitor::MonitorHandle as RootMonitorHandle, platform_impl::platform::{ dark_mode::try_theme, - definitions::ITaskbarList2, - definitions::{CLSID_TaskbarList, IID_ITaskbarList2}, + definitions::{CLSID_TaskbarList, IID_ITaskbarList2, ITaskbarList2}, dpi::{dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_dpi}, drop_handler::FileDropHandler, event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID}, @@ -486,6 +485,14 @@ impl Window { ); }); + // Mark as fullscreen window wrt to z-order + // + // this needs to be called before the below fullscreen SetWindowPos as this itself + // will generate WM_SIZE messages of the old window size that can race with what we set below + unsafe { + taskbar_mark_fullscreen(window.0, fullscreen.is_some()); + } + // Update window bounds match &fullscreen { Some(fullscreen) => { @@ -533,10 +540,6 @@ impl Window { } } } - - unsafe { - taskbar_mark_fullscreen(window.0, fullscreen.is_some()); - } }); } @@ -842,19 +845,20 @@ impl<'a, T: 'static> InitData<'a, T> { // attribute is correctly applied. win.set_visible(attributes.visible); - let dimensions = attributes - .inner_size - .unwrap_or_else(|| PhysicalSize::new(800, 600).into()); - win.set_inner_size(dimensions); - if attributes.maximized { - // Need to set MAXIMIZED after setting `inner_size` as - // `Window::set_inner_size` changes MAXIMIZED to false. - win.set_maximized(true); - } - if attributes.fullscreen.is_some() { win.set_fullscreen(attributes.fullscreen); force_window_active(win.window.0); + } else { + let dimensions = attributes + .inner_size + .unwrap_or_else(|| PhysicalSize::new(800, 600).into()); + win.set_inner_size(dimensions); + + if attributes.maximized { + // Need to set MAXIMIZED after setting `inner_size` as + // `Window::set_inner_size` changes MAXIMIZED to false. + win.set_maximized(true); + } } if let Some(position) = attributes.position {