diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c index 62fca28b9f..2e194781af 100644 --- a/src/events/SDL_windowevents.c +++ b/src/events/SDL_windowevents.c @@ -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; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index c8cd3991cf..f1f7985bb2 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -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. diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index bfdb6e6d83..ca01c117a8 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -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;