From 277fded7bac77417c94c1f58a33a0005ad02f5f1 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 12 Jan 2024 07:07:27 -0800
Subject: [PATCH] Refactor AdjustWindowRectEx() into
WIN_AdjustWindowRectForHWND()
Also include the window EXSTYLE to calls to AdjustWindowRectEx()
---
src/video/windows/SDL_windowsevents.c | 32 +++------------
src/video/windows/SDL_windowswindow.c | 59 +++++++++++++++++++++------
src/video/windows/SDL_windowswindow.h | 3 +-
3 files changed, 54 insertions(+), 40 deletions(-)
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index af5fbfbf204a..8a963cb85ca5 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 38a9055a3f4f..2a452d01b90e 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
+ 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
- WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, rect_type);
+
+#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 835ba622db60..8f6476c862e6 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