x11: Improve sync algorithm
Track and check move and resize requests separately, and consider them done if either the window is already at the expected location, or at least one configure event which moved or resized the window was processed. The avoids a timeout condition if resizing the window caused it to be implicitly moved in order to keep it within desktop bounds. The automated positioning test now runs on GNOME/X11 without any sync requests timing out.main
parent
7e5511d3cd
commit
63ae84e140
|
@ -1330,6 +1330,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|||
int x = xevent->xconfigure.x;
|
||||
int y = xevent->xconfigure.y;
|
||||
|
||||
data->pending_operation &= ~X11_PENDING_OP_MOVE;
|
||||
SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y);
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y);
|
||||
|
||||
|
@ -1349,6 +1350,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|||
if (xevent->xconfigure.width != data->last_xconfigure.width ||
|
||||
xevent->xconfigure.height != data->last_xconfigure.height) {
|
||||
if (!data->skip_size_count) {
|
||||
data->pending_operation &= ~X11_PENDING_OP_RESIZE;
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED,
|
||||
xevent->xconfigure.width,
|
||||
xevent->xconfigure.height);
|
||||
|
@ -1675,6 +1677,11 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|||
|
||||
/* Restore the last known floating state if leaving maximized mode */
|
||||
if (!(flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
data->pending_operation |= X11_PENDING_OP_MOVE | X11_PENDING_OP_RESIZE;
|
||||
data->expected.x = data->window->floating.x;
|
||||
data->expected.y = data->window->floating.y;
|
||||
data->expected.w = data->window->floating.w;
|
||||
data->expected.h = data->window->floating.h;
|
||||
X11_XMoveWindow(display, data->xwindow, data->window->floating.x, data->window->floating.y);
|
||||
X11_XResizeWindow(display, data->xwindow, data->window->floating.w, data->window->floating.h);
|
||||
}
|
||||
|
@ -1696,8 +1703,14 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|||
if (data->border_top != 0 || data->border_left != 0 || data->border_right != 0 || data->border_bottom != 0) {
|
||||
/* Adjust if the window size changed to accommodate the borders. */
|
||||
if (data->window->flags & SDL_WINDOW_MAXIMIZED) {
|
||||
data->pending_operation |= X11_PENDING_OP_RESIZE;
|
||||
data->expected.w = data->window->windowed.w;
|
||||
data->expected.h = data->window->windowed.h;
|
||||
X11_XResizeWindow(display, data->xwindow, data->window->windowed.w, data->window->windowed.h);
|
||||
} else {
|
||||
data->pending_operation |= X11_PENDING_OP_RESIZE;
|
||||
data->expected.w = data->window->floating.w;
|
||||
data->expected.h = data->window->floating.h;
|
||||
X11_XResizeWindow(display, data->xwindow, data->window->floating.w, data->window->floating.h);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -614,12 +614,12 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
|
|||
window->floating.x, window->floating.y,
|
||||
&win_x, &win_y);
|
||||
|
||||
/* Always create this with the window->windowed.* fields; if we're
|
||||
creating a windowed mode window, that's fine. If we're creating a
|
||||
fullscreen window, the window manager will want to know these values
|
||||
so it can use them if we go _back_ to windowed mode. SDL manages
|
||||
migration to fullscreen after CreateSDLWindow returns, which will
|
||||
put all the SDL_Window fields and system state as expected. */
|
||||
/* Always create this with the window->floating.* fields; if we're creating a windowed mode window,
|
||||
* that's fine. If we're creating a maximized or fullscreen window, the window manager will want to
|
||||
* know these values so it can use them if we go _back_ to the base floating windowed mode. SDL manages
|
||||
* migration to fullscreen after CreateSDLWindow returns, which will put all the SDL_Window fields and
|
||||
* system state as expected.
|
||||
*/
|
||||
w = X11_XCreateWindow(display, RootWindow(display, screen),
|
||||
win_x, win_y, window->floating.w, window->floating.h,
|
||||
0, depth, InputOutput, visual,
|
||||
|
@ -868,9 +868,9 @@ static int X11_SyncWindowTimeout(SDL_VideoDevice *_this, SDL_Window *window, int
|
|||
X11_XSync(display, False);
|
||||
X11_PumpEvents(_this);
|
||||
|
||||
if (window->x == data->expected.x && window->y == data->expected.y &&
|
||||
window->w == data->expected.w && window->h == data->expected.h &&
|
||||
data->pending_operation == X11_PENDING_OP_NONE) {
|
||||
if ((!(data->pending_operation & X11_PENDING_OP_MOVE) || (window->x == data->expected.x && window->y == data->expected.y)) &&
|
||||
(!(data->pending_operation & X11_PENDING_OP_RESIZE) || (window->w == data->expected.w && window->h == data->expected.h)) &&
|
||||
(data->pending_operation & ~(X11_PENDING_OP_MOVE | X11_PENDING_OP_RESIZE)) == X11_PENDING_OP_NONE) {
|
||||
/* The window is where it is wanted and nothing is pending. Done. */
|
||||
break;
|
||||
}
|
||||
|
@ -882,8 +882,6 @@ static int X11_SyncWindowTimeout(SDL_VideoDevice *_this, SDL_Window *window, int
|
|||
data->expected.w = window->w;
|
||||
data->expected.h = window->h;
|
||||
|
||||
data->pending_operation = X11_PENDING_OP_NONE;
|
||||
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -891,6 +889,8 @@ static int X11_SyncWindowTimeout(SDL_VideoDevice *_this, SDL_Window *window, int
|
|||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
data->pending_operation = X11_PENDING_OP_NONE;
|
||||
|
||||
if (!caught_x11_error) {
|
||||
X11_PumpEvents(_this);
|
||||
} else {
|
||||
|
@ -973,6 +973,7 @@ void X11_UpdateWindowPosition(SDL_Window *window, SDL_bool use_current_position)
|
|||
&data->expected.x, &data->expected.y);
|
||||
|
||||
/* Attempt to move the window */
|
||||
data->pending_operation |= X11_PENDING_OP_MOVE;
|
||||
X11_XMoveWindow(display, data->xwindow, data->expected.x, data->expected.y);
|
||||
}
|
||||
|
||||
|
@ -1116,6 +1117,7 @@ void X11_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
|
|||
} else {
|
||||
data->expected.w = window->floating.w;
|
||||
data->expected.h = window->floating.h;
|
||||
data->pending_operation |= X11_PENDING_OP_RESIZE;
|
||||
X11_XResizeWindow(display, data->xwindow, data->expected.w, data->expected.h);
|
||||
}
|
||||
}
|
||||
|
@ -1598,10 +1600,12 @@ static int X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, SDL_Window *wind
|
|||
|
||||
data->expected.w = window->floating.w;
|
||||
data->expected.h = window->floating.h;
|
||||
data->pending_operation |= X11_PENDING_OP_MOVE;
|
||||
X11_XMoveWindow(display, data->xwindow, data->expected.x, data->expected.y);
|
||||
|
||||
/* If the window is bordered, the size will be set when the borders turn themselves back on. */
|
||||
if (window->flags & SDL_WINDOW_BORDERLESS) {
|
||||
data->pending_operation |= X11_PENDING_OP_RESIZE;
|
||||
X11_XResizeWindow(display, data->xwindow, data->expected.w, data->expected.h);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,9 @@ struct SDL_WindowData
|
|||
X11_PENDING_OP_RESTORE = 0x01,
|
||||
X11_PENDING_OP_MINIMIZE = 0x02,
|
||||
X11_PENDING_OP_MAXIMIZE = 0x04,
|
||||
X11_PENDING_OP_FULLSCREEN = 0x08
|
||||
X11_PENDING_OP_FULLSCREEN = 0x08,
|
||||
X11_PENDING_OP_MOVE = 0x10,
|
||||
X11_PENDING_OP_RESIZE = 0x20
|
||||
} pending_operation;
|
||||
|
||||
SDL_bool initial_border_adjustment;
|
||||
|
|
|
@ -1134,10 +1134,9 @@ static int video_getSetWindowSize(void *arg)
|
|||
SDL_SetWindowSize(window, desiredW, desiredH);
|
||||
SDLTest_AssertPass("Call to SDL_SetWindowSize(...,%d,%d)", desiredW, desiredH);
|
||||
|
||||
/* The sync may time out if changing the size changes the window position. */
|
||||
result = SDL_SyncWindow(window);
|
||||
SDLTest_AssertPass("SDL_SyncWindow()");
|
||||
SDLTest_AssertCheck(result >= 0, "Verify return value; expected: >=0, got: %d", result);
|
||||
SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result);
|
||||
|
||||
/* Get size */
|
||||
currentW = desiredW + 1;
|
||||
|
|
Loading…
Reference in New Issue