From db92674a9e0ee38344a6dcea71552a6be1f40d37 Mon Sep 17 00:00:00 2001 From: Mohit Sethi Date: Tue, 13 Dec 2022 14:57:46 +0530 Subject: [PATCH] Fix window clipping when maximized --- src/win32_window.c | 110 ++++++++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 37 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 3313a139..a2913d37 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -491,8 +491,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static RECT border_thickness = { 0, 0, 0, 0 }; - if (!_glfw.hints.window.titlebar) - SetRect(&border_thickness, 8, 8, 8, 8); + BOOL hasThickFrame = GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME; _GLFWwindow* window = GetPropW(hWnd, L"GLFW"); if (!window) @@ -550,8 +549,21 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (_glfw.hints.window.titlebar) break; - MARGINS margins = { 0 }; - DwmExtendFrameIntoClientArea(hWnd, &margins); + if (hasThickFrame) + { + RECT size_rect; + GetWindowRect(hWnd, &size_rect); + + // Inform the application of the frame change to force redrawing with the new + // client area that is extended into the title bar + SetWindowPos( + hWnd, NULL, + size_rect.left, size_rect.top, + size_rect.right - size_rect.left, size_rect.bottom - size_rect.top, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE + ); + break; + } break; } @@ -561,9 +573,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (_glfw.hints.window.titlebar) break; - MARGINS margins = { 0 }; - DwmExtendFrameIntoClientArea(hWnd, &margins); - + RECT title_bar_rect = {0}; + InvalidateRect(hWnd, &title_bar_rect, FALSE); break; } } @@ -995,16 +1006,28 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, break; } - case WM_NCCALCSIZE: - { - if (_glfw.hints.window.titlebar) - break; + case WM_NCCALCSIZE: + { + if (_glfw.hints.window.titlebar || !hasThickFrame || !wParam) + break; - if (lParam) - return 0; + UINT dpi = GetDpiForWindow(hWnd); + + int frame_x = GetSystemMetricsForDpi(SM_CXFRAME, dpi); + int frame_y = GetSystemMetricsForDpi(SM_CYFRAME, dpi); + int padding = GetSystemMetricsForDpi(92, dpi); + + NCCALCSIZE_PARAMS* params = (NCCALCSIZE_PARAMS*)lParam; + RECT* requested_client_rect = params->rgrc; + + requested_client_rect->right -= frame_x + padding; + requested_client_rect->left += frame_x + padding; + requested_client_rect->bottom -= frame_y + padding; + requested_client_rect->top += frame_y + (window->win32.maximized ? 1.0f : -1.0f) * padding; + + return 0; + } - break; - } case WM_SIZE: { const int width = LOWORD(lParam); @@ -1045,6 +1068,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, window->win32.iconified = iconified; window->win32.maximized = maximized; + + RECT size_rect; + GetWindowRect(hWnd, &size_rect); + + // Inform the application of the frame change to force redrawing with the new + // client area that is extended into the title bar + SetWindowPos( + hWnd, NULL, + size_rect.left, size_rect.top, + size_rect.right - size_rect.left, size_rect.bottom - size_rect.top, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE + ); return 0; } @@ -1253,10 +1288,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (_glfw.hints.window.titlebar) break; - // Extend the frame into the client area. - MARGINS margins = { 0 }; - DwmExtendFrameIntoClientArea(hWnd, &margins); - + RECT title_bar_rect = { 0 }; + InvalidateRect(hWnd, &title_bar_rect, FALSE); break; } case WM_NCHITTEST: @@ -1264,28 +1297,26 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (_glfw.hints.window.titlebar) break; - if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME) + if (hasThickFrame) { POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; ScreenToClient(hWnd, &pt); - RECT rc; - GetClientRect(hWnd, &rc); - - int titlebarHittest = 0; - _glfwInputTitleBarHitTest(window, pt.x, pt.y, &titlebarHittest); - - if (titlebarHittest) - { - return HTCAPTION; - } - else + + if (!window->win32.maximized) { + RECT rc; + GetClientRect(hWnd, &rc); + + UINT dpi = GetDpiForWindow(hWnd); + int frame_y = GetSystemMetricsForDpi(SM_CYFRAME, dpi); + int padding = GetSystemMetricsForDpi(92, dpi); + enum { left = 1, top = 2, right = 4, bottom = 8 }; int hit = 0; - if (pt.x < border_thickness.left) hit |= left; - if (pt.x > rc.right - border_thickness.right) hit |= right; - if (pt.y < border_thickness.top) hit |= top; - if (pt.y > rc.bottom - border_thickness.bottom) hit |= bottom; + if (pt.x < border_thickness.left) hit |= left; + if (pt.x > rc.right - border_thickness.right) hit |= right; + if (pt.y < border_thickness.top || pt.y < frame_y + padding) hit |= top; + if (pt.y > rc.bottom - border_thickness.bottom) hit |= bottom; if (hit & top && hit & left) return HTTOPLEFT; if (hit & top && hit & right) return HTTOPRIGHT; @@ -1295,9 +1326,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (hit & top) return HTTOP; if (hit & right) return HTRIGHT; if (hit & bottom) return HTBOTTOM; - - return HTCLIENT; } + + int titlebarHittest = 0; + _glfwInputTitleBarHitTest(window, pt.x, pt.y, &titlebarHittest); + if (titlebarHittest) + return HTCAPTION; + + return HTCLIENT; } } }