1
1

Fix T88384: Improved Win32 Window Sizing and Positioning

When creating Win32 windows, the sizes and placements can be out by a
small amount, mostly noticeable near monitor edges. This is because
Windows 10 includes a thin invisible border (typically 7 pixels) when
determining position. Therefore the correct values can sometimes be
just outside the monitor bounds, but we clamp them at those bounds.

This patch fixes this by first clamping the requested values to monitor
bounds, adjusting for window chrome with AdjustWindowRectEx(), and then
using those adjusted values in CreateWindowExW().

see D11314 for more details.

Differential Revision: https://developer.blender.org/D11314

Reviewed by Ray Molenkamp
This commit is contained in:
2021-05-21 09:34:58 -07:00
parent 24deeee09e
commit 4fb052f08d

View File

@@ -121,22 +121,28 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
monitor.dwFlags = 0;
GetMonitorInfo(MonitorFromRect(&win_rect, MONITOR_DEFAULTTONEAREST), &monitor);
/* Adjust our requested size to allow for caption and borders and constrain to monitor. */
AdjustWindowRectEx(&win_rect, WS_CAPTION, FALSE, 0);
/* Constrain size to fit within this monitor. */
width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect.right - win_rect.left);
left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width);
height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect.bottom - win_rect.top);
top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height);
m_hWnd = ::CreateWindowExW(extended_style, // window extended style
s_windowClassName, // pointer to registered class name
title_16, // pointer to window name
style, // window style
left, // horizontal position of window
top, // vertical position of window
width, // window width
height, // window height
m_parentWindowHwnd, // handle to parent or owner window
win_rect.left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width);
win_rect.right = win_rect.left + width;
win_rect.top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height);
win_rect.bottom = win_rect.top + height;
/* Adjust our requested values to allow for caption, borders, shadows, etc.
Windows API Note: You cannot specify WS_OVERLAPPED when calling. */
AdjustWindowRectEx(&win_rect, style & ~WS_OVERLAPPED, FALSE, extended_style);
m_hWnd = ::CreateWindowExW(extended_style, // window extended style
s_windowClassName, // pointer to registered class name
title_16, // pointer to window name
style, // window style
win_rect.left, // horizontal position of window
win_rect.top, // vertical position of window
win_rect.right - win_rect.left, // window width
win_rect.bottom - win_rect.top, // window height
m_parentWindowHwnd, // handle to parent or owner window
0, // handle to menu or child-window identifier
::GetModuleHandle(0), // handle to application instance
0); // pointer to window-creation data