On Windows, fix window size for maximized, undecorated windows (#2584)

Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
This commit is contained in:
Markus Siglreithmaier 2023-01-28 14:04:47 +01:00 committed by GitHub
parent c984476687
commit 23b821285c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 18 deletions

View file

@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre
# Unreleased # Unreleased
- On Windows, fix window size for maximized, undecorated windows.
- On Windows and macOS, add `WindowBuilder::with_active`. - On Windows and macOS, add `WindowBuilder::with_active`.
- Add `Window::is_minimized`. - Add `Window::is_minimized`.
- On X11, fix errors handled during `register_xlib_error_hook` invocation bleeding into winit. - On X11, fix errors handled during `register_xlib_error_hook` invocation bleeding into winit.

View file

@ -977,6 +977,20 @@ unsafe fn public_window_callback_inner<T: 'static>(
return DefWindowProcW(window, msg, wparam, lparam); return DefWindowProcW(window, msg, wparam, lparam);
} }
let params = &mut *(lparam as *mut NCCALCSIZE_PARAMS);
if util::is_maximized(window) {
// Limit the window size when maximized to the current monitor.
// Otherwise it would include the non-existent decorations.
//
// Use `MonitorFromRect` instead of `MonitorFromWindow` to select
// the correct monitor here.
// See https://github.com/MicrosoftEdge/WebView2Feedback/issues/2549
let monitor = MonitorFromRect(&params.rgrc[0], MONITOR_DEFAULTTONULL);
if let Ok(monitor_info) = monitor::get_monitor_info(monitor) {
params.rgrc[0] = monitor_info.monitorInfo.rcWork;
}
} else if window_flags.contains(WindowFlags::MARKER_UNDECORATED_SHADOW) {
// Extend the client area to cover the whole non-client area. // Extend the client area to cover the whole non-client area.
// https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize#remarks // https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize#remarks
// //
@ -988,8 +1002,6 @@ unsafe fn public_window_callback_inner<T: 'static>(
// Unfortunately this results in janky resize behavior, where the compositor is // Unfortunately this results in janky resize behavior, where the compositor is
// ahead of the window surface. Currently, there seems no option to achieve this // ahead of the window surface. Currently, there seems no option to achieve this
// with the Windows API. // with the Windows API.
if window_flags.contains(WindowFlags::MARKER_UNDECORATED_SHADOW) {
let params = &mut *(lparam as *mut NCCALCSIZE_PARAMS);
params.rgrc[0].top += 1; params.rgrc[0].top += 1;
params.rgrc[0].bottom += 1; params.rgrc[0].bottom += 1;
} }

View file

@ -23,11 +23,11 @@ use windows_sys::{
HiDpi::{DPI_AWARENESS_CONTEXT, MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS}, HiDpi::{DPI_AWARENESS_CONTEXT, MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS},
Input::KeyboardAndMouse::GetActiveWindow, Input::KeyboardAndMouse::GetActiveWindow,
WindowsAndMessaging::{ WindowsAndMessaging::{
ClipCursor, GetClientRect, GetClipCursor, GetSystemMetrics, GetWindowRect, ClipCursor, GetClientRect, GetClipCursor, GetSystemMetrics, GetWindowPlacement,
IsIconic, ShowCursor, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP, GetWindowRect, IsIconic, ShowCursor, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS,
IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZEWE, IDC_HAND, IDC_HELP, IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS,
IDC_WAIT, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, IDC_SIZENWSE, IDC_SIZEWE, IDC_WAIT, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN,
SM_YVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, SW_MAXIMIZE, WINDOWPLACEMENT,
}, },
}, },
}, },
@ -91,6 +91,15 @@ impl WindowArea {
} }
} }
pub fn is_maximized(window: HWND) -> bool {
unsafe {
let mut placement: WINDOWPLACEMENT = mem::zeroed();
placement.length = mem::size_of::<WINDOWPLACEMENT>() as u32;
GetWindowPlacement(window, &mut placement);
placement.showCmd == SW_MAXIMIZE
}
}
pub fn set_cursor_hidden(hidden: bool) { pub fn set_cursor_hidden(hidden: bool) {
static HIDDEN: AtomicBool = AtomicBool::new(false); static HIDDEN: AtomicBool = AtomicBool::new(false);
let changed = HIDDEN.swap(hidden, Ordering::SeqCst) ^ hidden; let changed = HIDDEN.swap(hidden, Ordering::SeqCst) ^ hidden;