diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index af5fbfbf20..8a963cb85c 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1041,27 +1041,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) { - LONG style = GetWindowLong(hwnd, GWL_STYLE); - /* DJM - according to the docs for GetMenu(), the - return value is undefined if hwnd is a child window. - Apparently it's too difficult for MS to check - inside their function, so I have to do it here. - */ - BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); - UINT dpi; - - dpi = USER_DEFAULT_SCREEN_DPI; size.top = 0; size.left = 0; size.bottom = h; size.right = w; - - if (WIN_IsPerMonitorV2DPIAware(SDL_GetVideoDevice())) { - dpi = data->videodata->GetDpiForWindow(hwnd); - data->videodata->AdjustWindowRectExForDpi(&size, style, menu, 0, dpi); - } else { - AdjustWindowRectEx(&size, style, menu, 0); - } + WIN_AdjustWindowRectForHWND(hwnd, &size); w = size.right - size.left; h = size.bottom - size.top; #ifdef HIGHDPI_DEBUG @@ -1510,6 +1494,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) int query_client_w_win, query_client_h_win; const DWORD style = GetWindowLong(hwnd, GWL_STYLE); + const DWORD styleEx = GetWindowLong(hwnd, GWL_EXSTYLE); const BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); #ifdef HIGHDPI_DEBUG @@ -1522,7 +1507,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) RECT rect = { 0 }; if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) { - data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, prevDPI); + data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, styleEx, prevDPI); } frame_w = -rect.left + rect.right; @@ -1539,7 +1524,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) rect.bottom = query_client_h_win; if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) { - data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, nextDPI); + data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, styleEx, nextDPI); } /* This is supposed to control the suggested rect param of WM_DPICHANGED */ @@ -1580,19 +1565,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { /* Calculate the new frame w/h such that the client area size is maintained. */ - const DWORD style = GetWindowLong(hwnd, GWL_STYLE); - const BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); - RECT rect = { 0 }; rect.right = data->window->w; rect.bottom = data->window->h; if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) { - if (data->videodata->GetDpiForWindow && data->videodata->AdjustWindowRectExForDpi) { - data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, newDPI); - } else { - AdjustWindowRectEx(&rect, style, menu, 0); - } + WIN_AdjustWindowRectForHWND(hwnd, &rect); } w = rect.right - rect.left; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 38a9055a3f..2a452d01b9 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -154,7 +154,7 @@ static DWORD GetWindowStyleEx(SDL_Window *window) * Returns arguments to pass to SetWindowPos - the window rect, including frame, in Windows coordinates. * Can be called before we have a HWND. */ -static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type) +static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, DWORD styleEx, BOOL menu, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type) { SDL_VideoData *videodata = SDL_GetVideoDevice() ? SDL_GetVideoDevice()->driverdata : NULL; RECT rect; @@ -162,17 +162,17 @@ static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL m /* Client rect, in points */ switch (rect_type) { case SDL_WINDOWRECT_CURRENT: - SDL_RelativeToGlobalForWindow(window,window->x, window->y, x, y); + SDL_RelativeToGlobalForWindow(window, window->x, window->y, x, y); *width = window->w; *height = window->h; break; case SDL_WINDOWRECT_WINDOWED: - SDL_RelativeToGlobalForWindow(window,window->windowed.x, window->windowed.y, x, y); + SDL_RelativeToGlobalForWindow(window, window->windowed.x, window->windowed.y, x, y); *width = window->windowed.w; *height = window->windowed.h; break; case SDL_WINDOWRECT_FLOATING: - SDL_RelativeToGlobalForWindow(window,window->floating.x, window->floating.y, x, y); + SDL_RelativeToGlobalForWindow(window, window->floating.x, window->floating.y, x, y); *width = window->floating.w; *height = window->floating.h; break; @@ -202,12 +202,12 @@ static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL m UINT frame_dpi; SDL_WindowData *data = window->driverdata; frame_dpi = (data && videodata->GetDpiForWindow) ? videodata->GetDpiForWindow(data->hwnd) : USER_DEFAULT_SCREEN_DPI; - if (videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, frame_dpi) == 0) { + if (videodata->AdjustWindowRectExForDpi(&rect, style, menu, styleEx, frame_dpi) == 0) { return WIN_SetError("AdjustWindowRectExForDpi()"); } } } else { - if (AdjustWindowRectEx(&rect, style, menu, 0) == 0) { + if (AdjustWindowRectEx(&rect, style, menu, styleEx) == 0) { return WIN_SetError("AdjustWindowRectEx()"); } } @@ -231,20 +231,54 @@ static int WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL m return 0; } -void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type) +int WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type) { SDL_WindowData *data = window->driverdata; HWND hwnd = data->hwnd; - DWORD style; + DWORD style, styleEx; BOOL menu; style = GetWindowLong(hwnd, GWL_STYLE); + styleEx = GetWindowLong(hwnd, GWL_EXSTYLE); #if defined(__XBOXONE__) || defined(__XBOXSERIES__) menu = FALSE; #else menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); #endif - WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, rect_type); + return WIN_AdjustWindowRectWithStyle(window, style, styleEx, menu, x, y, width, height, rect_type); +} + +int WIN_AdjustWindowRectForHWND(HWND hwnd, LPRECT lpRect) +{ + SDL_VideoDevice *videodevice = SDL_GetVideoDevice(); + SDL_VideoData *videodata = videodevice ? videodevice->driverdata : NULL; + DWORD style, styleEx; + BOOL menu; + + style = GetWindowLong(hwnd, GWL_STYLE); + styleEx = GetWindowLong(hwnd, GWL_EXSTYLE); +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + menu = FALSE; +#else + menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); +#endif + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + AdjustWindowRectEx(&rect, style, menu, styleEx); +#else + if (WIN_IsPerMonitorV2DPIAware(videodevice)) { + /* With per-monitor v2, the window border/titlebar size depend on the DPI, so we need to call AdjustWindowRectExForDpi instead of AdjustWindowRectEx. */ + UINT frame_dpi = videodata->GetDpiForWindow ? videodata->GetDpiForWindow(hwnd) : USER_DEFAULT_SCREEN_DPI; + if (!videodata->AdjustWindowRectExForDpi(lpRect, style, menu, styleEx, frame_dpi)) { + return WIN_SetError("AdjustWindowRectExForDpi()"); + } + } else { + if (!AdjustWindowRectEx(lpRect, style, menu, styleEx)) { + return WIN_SetError("AdjustWindowRectEx()"); + } + } +#endif + return 0; } int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type) @@ -603,7 +637,7 @@ int WIN_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI /* Figure out what the window area will be */ WIN_ConstrainPopup(window); - WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_WINDOWRECT_FLOATING); + WIN_AdjustWindowRectWithStyle(window, style, styleEx, FALSE, &x, &y, &w, &h, SDL_WINDOWRECT_FLOATING); hwnd = CreateWindowEx(styleEx, SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL, SDL_Instance, NULL); @@ -1073,7 +1107,7 @@ int WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vide SDL_WindowData *data = window->driverdata; HWND hwnd = data->hwnd; MONITORINFO minfo; - DWORD style; + DWORD style, styleEx; HWND top; int x, y; int w, h; @@ -1108,6 +1142,7 @@ int WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vide style = GetWindowLong(hwnd, GWL_STYLE); style &= ~STYLE_MASK; style |= GetWindowStyle(window); + styleEx = GetWindowLong(hwnd, GWL_EXSTYLE); if (fullscreen) { x = minfo.rcMonitor.left; @@ -1136,7 +1171,7 @@ int WIN_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vide } menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); - WIN_AdjustWindowRectWithStyle(window, style, menu, + WIN_AdjustWindowRectWithStyle(window, style, styleEx, menu, &x, &y, &w, &h, data->windowed_mode_was_maximized ? SDL_WINDOWRECT_WINDOWED : SDL_WINDOWRECT_FLOATING); diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index 835ba622db..8f6476c862 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -119,7 +119,8 @@ extern void WIN_UpdateDarkModeForHWND(HWND hwnd); extern int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type); extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y); extern int WIN_SetWindowFocusable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool focusable); -extern void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type); +extern int WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_WindowRect rect_type); +extern int WIN_AdjustWindowRectForHWND(HWND hwnd, LPRECT lpRect); /* Ends C function definitions when using C++ */ #ifdef __cplusplus