|
@@ -1108,6 +1108,41 @@ void X11_GetBorderValues(SDL_WindowData *data)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void X11_EmitConfigureNotifyEvents(SDL_WindowData *data, XConfigureEvent *xevent)
|
|
|
+{
|
|
|
+ if (xevent->x != data->last_xconfigure.x ||
|
|
|
+ xevent->y != data->last_xconfigure.y) {
|
|
|
+ if (!data->size_move_event_flags) {
|
|
|
+ SDL_Window *w;
|
|
|
+ int x = xevent->x;
|
|
|
+ int y = xevent->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);
|
|
|
+
|
|
|
+ for (w = data->window->first_child; w; w = w->next_sibling) {
|
|
|
+ // Don't update hidden child popup windows, their relative position doesn't change
|
|
|
+ if (SDL_WINDOW_IS_POPUP(w) && !(w->flags & SDL_WINDOW_HIDDEN)) {
|
|
|
+ X11_UpdateWindowPosition(w, true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (xevent->width != data->last_xconfigure.width ||
|
|
|
+ xevent->height != data->last_xconfigure.height) {
|
|
|
+ if (!data->size_move_event_flags) {
|
|
|
+ data->pending_operation &= ~X11_PENDING_OP_RESIZE;
|
|
|
+ SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED,
|
|
|
+ xevent->width,
|
|
|
+ xevent->height);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_copyp(&data->last_xconfigure, xevent);
|
|
|
+}
|
|
|
+
|
|
|
static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|
|
{
|
|
|
SDL_VideoData *videodata = _this->internal;
|
|
@@ -1459,9 +1494,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|
|
xevent->xconfigure.x, xevent->xconfigure.y,
|
|
|
xevent->xconfigure.width, xevent->xconfigure.height);
|
|
|
#endif
|
|
|
- // Real configure notify events are relative to the parent, synthetic events are absolute.
|
|
|
- if (!xevent->xconfigure.send_event)
|
|
|
- {
|
|
|
+ // Real configure notify events are relative to the parent, synthetic events are absolute.
|
|
|
+ if (!xevent->xconfigure.send_event) {
|
|
|
unsigned int NumChildren;
|
|
|
Window ChildReturn, Root, Parent;
|
|
|
Window *Children;
|
|
@@ -1474,41 +1508,23 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|
|
&ChildReturn);
|
|
|
}
|
|
|
|
|
|
- if (xevent->xconfigure.x != data->last_xconfigure.x ||
|
|
|
- xevent->xconfigure.y != data->last_xconfigure.y) {
|
|
|
- if (!data->size_move_event_flags) {
|
|
|
- SDL_Window *w;
|
|
|
- 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);
|
|
|
+ /* Xfce sends ConfigureNotify before PropertyNotify when toggling fullscreen and maximized, which
|
|
|
+ * is backwards from every other window manager, as well as what is expected by SDL and its clients.
|
|
|
+ * Defer emitting the size/move events until the corresponding PropertyNotify arrives.
|
|
|
+ */
|
|
|
+ const Uint32 changed = X11_GetNetWMState(_this, data->window, xevent->xproperty.window) ^ data->window->flags;
|
|
|
+ if (changed & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED)) {
|
|
|
+ SDL_copyp(&data->pending_xconfigure, &xevent->xconfigure);
|
|
|
+ data->emit_size_move_after_property_notify = true;
|
|
|
+ }
|
|
|
|
|
|
- for (w = data->window->first_child; w; w = w->next_sibling) {
|
|
|
- // Don't update hidden child popup windows, their relative position doesn't change
|
|
|
- if (SDL_WINDOW_IS_POPUP(w) && !(w->flags & SDL_WINDOW_HIDDEN)) {
|
|
|
- X11_UpdateWindowPosition(w, true);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ if (!data->emit_size_move_after_property_notify) {
|
|
|
+ X11_EmitConfigureNotifyEvents(data, &xevent->xconfigure);
|
|
|
}
|
|
|
|
|
|
#ifdef SDL_VIDEO_DRIVER_X11_XSYNC
|
|
|
X11_HandleConfigure(data->window, &xevent->xconfigure);
|
|
|
#endif /* SDL_VIDEO_DRIVER_X11_XSYNC */
|
|
|
-
|
|
|
- if (xevent->xconfigure.width != data->last_xconfigure.width ||
|
|
|
- xevent->xconfigure.height != data->last_xconfigure.height) {
|
|
|
- if (!data->size_move_event_flags) {
|
|
|
- data->pending_operation &= ~X11_PENDING_OP_RESIZE;
|
|
|
- SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED,
|
|
|
- xevent->xconfigure.width,
|
|
|
- xevent->xconfigure.height);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- data->last_xconfigure = xevent->xconfigure;
|
|
|
} break;
|
|
|
|
|
|
// Have we been requested to quit (or another client message?)
|
|
@@ -1906,6 +1922,10 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ if (data->emit_size_move_after_property_notify) {
|
|
|
+ X11_EmitConfigureNotifyEvents(data, &data->pending_xconfigure);
|
|
|
+ data->emit_size_move_after_property_notify = false;
|
|
|
+ }
|
|
|
if ((flags & SDL_WINDOW_INPUT_FOCUS)) {
|
|
|
if (data->pending_move) {
|
|
|
DispatchWindowMove(_this, data, &data->pending_move_point);
|