mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
On Windows, fix window size for maximized, undecorated windows (#2584)
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
This commit is contained in:
parent
c984476687
commit
23b821285c
|
@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
|
||||
# Unreleased
|
||||
|
||||
- On Windows, fix window size for maximized, undecorated windows.
|
||||
- On Windows and macOS, add `WindowBuilder::with_active`.
|
||||
- Add `Window::is_minimized`.
|
||||
- On X11, fix errors handled during `register_xlib_error_hook` invocation bleeding into winit.
|
||||
|
|
|
@ -977,19 +977,31 @@ unsafe fn public_window_callback_inner<T: 'static>(
|
|||
return DefWindowProcW(window, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
// Extend the client area to cover the whole non-client area.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize#remarks
|
||||
//
|
||||
// HACK(msiglreith): To add the drop shadow we slightly tweak the non-client area.
|
||||
// This leads to a small black 1px border on the top. Adding a margin manually
|
||||
// on all 4 borders would result in the caption getting drawn by the DWM.
|
||||
//
|
||||
// Another option would be to allow the DWM to paint inside the client area.
|
||||
// Unfortunately this results in janky resize behavior, where the compositor is
|
||||
// ahead of the window surface. Currently, there seems no option to achieve this
|
||||
// with the Windows API.
|
||||
if window_flags.contains(WindowFlags::MARKER_UNDECORATED_SHADOW) {
|
||||
let params = &mut *(lparam as *mut NCCALCSIZE_PARAMS);
|
||||
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(¶ms.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.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize#remarks
|
||||
//
|
||||
// HACK(msiglreith): To add the drop shadow we slightly tweak the non-client area.
|
||||
// This leads to a small black 1px border on the top. Adding a margin manually
|
||||
// on all 4 borders would result in the caption getting drawn by the DWM.
|
||||
//
|
||||
// Another option would be to allow the DWM to paint inside the client area.
|
||||
// Unfortunately this results in janky resize behavior, where the compositor is
|
||||
// ahead of the window surface. Currently, there seems no option to achieve this
|
||||
// with the Windows API.
|
||||
params.rgrc[0].top += 1;
|
||||
params.rgrc[0].bottom += 1;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ use windows_sys::{
|
|||
HiDpi::{DPI_AWARENESS_CONTEXT, MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS},
|
||||
Input::KeyboardAndMouse::GetActiveWindow,
|
||||
WindowsAndMessaging::{
|
||||
ClipCursor, GetClientRect, GetClipCursor, GetSystemMetrics, GetWindowRect,
|
||||
IsIconic, ShowCursor, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_HELP,
|
||||
IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZEWE,
|
||||
IDC_WAIT, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN,
|
||||
SM_YVIRTUALSCREEN,
|
||||
ClipCursor, GetClientRect, GetClipCursor, GetSystemMetrics, GetWindowPlacement,
|
||||
GetWindowRect, IsIconic, ShowCursor, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS,
|
||||
IDC_HAND, IDC_HELP, IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS,
|
||||
IDC_SIZENWSE, IDC_SIZEWE, IDC_WAIT, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN,
|
||||
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) {
|
||||
static HIDDEN: AtomicBool = AtomicBool::new(false);
|
||||
let changed = HIDDEN.swap(hidden, Ordering::SeqCst) ^ hidden;
|
||||
|
|
Loading…
Reference in a new issue