SDL: video: Don't resize moved, fullscreen windows when mode switching is being emulated

From 5d5d39b19079d45498855f6d28fbdbaba00d53c0 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Thu, 19 Jan 2023 14:02:09 -0500
Subject: [PATCH] video: Don't resize moved, fullscreen windows when mode
 switching is being emulated

When a driver is emulating mode changes, the display bounds are always the native desktop size, not those of the video mode being emulated. This can result in incorrectly setting the size of fullscreen Wayland windows. Don't resize fullscreen windows to the display dimensions when mode switching is emulated.

Renames the quirk flag from VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING to VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED to better reflect its purpose.
---
 src/video/SDL_sysvideo.h             |  2 +-
 src/video/SDL_video.c                | 17 +++++++++++------
 src/video/wayland/SDL_waylandvideo.c |  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 86329d9d312d..f61d5d3bda95 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -143,7 +143,7 @@ struct SDL_SysWMinfo;
 /* Video device flags */
 typedef enum
 {
-    VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING = 0x01,
+    VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED = 0x01,
     VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE = 0x02,
 } DeviceQuirkFlags;
 
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index a0272cf71983..7f5947618633 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -160,9 +160,9 @@ extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, SDL_bool stat
 #endif
 
 /* Convenience functions for reading driver flags */
-static SDL_bool DisableDisplayModeSwitching(_THIS)
+static SDL_bool ModeSwitchingEmulated(_THIS)
 {
-    return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING);
+    return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED);
 }
 
 static SDL_bool DisableUnsetFullscreenOnMinimize(_THIS)
@@ -1019,8 +1019,8 @@ static int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, const SDL_Dis
     SDL_DisplayMode current_mode;
     int result;
 
-    /* Mode switching disabled via driver quirk flag, nothing to do and cannot fail. */
-    if (DisableDisplayModeSwitching(_this)) {
+    /* Mode switching set as emulated via driver quirk flag, nothing to do and cannot fail. */
+    if (ModeSwitchingEmulated(_this)) {
         return 0;
     }
 
@@ -2929,7 +2929,12 @@ void SDL_OnWindowDisplayChanged(SDL_Window *window)
             SDL_UpdateFullscreenMode(window, SDL_TRUE);
         }
 
-        if (SDL_GetDisplayBounds(window->display_index, &rect) == 0) {
+        /*
+         * If mode switching is being emulated, the display bounds don't necessarily reflect the
+         * emulated mode dimensions since the window is just being scaled.
+         */
+        if (!ModeSwitchingEmulated(_this) &&
+            SDL_GetDisplayBounds(window->display_index, &rect) == 0) {
             int old_w = window->w;
             int old_h = window->h;
             window->x = rect.x;
@@ -3050,7 +3055,7 @@ static SDL_bool SDL_ShouldMinimizeOnFocusLoss(SDL_Window *window)
     hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
     if (hint == NULL || !*hint || SDL_strcasecmp(hint, "auto") == 0) {
         if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ||
-            DisableDisplayModeSwitching(_this) == SDL_TRUE) {
+            ModeSwitchingEmulated(_this) == SDL_TRUE) {
             return SDL_FALSE;
         } else {
             return SDL_TRUE;
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 68b26bbb7ee2..85c12b1acaea 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -272,7 +272,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
 
     device->free = Wayland_DeleteDevice;
 
-    device->quirk_flags = VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING |
+    device->quirk_flags = VIDEO_DEVICE_QUIRK_MODE_SWITCHING_EMULATED |
                           VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE;
 
     return device;