From 3bfd59660833ee09344b9408aaaa082d509ca54a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 24 Feb 2023 17:06:47 -0800
Subject: [PATCH] Added handling for undefined window position on Windows
---
src/video/SDL_sysvideo.h | 1 +
src/video/SDL_video.c | 24 +++++++++++---
src/video/windows/SDL_windowsvideo.c | 2 ++
src/video/windows/SDL_windowswindow.c | 47 +++++++++++++++++++++++++--
4 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 1a6e4c5ba0cc..ddf0e62ab201 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -153,6 +153,7 @@ typedef enum
{
VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED = 0x01,
VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE = 0x02,
+ VIDEO_DEVICE_QUIRK_HANDLES_UNDEFINED_WINDOW_POSITION = 0x04,
} DeviceQuirkFlags;
struct SDL_VideoDevice
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 431adfde83e7..82e51b00f579 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -154,12 +154,26 @@ extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, SDL_bool stat
/* Convenience functions for reading driver flags */
static SDL_bool ModeSwitchingEmulated(_THIS)
{
- return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED);
+ if (_this->quirk_flags & VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED) {
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
}
static SDL_bool DisableUnsetFullscreenOnMinimize(_THIS)
{
- return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE);
+ if (_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE) {
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
+}
+
+static SDL_bool HandlesUndefinedWindowPosition(_THIS)
+{
+ if (_this->quirk_flags & VIDEO_DEVICE_QUIRK_HANDLES_UNDEFINED_WINDOW_POSITION) {
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
}
/* Support for framebuffer emulation using an accelerated renderer */
@@ -1672,10 +1686,12 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint
SDL_zero(bounds);
SDL_GetDisplayBounds(displayID, &bounds);
- if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) {
+ if (SDL_WINDOWPOS_ISCENTERED(x) ||
+ (SDL_WINDOWPOS_ISUNDEFINED(x) && !HandlesUndefinedWindowPosition(_this))) {
x = bounds.x + (bounds.w - w) / 2;
}
- if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) {
+ if (SDL_WINDOWPOS_ISCENTERED(y) ||
+ (SDL_WINDOWPOS_ISUNDEFINED(y) && !HandlesUndefinedWindowPosition(_this))) {
y = bounds.y + (bounds.h - h) / 2;
}
}
diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c
index 9cb30d820b8f..cd297cb2ddd1 100644
--- a/src/video/windows/SDL_windowsvideo.c
+++ b/src/video/windows/SDL_windowsvideo.c
@@ -260,6 +260,8 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->free = WIN_DeleteDevice;
+ device->quirk_flags = VIDEO_DEVICE_QUIRK_HANDLES_UNDEFINED_WINDOW_POSITION;
+
return device;
}
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index 06e125cc0964..9c45da382760 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -490,6 +490,7 @@ int WIN_CreateWindow(_THIS, SDL_Window *window)
DWORD style = STYLE_BASIC;
int x, y;
int w, h;
+ SDL_bool undefined_position = SDL_FALSE;
if (window->flags & SDL_WINDOW_SKIP_TASKBAR) {
parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL);
@@ -497,12 +498,46 @@ int WIN_CreateWindow(_THIS, SDL_Window *window)
style |= GetWindowStyle(window);
+ /* Make sure we have valid coordinates for the AdjustWindowRect call below */
+ x = window->x;
+ y = window->y;
+ if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y)) {
+ SDL_DisplayID displayID = 0;
+ SDL_Rect bounds;
+
+ if (SDL_WINDOWPOS_ISUNDEFINED(x) && (x & 0xFFFF)) {
+ displayID = (x & 0xFFFF);
+ } else if (SDL_WINDOWPOS_ISUNDEFINED(y) && (y & 0xFFFF)) {
+ displayID = (y & 0xFFFF);
+ }
+ if (displayID == 0 || SDL_GetDisplayIndex(displayID) < 0) {
+ displayID = SDL_GetPrimaryDisplay();
+ }
+
+ SDL_zero(bounds);
+ SDL_GetDisplayBounds(displayID, &bounds);
+ if (SDL_WINDOWPOS_ISUNDEFINED(x)) {
+ window->x = window->windowed.x = bounds.x + (bounds.w - window->w) / 2;
+ }
+ if (SDL_WINDOWPOS_ISUNDEFINED(y)) {
+ window->y = window->windowed.y = bounds.y + (bounds.h - window->h) / 2;
+ }
+ if (displayID == SDL_GetPrimaryDisplay() &&
+ SDL_WINDOWPOS_ISUNDEFINED(x) && SDL_WINDOWPOS_ISUNDEFINED(y)) {
+ /* We can use CW_USEDEFAULT for the position */
+ undefined_position = SDL_TRUE;
+ }
+ }
+
/* Figure out what the window area will be */
WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE);
- hwnd =
- CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL,
- SDL_Instance, NULL);
+ if (undefined_position) {
+ x = CW_USEDEFAULT;
+ y = CW_USEDEFAULT; /* Not actually used */
+ }
+
+ hwnd = CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL, SDL_Instance, NULL);
if (!hwnd) {
return WIN_SetError("Couldn't create window");
}
@@ -517,6 +552,12 @@ int WIN_CreateWindow(_THIS, SDL_Window *window)
return -1;
}
+ if (undefined_position) {
+ /* Record where the window ended up */
+ window->windowed.x = window->x;
+ window->windowed.y = window->y;
+ }
+
/* Inform Windows of the frame change so we can respond to WM_NCCALCSIZE */
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);