mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-24 22:09:54 +00:00
video: Windows keep any position set when in fullscreen after leaving fullscreen
Adds an automated test for the behavior as well.
This commit is contained in:
committed by
Sam Lantinga
parent
b608108593
commit
f31ca02723
@@ -3051,6 +3051,14 @@ bool SDL_SetWindowPosition(SDL_Window *window, int x, int y)
|
||||
|
||||
window->pending.x = x;
|
||||
window->pending.y = y;
|
||||
|
||||
/* Windows are placed at the coordinates received while in fullscreen after leaving fullscreen.
|
||||
* Asynchronous backends need special handling in this case.
|
||||
*/
|
||||
if (!_this->SyncWindow && (window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
window->floating.x = window->windowed.x = x;
|
||||
window->floating.y = window->windowed.y = y;
|
||||
}
|
||||
window->undefined_x = false;
|
||||
window->undefined_y = false;
|
||||
window->last_position_pending = true;
|
||||
|
||||
@@ -1461,7 +1461,6 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
|
||||
}
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_ENTER_FULLSCREEN, 0, 0);
|
||||
|
||||
_data.pending_position = NO;
|
||||
_data.pending_size = NO;
|
||||
|
||||
/* Force the size change event in case it was delivered earlier
|
||||
@@ -2605,7 +2604,7 @@ bool Cocoa_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
BOOL fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN) ? YES : NO;
|
||||
int x, y;
|
||||
|
||||
if ([windata.listener isInFullscreenSpaceTransition]) {
|
||||
if (fullscreen || [windata.listener isInFullscreenSpaceTransition]) {
|
||||
windata.pending_position = YES;
|
||||
return true;
|
||||
}
|
||||
@@ -3030,8 +3029,13 @@ SDL_FullscreenResult Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Windo
|
||||
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0);
|
||||
|
||||
rect.origin.x = data.was_zoomed ? window->windowed.x : window->floating.x;
|
||||
rect.origin.y = data.was_zoomed ? window->windowed.y : window->floating.y;
|
||||
if (data.pending_position) {
|
||||
rect.origin.x = window->pending.x;
|
||||
rect.origin.y = window->pending.y;
|
||||
} else {
|
||||
rect.origin.x = data.was_zoomed ? window->windowed.x : window->floating.x;
|
||||
rect.origin.y = data.was_zoomed ? window->windowed.y : window->floating.y;
|
||||
}
|
||||
rect.size.width = data.was_zoomed ? window->windowed.w : window->floating.w;
|
||||
rect.size.height = data.was_zoomed ? window->windowed.h : window->floating.h;
|
||||
|
||||
|
||||
@@ -1200,6 +1200,7 @@ bool X11_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
X11_UpdateWindowPosition(window, false);
|
||||
} else {
|
||||
window->internal->fs_repositioned = true;
|
||||
SDL_UpdateFullscreenMode(window, SDL_FULLSCREEN_OP_UPDATE, true);
|
||||
}
|
||||
return true;
|
||||
@@ -1921,6 +1922,8 @@ static SDL_FullscreenResult X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this,
|
||||
}
|
||||
} else {
|
||||
SDL_zero(data->requested_fullscreen_mode);
|
||||
data->pending_position = data->fs_repositioned;
|
||||
data->fs_repositioned = false;
|
||||
|
||||
/* Fullscreen windows sometimes end up being marked maximized by
|
||||
* window managers. Force it back to how we expect it to be.
|
||||
|
||||
@@ -111,6 +111,7 @@ struct SDL_WindowData
|
||||
|
||||
bool pending_size;
|
||||
bool pending_position;
|
||||
bool fs_repositioned;
|
||||
bool window_was_maximized;
|
||||
bool previous_borders_nonzero;
|
||||
bool toggle_borders;
|
||||
|
||||
@@ -843,6 +843,7 @@ static int SDLCALL video_getSetWindowPosition(void *arg)
|
||||
{
|
||||
const char *title = "video_getSetWindowPosition Test Window";
|
||||
SDL_Window *window;
|
||||
SDL_WindowFlags flags;
|
||||
int result;
|
||||
int maxxVariation, maxyVariation;
|
||||
int xVariation, yVariation;
|
||||
@@ -974,6 +975,95 @@ static int SDLCALL video_getSetWindowPosition(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
/* Fullscreen test */
|
||||
desiredX = 100;
|
||||
desiredY = 100;
|
||||
SDL_SetWindowPosition(window, desiredX, desiredY);
|
||||
SDLTest_AssertPass("Call to SDL_SetWindowPosition(...,%d,%d)", desiredX, desiredY);
|
||||
|
||||
result = SDL_SyncWindow(window);
|
||||
SDLTest_AssertPass("SDL_SyncWindow()");
|
||||
SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result);
|
||||
|
||||
/* Get position */
|
||||
currentX = desiredX + 1;
|
||||
currentY = desiredY + 1;
|
||||
SDL_GetWindowPosition(window, ¤tX, ¤tY);
|
||||
SDLTest_AssertPass("Call to SDL_GetWindowPosition()");
|
||||
|
||||
if (desiredX == currentX && desiredY == currentY) {
|
||||
SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX);
|
||||
SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY);
|
||||
} else {
|
||||
bool hasEvent;
|
||||
/* SDL_SetWindowPosition() and SDL_SetWindowSize() will make requests of the window manager and set the internal position and size,
|
||||
* and then we get events signaling what actually happened, and they get passed on to the application if they're not what we expect. */
|
||||
currentX = desiredX + 1;
|
||||
currentY = desiredY + 1;
|
||||
hasEvent = getPositionFromEvent(¤tX, ¤tY);
|
||||
SDLTest_AssertCheck(hasEvent == true, "Changing position was not honored by WM, checking present of SDL_EVENT_WINDOW_MOVED");
|
||||
if (hasEvent) {
|
||||
SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position is the position from SDL event; expected: %d, got: %d", desiredX, currentX);
|
||||
SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position is the position from SDL event; expected: %d, got: %d", desiredY, currentY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test setting position while fullscreen */
|
||||
result = SDL_SetWindowFullscreen(window, true);
|
||||
SDLTest_AssertPass("SDL_SetWindowFullscreen()");
|
||||
SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result);
|
||||
|
||||
result = SDL_SyncWindow(window);
|
||||
SDLTest_AssertPass("SDL_SyncWindow()");
|
||||
SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result);
|
||||
|
||||
/* Verify that window is in fullscreen */
|
||||
flags = SDL_GetWindowFlags(window);
|
||||
SDLTest_AssertPass("SDL_GetWindowFlags()");
|
||||
SDLTest_AssertCheck(flags & SDL_WINDOW_FULLSCREEN, "Verify the `SDL_WINDOW_FULLSCREEN` flag is set: %s", (flags & SDL_WINDOW_FULLSCREEN) ? "true" : "false");
|
||||
|
||||
/* Set the fullscreen window position */
|
||||
desiredX = desiredX + 10;
|
||||
desiredY = desiredY + 10;
|
||||
SDL_SetWindowPosition(window, desiredX, desiredY);
|
||||
SDLTest_AssertPass("Call to SDL_SetWindowPosition(...,%d,%d)", desiredX, desiredY);
|
||||
|
||||
result = SDL_SetWindowFullscreen(window, false);
|
||||
SDLTest_AssertPass("SDL_SetWindowFullscreen()");
|
||||
SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result);
|
||||
|
||||
result = SDL_SyncWindow(window);
|
||||
SDLTest_AssertPass("SDL_SyncWindow()");
|
||||
SDLTest_AssertCheck(result == true, "Verify return value; expected: true, got: %d", result);
|
||||
|
||||
/* Verify that window left fullscreen */
|
||||
flags = SDL_GetWindowFlags(window);
|
||||
SDLTest_AssertPass("SDL_GetWindowFlags()");
|
||||
SDLTest_AssertCheck(!(flags & SDL_WINDOW_FULLSCREEN), "Verify the `SDL_WINDOW_FULLSCREEN` flag is not set: %s", !(flags & SDL_WINDOW_FULLSCREEN) ? "true" : "false");
|
||||
|
||||
/* Get position */
|
||||
currentX = desiredX + 1;
|
||||
currentY = desiredY + 1;
|
||||
SDL_GetWindowPosition(window, ¤tX, ¤tY);
|
||||
SDLTest_AssertPass("Call to SDL_GetWindowPosition()");
|
||||
|
||||
if (desiredX == currentX && desiredY == currentY) {
|
||||
SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX);
|
||||
SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY);
|
||||
} else {
|
||||
bool hasEvent;
|
||||
/* SDL_SetWindowPosition() and SDL_SetWindowSize() will make requests of the window manager and set the internal position and size,
|
||||
* and then we get events signaling what actually happened, and they get passed on to the application if they're not what we expect. */
|
||||
currentX = desiredX + 1;
|
||||
currentY = desiredY + 1;
|
||||
hasEvent = getPositionFromEvent(¤tX, ¤tY);
|
||||
SDLTest_AssertCheck(hasEvent == true, "Changing position was not honored by WM, checking present of SDL_EVENT_WINDOW_MOVED");
|
||||
if (hasEvent) {
|
||||
SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position is the position from SDL event; expected: %d, got: %d", desiredX, currentX);
|
||||
SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position is the position from SDL event; expected: %d, got: %d", desiredY, currentY);
|
||||
}
|
||||
}
|
||||
|
||||
null_tests:
|
||||
|
||||
/* Dummy call with both pointers NULL */
|
||||
|
||||
Reference in New Issue
Block a user