From c8dfc6b4757470bbb5b3678ee9a37bf8c9a74267 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 19 Jan 2023 07:43:01 -0800
Subject: [PATCH] Fixing window being incorrect size when using win+shift+arrow
to move new big picture mode between displays
*When changing the display of a window, if it's a fullscreen window, resize it to the size of the new display
CR: @saml
---
src/events/SDL_windowevents.c | 4 ++++
src/video/SDL_sysvideo.h | 1 +
src/video/SDL_video.c | 30 +++++++++++++++++++++++++++
src/video/windows/SDL_windowsevents.c | 12 +++++++++++
4 files changed, 47 insertions(+)
diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c
index 3d108ac6c388..f6bc8ece8154 100644
--- a/src/events/SDL_windowevents.c
+++ b/src/events/SDL_windowevents.c
@@ -175,6 +175,10 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
SDL_OnWindowFocusLost(window);
break;
+ case SDL_WINDOWEVENT_DISPLAY_CHANGED:
+ SDL_assert(data1 == window->display_index);
+ SDL_OnWindowDisplayChanged(window);
+ break;
default:
break;
}
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 525a84f5b58e..86329d9d312d 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -504,6 +504,7 @@ extern void SDL_OnWindowEnter(SDL_Window *window);
extern void SDL_OnWindowLeave(SDL_Window *window);
extern void SDL_OnWindowFocusGained(SDL_Window *window);
extern void SDL_OnWindowFocusLost(SDL_Window *window);
+extern void SDL_OnWindowDisplayChanged(SDL_Window *window);
extern void SDL_UpdateWindowGrab(SDL_Window *window);
extern SDL_Window *SDL_GetFocusWindow(void);
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 569c845fb43d..a0272cf71983 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -2919,6 +2919,36 @@ void SDL_OnWindowHidden(SDL_Window *window)
SDL_UpdateFullscreenMode(window, SDL_FALSE);
}
+void SDL_OnWindowDisplayChanged(SDL_Window *window)
+{
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ SDL_Rect rect;
+
+ if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+ window->last_fullscreen_flags = 0;
+ SDL_UpdateFullscreenMode(window, SDL_TRUE);
+ }
+
+ if (SDL_GetDisplayBounds(window->display_index, &rect) == 0) {
+ int old_w = window->w;
+ int old_h = window->h;
+ window->x = rect.x;
+ window->y = rect.y;
+ window->w = rect.w;
+ window->h = rect.h;
+ window->fullscreen_mode.w = rect.w;
+ window->fullscreen_mode.h = rect.h;
+ if (_this->SetWindowSize) {
+ _this->SetWindowSize(_this, window);
+ }
+
+ if (window->w != old_w || window->h != old_h) {
+ SDL_OnWindowResized(window);
+ }
+ }
+ }
+}
+
void SDL_OnWindowResized(SDL_Window *window)
{
int display_index = SDL_GetWindowDisplayIndex(window);
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index e3d1153372ac..5ea9fbc553cc 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -1266,6 +1266,18 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);
+ // Moving the window from one display to another can change the size of the window (in the handling of SDL_WINDOWEVENT_MOVED), so we need to re-query the bounds
+ if (GetClientRect(hwnd, &rect)) {
+ ClientToScreen(hwnd, (LPPOINT)&rect);
+ ClientToScreen(hwnd, (LPPOINT)&rect + 1);
+
+ WIN_UpdateClipCursor(data->window);
+
+ x = rect.left;
+ y = rect.top;
+ WIN_ScreenPointToSDL(&x, &y);
+ }
+
/* Convert client area width/height from pixels to dpi-scaled points */
w = rect.right - rect.left;
h = rect.bottom - rect.top;