From 71cba66d086e19502d478f9205ed432f2baa03c1 Mon Sep 17 00:00:00 2001 From: amrbashir Date: Sun, 30 Jan 2022 18:54:04 +0200 Subject: [PATCH 1/2] fix(windows): revet maximized state handling to winit impl, closes #193 --- src/platform_impl/windows/event_loop.rs | 19 +++++++++++++++-- src/platform_impl/windows/util.rs | 14 ------------ src/platform_impl/windows/window.rs | 26 +++++++++++++++++------ src/platform_impl/windows/window_state.rs | 17 +++++++++++++++ 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 81ac50bbd..137dd551a 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -1094,6 +1094,18 @@ unsafe fn public_window_callback_inner( event: Resized(physical_size), }; + { + let mut w = subclass_input.window_state.lock(); + // See WindowFlags::MARKER_RETAIN_STATE_ON_SIZE docs for info on why this `if` check exists. + if !w + .window_flags() + .contains(WindowFlags::MARKER_RETAIN_STATE_ON_SIZE) + { + let maximized = wparam.0 == win32wm::SIZE_MAXIMIZED as _; + w.set_window_flags_in_place(|f| f.set(WindowFlags::MAXIMIZED, maximized)); + } + } + subclass_input.send_event(event); result = ProcResult::Value(LRESULT(0)); } @@ -1698,7 +1710,8 @@ unsafe fn public_window_callback_inner( return; } - window_state.fullscreen.is_none() && !util::is_maximized(window) + window_state.fullscreen.is_none() + && !window_state.window_flags().contains(WindowFlags::MAXIMIZED) }; let style = GetWindowLongW(window, GWL_STYLE) as WINDOW_STYLE; @@ -1771,7 +1784,9 @@ unsafe fn public_window_callback_inner( .contains(WindowFlags::MARKER_IN_SIZE_MOVE); // Unset maximized if we're changing the window's size. if new_physical_inner_size != old_physical_inner_size { - util::set_maximized(window, false); + WindowState::set_window_flags(window_state, window, |f| { + f.set(WindowFlags::MAXIMIZED, false) + }); } } diff --git a/src/platform_impl/windows/util.rs b/src/platform_impl/windows/util.rs index 29f8c4192..85fd23ea0 100644 --- a/src/platform_impl/windows/util.rs +++ b/src/platform_impl/windows/util.rs @@ -221,20 +221,6 @@ pub fn is_maximized(window: HWND) -> bool { placement.showCmd == SW_MAXIMIZE } -pub fn set_maximized(window: HWND, maximized: bool) { - unsafe { - if IsWindowVisible(window).as_bool() { - ShowWindow( - window, - match maximized { - true => SW_MAXIMIZE, - false => SW_RESTORE, - }, - ); - } - } -} - pub fn get_hicon_from_buffer(buffer: &[u8], width: i32, height: i32) -> Option { unsafe { match LookupIconIdFromDirectoryEx(buffer.as_ptr() as _, true, width, height, LR_DEFAULTCOLOR) diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 06ce1ccab..1c0b3c4e7 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -198,9 +198,12 @@ impl Window { pub fn set_outer_position(&self, position: Position) { let (x, y): (i32, i32) = position.to_physical::(self.scale_factor()).into(); + let window_state = Arc::clone(&self.window_state); let window = self.window.clone(); self.thread_executor.execute_in_thread(move || { - util::set_maximized(window.0, false); + WindowState::set_window_flags(window_state.lock(), window.0, |f| { + f.set(WindowFlags::MAXIMIZED, false) + }); }); unsafe { @@ -246,9 +249,12 @@ impl Window { let scale_factor = self.scale_factor(); let (width, height) = size.to_physical::(scale_factor).into(); + let window_state = Arc::clone(&self.window_state); let window = self.window.clone(); self.thread_executor.execute_in_thread(move || { - util::set_maximized(window.0, false); + WindowState::set_window_flags(window_state.lock(), window.0, |f| { + f.set(WindowFlags::MAXIMIZED, false) + }); }); util::set_inner_size_physical(self.window.0, width, height); @@ -406,12 +412,20 @@ impl Window { #[inline] pub fn set_maximized(&self, maximized: bool) { - util::set_maximized(self.window.0, maximized); + let window = self.window.clone(); + let window_state = Arc::clone(&self.window_state); + + self.thread_executor.execute_in_thread(move || { + WindowState::set_window_flags(window_state.lock(), window.0, |f| { + f.set(WindowFlags::MAXIMIZED, maximized) + }); + }); } #[inline] pub fn is_maximized(&self) -> bool { - util::is_maximized(self.window.0) + let window_state = self.window_state.lock(); + window_state.window_flags.contains(WindowFlags::MAXIMIZED) } #[inline] @@ -996,8 +1010,8 @@ unsafe extern "system" fn window_proc( win32wm::WM_NCCALCSIZE => { let userdata = util::GetWindowLongPtrW(window, GWL_USERDATA); if userdata != 0 { - let window_flags = WindowFlags::from_bits_unchecked(userdata as _); - if !window_flags.contains(WindowFlags::DECORATIONS) { + let win_flags = WindowFlags::from_bits_unchecked(userdata as _); + if !win_flags.contains(WindowFlags::DECORATIONS) { // adjust the maximized borderless window so it doesn't cover the taskbar if util::is_maximized(window) { let monitor = monitor::current_monitor(window); diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 25876e96d..fdc6f8cee 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -92,6 +92,7 @@ bitflags! { const MINIMIZED = 1 << 12; const EXCLUSIVE_FULLSCREEN_OR_MASK = WindowFlags::ALWAYS_ON_TOP.bits; + const INVISIBLE_AND_MASK = !WindowFlags::MAXIMIZED.bits; } } @@ -184,6 +185,10 @@ impl WindowFlags { self |= WindowFlags::EXCLUSIVE_FULLSCREEN_OR_MASK; } + if !self.contains(WindowFlags::VISIBLE) { + self &= WindowFlags::INVISIBLE_AND_MASK; + } + self } @@ -284,6 +289,18 @@ impl WindowFlags { } } + if diff.contains(WindowFlags::MAXIMIZED) || new.contains(WindowFlags::MAXIMIZED) { + unsafe { + ShowWindow( + window, + match new.contains(WindowFlags::MAXIMIZED) { + true => SW_MAXIMIZE, + false => SW_RESTORE, + }, + ); + } + } + if diff != WindowFlags::empty() { let (style, style_ex) = new.to_window_styles(); From ff7a6d5858b673776a8c0eaa0664baabbe039b8f Mon Sep 17 00:00:00 2001 From: amrbashir Date: Sun, 30 Jan 2022 18:58:36 +0200 Subject: [PATCH 2/2] add chanefile [skip ci] --- .changes/windows-fix-maximized-state.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/windows-fix-maximized-state.md diff --git a/.changes/windows-fix-maximized-state.md b/.changes/windows-fix-maximized-state.md new file mode 100644 index 000000000..7b795c51f --- /dev/null +++ b/.changes/windows-fix-maximized-state.md @@ -0,0 +1,5 @@ +--- +"tao": "patch" +--- + +Fix using `WindowBuilder::with_visible` and `WindowBuilder::with_maximized` not behaving correctly.