mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-05 19:08:12 +00:00
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.
This commit is contained in:
@@ -99,6 +99,12 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
window->undefined_x = false;
|
||||
window->undefined_y = false;
|
||||
/* Clear the pending display if this move was not the result of an explicit request,
|
||||
* and the window is not scheduled to become fullscreen when shown.
|
||||
*/
|
||||
if (!window->last_position_pending && !(window->pending_flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
window->pending_displayID = 0;
|
||||
}
|
||||
window->last_position_pending = false;
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
window->windowed.x = data1;
|
||||
|
@@ -61,6 +61,7 @@ struct SDL_Window
|
||||
bool fullscreen_exclusive; // The window is currently fullscreen exclusive
|
||||
SDL_DisplayID last_fullscreen_exclusive_display; // The last fullscreen_exclusive display
|
||||
SDL_DisplayID last_displayID;
|
||||
SDL_DisplayID pending_displayID;
|
||||
|
||||
/* Stored position and size for the window in the non-fullscreen state,
|
||||
* including when the window is maximized or tiled.
|
||||
|
@@ -1726,6 +1726,9 @@ SDL_VideoDisplay *SDL_GetVideoDisplayForFullscreenWindow(SDL_Window *window)
|
||||
* window position, or an async window manager hasn't yet actually moved the window,
|
||||
* the current position won't be updated at the time of the fullscreen call.
|
||||
*/
|
||||
if (!displayID) {
|
||||
displayID = window->pending_displayID;
|
||||
}
|
||||
if (!displayID) {
|
||||
// Use the pending position and dimensions, if available, otherwise, use the current.
|
||||
const int x = window->last_position_pending ? window->pending.x : window->x;
|
||||
@@ -2364,6 +2367,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
|
||||
SDL_Window *parent = (SDL_Window *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, NULL);
|
||||
SDL_WindowFlags flags = SDL_GetWindowFlagProperties(props);
|
||||
SDL_WindowFlags type_flags, graphics_flags;
|
||||
SDL_DisplayID displayID = 0;
|
||||
bool undefined_x = false;
|
||||
bool undefined_y = false;
|
||||
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)
|
||||
|
||||
if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) ||
|
||||
SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
|
||||
SDL_DisplayID displayID = 0;
|
||||
SDL_Rect bounds;
|
||||
|
||||
if ((SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) && (x & 0xFFFF)) {
|
||||
@@ -2506,6 +2509,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
|
||||
window->floating.h = window->windowed.h = window->h = h;
|
||||
window->undefined_x = undefined_x;
|
||||
window->undefined_y = undefined_y;
|
||||
window->pending_displayID = displayID;
|
||||
|
||||
SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window);
|
||||
if (display) {
|
||||
@@ -2885,6 +2889,7 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
|
||||
const int h = window->last_size_pending ? window->pending.h : window->windowed.h;
|
||||
|
||||
original_displayID = SDL_GetDisplayForWindow(window);
|
||||
window->pending_displayID = 0;
|
||||
|
||||
if (SDL_WINDOWPOS_ISUNDEFINED(x)) {
|
||||
x = window->windowed.x;
|
||||
@@ -2905,6 +2910,8 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
|
||||
displayID = SDL_GetPrimaryDisplay();
|
||||
}
|
||||
|
||||
window->pending_displayID = displayID;
|
||||
|
||||
SDL_zero(bounds);
|
||||
if (!SDL_GetDisplayUsableBounds(displayID, &bounds) || w > bounds.w || h > bounds.h) {
|
||||
if (!SDL_GetDisplayBounds(displayID, &bounds)) {
|
||||
@@ -2917,6 +2924,21 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
|
||||
if (SDL_WINDOWPOS_ISCENTERED(y)) {
|
||||
y = bounds.y + (bounds.h - h) / 2;
|
||||
}
|
||||
} else {
|
||||
/* See if the requested window position matches the origin of any displays and set
|
||||
* the pending fullscreen display ID if it does. This needs to be set early in case
|
||||
* the window is prevented from moving to the exact origin due to struts.
|
||||
*/
|
||||
for (int i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_Rect rect;
|
||||
const SDL_DisplayID cur_id = _this->displays[i]->id;
|
||||
if (SDL_GetDisplayBounds(cur_id, &rect)) {
|
||||
if (x == rect.x && y == rect.y) {
|
||||
window->pending_displayID = cur_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window->pending.x = x;
|
||||
|
Reference in New Issue
Block a user