Make maximized geometry handling less bugged on Windows

This commit is contained in:
Ilya Fedin 2022-06-18 12:03:19 +04:00 committed by John Preston
parent 0b87868b1d
commit 3043ec69ea

View file

@ -42,6 +42,10 @@ constexpr auto kDWMWA_TEXT_COLOR = DWORD(36);
UINT(__stdcall *GetDpiForWindow)(_In_ HWND hwnd); UINT(__stdcall *GetDpiForWindow)(_In_ HWND hwnd);
int(__stdcall *GetSystemMetricsForDpi)(
_In_ int nIndex,
_In_ UINT dpi);
[[nodiscard]] bool GetDpiForWindowSupported() { [[nodiscard]] bool GetDpiForWindowSupported() {
static const auto Result = [&] { static const auto Result = [&] {
#define LOAD_SYMBOL(lib, name) base::Platform::LoadMethod(lib, #name, name) #define LOAD_SYMBOL(lib, name) base::Platform::LoadMethod(lib, #name, name)
@ -52,6 +56,16 @@ UINT(__stdcall *GetDpiForWindow)(_In_ HWND hwnd);
return Result; return Result;
} }
[[nodiscard]] bool GetSystemMetricsForDpiSupported() {
static const auto Result = [&] {
#define LOAD_SYMBOL(lib, name) base::Platform::LoadMethod(lib, #name, name)
const auto user32 = base::Platform::SafeLoadLibrary(L"User32.dll");
return LOAD_SYMBOL(user32, GetSystemMetricsForDpi);
#undef LOAD_SYMBOL
}();
return Result;
}
[[nodiscard]] bool IsCompositionEnabled() { [[nodiscard]] bool IsCompositionEnabled() {
auto result = BOOL(FALSE); auto result = BOOL(FALSE);
const auto success = (DwmIsCompositionEnabled(&result) == S_OK); const auto success = (DwmIsCompositionEnabled(&result) == S_OK);
@ -426,7 +440,7 @@ bool WindowHelper::handleNativeEvent(
} return true; } return true;
case WM_NCCALCSIZE: { case WM_NCCALCSIZE: {
if (_title->isHidden() || !wParam) { if (_title->isHidden() || window()->isFullScreen() || !wParam) {
return false; return false;
} }
WINDOWPLACEMENT wp; WINDOWPLACEMENT wp;
@ -434,31 +448,37 @@ bool WindowHelper::handleNativeEvent(
if (GetWindowPlacement(_handle, &wp) if (GetWindowPlacement(_handle, &wp)
&& (wp.showCmd == SW_SHOWMAXIMIZED)) { && (wp.showCmd == SW_SHOWMAXIMIZED)) {
const auto r = &((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0]; const auto r = &((LPNCCALCSIZE_PARAMS)lParam)->rgrc[0];
const auto hMonitor = MonitorFromPoint( const auto dpi = _dpi.current();
{ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
const auto borderWidth = (GetSystemMetricsForDpiSupported() && dpi)
? GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+ GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)
: GetSystemMetrics(SM_CXSIZEFRAME)
+ GetSystemMetrics(SM_CXPADDEDBORDER);
r->left += borderWidth;
r->right -= borderWidth;
r->top += borderWidth;
r->bottom -= borderWidth;
const auto hMonitor = MonitorFromWindow(
_handle,
MONITOR_DEFAULTTONEAREST); MONITOR_DEFAULTTONEAREST);
if (hMonitor) { MONITORINFO mi;
MONITORINFO mi; mi.cbSize = sizeof(mi);
mi.cbSize = sizeof(mi); UINT uEdge = (UINT)-1;
if (GetMonitorInfo(hMonitor, &mi)) { if (GetMonitorInfo(hMonitor, &mi)
*r = mi.rcWork; && IsTaskbarAutoHidden(&mi.rcMonitor, &uEdge)) {
UINT uEdge = (UINT)-1; switch (uEdge) {
if (IsTaskbarAutoHidden(&mi.rcMonitor, &uEdge)) { case ABE_LEFT: r->left += 1; break;
switch (uEdge) { case ABE_RIGHT: r->right -= 1; break;
case ABE_LEFT: r->left += 1; break; case ABE_TOP: r->top += 1; break;
case ABE_RIGHT: r->right -= 1; break; case ABE_BOTTOM: r->bottom -= 1; break;
case ABE_TOP: r->top += 1; break;
case ABE_BOTTOM: r->bottom -= 1; break;
}
}
} }
} }
if (result) *result = 0; if (result) *result = 0;
} else { } else {
if (result) *result = WVR_REDRAW; if (result) *result = WVR_REDRAW;
} }
return true; } return true;
}
case WM_NCRBUTTONUP: { case WM_NCRBUTTONUP: {
if (_title->isHidden()) { if (_title->isHidden()) {