diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 4b9e5b2b6..57aed653a 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -243,7 +243,10 @@ toplevel_surface_commit (MetaWaylandSurface *surface, return; } - meta_window_wayland_move_resize (window, geom, pending->dx, pending->dy); + meta_window_wayland_move_resize (window, + &surface->acked_configure_serial, + geom, pending->dx, pending->dy); + surface->acked_configure_serial.set = FALSE; } } @@ -906,11 +909,10 @@ xdg_surface_ack_configure (struct wl_client *client, struct wl_resource *resource, uint32_t serial) { - /* Do nothing for now. In the future, we'd imagine that - * we'd ignore attaches when we have a state pending that - * we haven't had the client ACK'd, to prevent a race - * condition when we have an in-flight attach when the - * client gets the new state. */ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + + surface->acked_configure_serial.set = TRUE; + surface->acked_configure_serial.value = serial; } static void @@ -1811,7 +1813,8 @@ fill_states (struct wl_array *states, MetaWindow *window) void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, int new_width, - int new_height) + int new_height, + MetaWaylandSerial *sent_serial) { if (surface->xdg_surface.resource) { @@ -1832,6 +1835,12 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, xdg_surface_send_configure (surface->xdg_surface.resource, new_width, new_height, &states, serial); wl_array_release (&states); + + if (sent_serial) + { + sent_serial->set = TRUE; + sent_serial->value = serial; + } } else if (surface->wl_shell_surface.resource) wl_shell_surface_send_configure (surface->wl_shell_surface.resource, diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 582d07d4e..98a344c26 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -31,6 +31,11 @@ #include "meta-wayland-types.h" #include "meta-surface-actor.h" +struct _MetaWaylandSerial { + gboolean set; + uint32_t value; +}; + struct _MetaWaylandBuffer { struct wl_resource *resource; @@ -113,6 +118,8 @@ struct _MetaWaylandSurface /* All the pending state that wl_surface.commit will apply. */ MetaWaylandPendingState pending; + + MetaWaylandSerial acked_configure_serial; }; void meta_wayland_shell_init (MetaWaylandCompositor *compositor); @@ -126,8 +133,9 @@ void meta_wayland_surface_set_window (MetaWaylandSurface *surface MetaWindow *window); void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, - int width, - int height); + int width, + int height, + MetaWaylandSerial *sent_serial); void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial); diff --git a/src/wayland/meta-wayland-types.h b/src/wayland/meta-wayland-types.h index 9d85d5b4f..72174310a 100644 --- a/src/wayland/meta-wayland-types.h +++ b/src/wayland/meta-wayland-types.h @@ -36,4 +36,6 @@ typedef struct _MetaWaylandBufferReference MetaWaylandBufferReference; typedef struct _MetaWaylandSurface MetaWaylandSurface; +typedef struct _MetaWaylandSerial MetaWaylandSerial; + #endif diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 9d10a6783..31df759c6 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -36,6 +36,7 @@ struct _MetaWindowWayland { MetaWindow parent; + MetaWaylandSerial pending_configure_serial; gboolean has_pending_move; int pending_move_x; int pending_move_y; @@ -126,7 +127,8 @@ surface_state_changed (MetaWindow *window) meta_wayland_surface_configure_notify (window->surface, wl_window->last_sent_width, - wl_window->last_sent_height); + wl_window->last_sent_height, + &wl_window->pending_configure_serial); } static void @@ -214,7 +216,8 @@ meta_window_wayland_move_resize_internal (MetaWindow *window, meta_wayland_surface_configure_notify (window->surface, constrained_rect.width, - constrained_rect.height); + constrained_rect.height, + &wl_window->pending_configure_serial); } else { @@ -349,16 +352,33 @@ meta_window_wayland_new (MetaDisplay *display, * Complete a resize operation from a wayland client. */ void -meta_window_wayland_move_resize (MetaWindow *window, - MetaRectangle new_geom, - int dx, - int dy) +meta_window_wayland_move_resize (MetaWindow *window, + MetaWaylandSerial *acked_configure_serial, + MetaRectangle new_geom, + int dx, + int dy) { MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); int gravity; MetaRectangle rect; MetaMoveResizeFlags flags; + if (wl_window->pending_configure_serial.set) + { + /* If we're waiting for a configure and this isn't an ACK for + * any configure, then fizzle it out. */ + if (!acked_configure_serial->set) + return; + + /* If we're waiting for a configure and this isn't an ACK for + * the configure we're waiting for, then fizzle it out. */ + if (acked_configure_serial->value != wl_window->pending_configure_serial.value) + return; + + /* OK, this request is going to ACK the pending configure. */ + wl_window->pending_configure_serial.set = FALSE; + } + /* XXX: Find a better place to store the window geometry offsets. */ window->custom_frame_extents.left = new_geom.x; window->custom_frame_extents.top = new_geom.y; diff --git a/src/wayland/window-wayland.h b/src/wayland/window-wayland.h index 3c326850c..eb2e8deb5 100644 --- a/src/wayland/window-wayland.h +++ b/src/wayland/window-wayland.h @@ -45,9 +45,10 @@ typedef struct _MetaWindowWaylandClass MetaWindowWaylandClass; MetaWindow * meta_window_wayland_new (MetaDisplay *display, MetaWaylandSurface *surface); -void meta_window_wayland_move_resize (MetaWindow *window, - MetaRectangle new_geom, - int dx, - int dy); +void meta_window_wayland_move_resize (MetaWindow *window, + MetaWaylandSerial *acked_configure_serial, + MetaRectangle new_geom, + int dx, + int dy); #endif