Skip to content

Commit 33c8998

Browse files
committed
video: Use additional checks for determining on which display a window should be fullscreen
Trying to determine where a window should be made fullscreen from the size and position can be unreliable if the window exceeds the display bounds. Add additional checks with the following priority: - If the window was positioned with a macro that explicitly passes a display ID, store and use the requested display as the explicit fullscreen target. - Check if the window position is an exact match for any display origins, and use that display if found, as positioning a fullscreen window by moving it to the origin of the destination display is common behavior. - Fall back to the existing center point check if the previous checks were not successful, as it is known behavior, and won't risk breaking existing clients that rely on it.
1 parent 561c99e commit 33c8998

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

src/events/SDL_windowevents.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
9999
case SDL_EVENT_WINDOW_MOVED:
100100
window->undefined_x = false;
101101
window->undefined_y = false;
102+
/* Clear the pending display if this move was not the result of an explicit request,
103+
* and the window is not scheduled to become fullscreen when shown.
104+
*/
105+
if (!window->last_position_pending && !(window->pending_flags & SDL_WINDOW_FULLSCREEN)) {
106+
window->pending_displayID = 0;
107+
}
102108
window->last_position_pending = false;
103109
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
104110
window->windowed.x = data1;

src/video/SDL_sysvideo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct SDL_Window
6161
bool fullscreen_exclusive; // The window is currently fullscreen exclusive
6262
SDL_DisplayID last_fullscreen_exclusive_display; // The last fullscreen_exclusive display
6363
SDL_DisplayID last_displayID;
64+
SDL_DisplayID pending_displayID;
6465

6566
/* Stored position and size for the window in the non-fullscreen state,
6667
* including when the window is maximized or tiled.

src/video/SDL_video.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,9 @@ SDL_VideoDisplay *SDL_GetVideoDisplayForFullscreenWindow(SDL_Window *window)
17261726
* window position, or an async window manager hasn't yet actually moved the window,
17271727
* the current position won't be updated at the time of the fullscreen call.
17281728
*/
1729+
if (!displayID) {
1730+
displayID = window->pending_displayID;
1731+
}
17291732
if (!displayID) {
17301733
// Use the pending position and dimensions, if available, otherwise, use the current.
17311734
const int x = window->last_position_pending ? window->pending.x : window->x;
@@ -2364,6 +2367,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
23642367
SDL_Window *parent = (SDL_Window *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, NULL);
23652368
SDL_WindowFlags flags = SDL_GetWindowFlagProperties(props);
23662369
SDL_WindowFlags type_flags, graphics_flags;
2370+
SDL_DisplayID displayID = 0;
23672371
bool undefined_x = false;
23682372
bool undefined_y = false;
23692373
bool external_graphics_context = SDL_GetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN, false);
@@ -2423,7 +2427,6 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
24232427

24242428
if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) ||
24252429
SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
2426-
SDL_DisplayID displayID = 0;
24272430
SDL_Rect bounds;
24282431

24292432
if ((SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) && (x & 0xFFFF)) {
@@ -2506,6 +2509,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
25062509
window->floating.h = window->windowed.h = window->h = h;
25072510
window->undefined_x = undefined_x;
25082511
window->undefined_y = undefined_y;
2512+
window->pending_displayID = displayID;
25092513

25102514
SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window);
25112515
if (display) {
@@ -2885,6 +2889,7 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
28852889
const int h = window->last_size_pending ? window->pending.h : window->windowed.h;
28862890

28872891
original_displayID = SDL_GetDisplayForWindow(window);
2892+
window->pending_displayID = 0;
28882893

28892894
if (SDL_WINDOWPOS_ISUNDEFINED(x)) {
28902895
x = window->windowed.x;
@@ -2905,6 +2910,8 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
29052910
displayID = SDL_GetPrimaryDisplay();
29062911
}
29072912

2913+
window->pending_displayID = displayID;
2914+
29082915
SDL_zero(bounds);
29092916
if (!SDL_GetDisplayUsableBounds(displayID, &bounds) || w > bounds.w || h > bounds.h) {
29102917
if (!SDL_GetDisplayBounds(displayID, &bounds)) {
@@ -2917,6 +2924,21 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
29172924
if (SDL_WINDOWPOS_ISCENTERED(y)) {
29182925
y = bounds.y + (bounds.h - h) / 2;
29192926
}
2927+
} else {
2928+
/* See if the requested window position matches the origin of any displays and set
2929+
* the pending fullscreen display ID if it does. This needs to be set early in case
2930+
* the window is prevented from moving to the exact origin due to struts.
2931+
*/
2932+
for (int i = 0; i < _this->num_displays; ++i) {
2933+
SDL_Rect rect;
2934+
const SDL_DisplayID cur_id = _this->displays[i]->id;
2935+
if (SDL_GetDisplayBounds(cur_id, &rect)) {
2936+
if (x == rect.x && y == rect.y) {
2937+
window->pending_displayID = cur_id;
2938+
break;
2939+
}
2940+
}
2941+
}
29202942
}
29212943

29222944
window->pending.x = x;

0 commit comments

Comments
 (0)