libweston-desktop/xdg-shell: Consolidate configure event sending

When switching a state twice in a row, we were overwriting the old value
without setting it back, sending a wrong state to the client.

Now we update our requested state, then check if we need to schedule a
configure event, if we have one scheduled already or even if we can
cancel it.

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
Reviewed-by: Daniel Stone <daniels@collabora.com>
dev
Quentin Glidic 8 years ago
parent c84423baea
commit d51f826c0b
No known key found for this signature in database
GPG Key ID: AC203F96E2C34BB7
  1. 81
      libweston-desktop/xdg-shell-v5.c
  2. 95
      libweston-desktop/xdg-shell-v6.c

@ -118,18 +118,56 @@ weston_desktop_xdg_surface_send_configure(void *data)
wl_array_release(&states); wl_array_release(&states);
}; };
static bool
weston_desktop_xdg_surface_state_compare(struct weston_desktop_xdg_surface *surface)
{
struct weston_surface *wsurface =
weston_desktop_surface_get_surface(surface->surface);
if (surface->requested_state.activated != surface->state.activated)
return false;
if (surface->requested_state.fullscreen != surface->state.fullscreen)
return false;
if (surface->requested_state.maximized != surface->state.maximized)
return false;
if (surface->requested_state.resizing != surface->state.resizing)
return false;
if (wsurface->width == surface->requested_size.width &&
wsurface->height == surface->requested_size.height)
return true;
if (surface->requested_size.width == 0 &&
surface->requested_size.height == 0)
return true;
return false;
}
static void static void
weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *surface) weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *surface,
bool force)
{ {
struct wl_display *display = weston_desktop_get_display(surface->desktop); struct wl_display *display = weston_desktop_get_display(surface->desktop);
struct wl_event_loop *loop = wl_display_get_event_loop(display); struct wl_event_loop *loop = wl_display_get_event_loop(display);
bool requested_same =
!force && weston_desktop_xdg_surface_state_compare(surface);
if (surface->configure_idle != NULL) if (surface->configure_idle != NULL) {
return; if (!requested_same)
surface->configure_idle = return;
wl_event_loop_add_idle(loop,
weston_desktop_xdg_surface_send_configure, wl_event_source_remove(surface->configure_idle);
surface); surface->configure_idle = NULL;
} else {
if (requested_same)
return;
surface->configure_idle =
wl_event_loop_add_idle(loop,
weston_desktop_xdg_surface_send_configure,
surface);
}
} }
static void static void
@ -138,11 +176,8 @@ weston_desktop_xdg_surface_set_maximized(struct weston_desktop_surface *dsurface
{ {
struct weston_desktop_xdg_surface *surface = user_data; struct weston_desktop_xdg_surface *surface = user_data;
if (surface->state.maximized == maximized)
return;
surface->requested_state.maximized = maximized; surface->requested_state.maximized = maximized;
weston_desktop_xdg_surface_schedule_configure(surface); weston_desktop_xdg_surface_schedule_configure(surface, false);
} }
static void static void
@ -151,11 +186,8 @@ weston_desktop_xdg_surface_set_fullscreen(struct weston_desktop_surface *dsurfac
{ {
struct weston_desktop_xdg_surface *surface = user_data; struct weston_desktop_xdg_surface *surface = user_data;
if (surface->state.fullscreen == fullscreen)
return;
surface->requested_state.fullscreen = fullscreen; surface->requested_state.fullscreen = fullscreen;
weston_desktop_xdg_surface_schedule_configure(surface); weston_desktop_xdg_surface_schedule_configure(surface, false);
} }
static void static void
@ -164,11 +196,8 @@ weston_desktop_xdg_surface_set_resizing(struct weston_desktop_surface *dsurface,
{ {
struct weston_desktop_xdg_surface *surface = user_data; struct weston_desktop_xdg_surface *surface = user_data;
if (surface->state.resizing == resizing)
return;
surface->requested_state.resizing = resizing; surface->requested_state.resizing = resizing;
weston_desktop_xdg_surface_schedule_configure(surface); weston_desktop_xdg_surface_schedule_configure(surface, false);
} }
static void static void
@ -177,11 +206,8 @@ weston_desktop_xdg_surface_set_activated(struct weston_desktop_surface *dsurface
{ {
struct weston_desktop_xdg_surface *surface = user_data; struct weston_desktop_xdg_surface *surface = user_data;
if (surface->state.activated == activated)
return;
surface->requested_state.activated = activated; surface->requested_state.activated = activated;
weston_desktop_xdg_surface_schedule_configure(surface); weston_desktop_xdg_surface_schedule_configure(surface, false);
} }
static void static void
@ -190,16 +216,11 @@ weston_desktop_xdg_surface_set_size(struct weston_desktop_surface *dsurface,
int32_t width, int32_t height) int32_t width, int32_t height)
{ {
struct weston_desktop_xdg_surface *surface = user_data; struct weston_desktop_xdg_surface *surface = user_data;
struct weston_surface *wsurface = weston_desktop_surface_get_surface(surface->surface);
surface->requested_size.width = width; surface->requested_size.width = width;
surface->requested_size.height = height; surface->requested_size.height = height;
if ((wsurface->width == width && wsurface->height == height) || weston_desktop_xdg_surface_schedule_configure(surface, false);
(width == 0 && height == 0))
return;
weston_desktop_xdg_surface_schedule_configure(surface);
} }
static void static void
@ -217,7 +238,7 @@ weston_desktop_xdg_surface_committed(struct weston_desktop_surface *dsurface,
surface->requested_size.height != wsurface->height; surface->requested_size.height != wsurface->height;
if (reconfigure) { if (reconfigure) {
weston_desktop_xdg_surface_schedule_configure(surface); weston_desktop_xdg_surface_schedule_configure(surface, true);
} else { } else {
surface->state = surface->next_state; surface->state = surface->next_state;
if (surface->has_next_geometry) { if (surface->has_next_geometry) {

@ -281,7 +281,8 @@ static const struct zxdg_positioner_v6_interface weston_desktop_xdg_positioner_i
}; };
static void static void
weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *surface); weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *surface,
bool force);
static void static void
weston_desktop_xdg_toplevel_ensure_added(struct weston_desktop_xdg_toplevel *toplevel) weston_desktop_xdg_toplevel_ensure_added(struct weston_desktop_xdg_toplevel *toplevel)
@ -291,7 +292,7 @@ weston_desktop_xdg_toplevel_ensure_added(struct weston_desktop_xdg_toplevel *top
weston_desktop_api_surface_added(toplevel->base.desktop, weston_desktop_api_surface_added(toplevel->base.desktop,
toplevel->base.desktop_surface); toplevel->base.desktop_surface);
weston_desktop_xdg_surface_schedule_configure(&toplevel->base); weston_desktop_xdg_surface_schedule_configure(&toplevel->base, true);
toplevel->added = true; toplevel->added = true;
} }
@ -554,11 +555,8 @@ weston_desktop_xdg_toplevel_set_maximized(struct weston_desktop_surface *dsurfac
{ {
struct weston_desktop_xdg_toplevel *toplevel = user_data; struct weston_desktop_xdg_toplevel *toplevel = user_data;
if (toplevel->state.maximized == maximized)
return;
toplevel->requested_state.maximized = maximized; toplevel->requested_state.maximized = maximized;
weston_desktop_xdg_surface_schedule_configure(&toplevel->base); weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
} }
static void static void
@ -567,11 +565,8 @@ weston_desktop_xdg_toplevel_set_fullscreen(struct weston_desktop_surface *dsurfa
{ {
struct weston_desktop_xdg_toplevel *toplevel = user_data; struct weston_desktop_xdg_toplevel *toplevel = user_data;
if (toplevel->state.fullscreen == fullscreen)
return;
toplevel->requested_state.fullscreen = fullscreen; toplevel->requested_state.fullscreen = fullscreen;
weston_desktop_xdg_surface_schedule_configure(&toplevel->base); weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
} }
static void static void
@ -580,11 +575,8 @@ weston_desktop_xdg_toplevel_set_resizing(struct weston_desktop_surface *dsurface
{ {
struct weston_desktop_xdg_toplevel *toplevel = user_data; struct weston_desktop_xdg_toplevel *toplevel = user_data;
if (toplevel->state.resizing == resizing)
return;
toplevel->requested_state.resizing = resizing; toplevel->requested_state.resizing = resizing;
weston_desktop_xdg_surface_schedule_configure(&toplevel->base); weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
} }
static void static void
@ -593,11 +585,8 @@ weston_desktop_xdg_toplevel_set_activated(struct weston_desktop_surface *dsurfac
{ {
struct weston_desktop_xdg_toplevel *toplevel = user_data; struct weston_desktop_xdg_toplevel *toplevel = user_data;
if (toplevel->state.activated == activated)
return;
toplevel->requested_state.activated = activated; toplevel->requested_state.activated = activated;
weston_desktop_xdg_surface_schedule_configure(&toplevel->base); weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
} }
static void static void
@ -606,17 +595,11 @@ weston_desktop_xdg_toplevel_set_size(struct weston_desktop_surface *dsurface,
int32_t width, int32_t height) int32_t width, int32_t height)
{ {
struct weston_desktop_xdg_toplevel *toplevel = user_data; struct weston_desktop_xdg_toplevel *toplevel = user_data;
struct weston_surface *wsurface =
weston_desktop_surface_get_surface(toplevel->base.desktop_surface);
toplevel->requested_size.width = width; toplevel->requested_size.width = width;
toplevel->requested_size.height = height; toplevel->requested_size.height = height;
if ((wsurface->width == width && wsurface->height == height) || weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
(width == 0 && height == 0))
return;
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
} }
static void static void
@ -793,7 +776,7 @@ static void
weston_desktop_xdg_popup_committed(struct weston_desktop_xdg_popup *popup) weston_desktop_xdg_popup_committed(struct weston_desktop_xdg_popup *popup)
{ {
if (!popup->committed) if (!popup->committed)
weston_desktop_xdg_surface_schedule_configure(&popup->base); weston_desktop_xdg_surface_schedule_configure(&popup->base, true);
popup->committed = true; popup->committed = true;
weston_desktop_xdg_popup_update_position(popup->base.desktop_surface, weston_desktop_xdg_popup_update_position(popup->base.desktop_surface,
popup); popup);
@ -874,18 +857,64 @@ weston_desktop_xdg_surface_send_configure(void *user_data)
zxdg_surface_v6_send_configure(surface->resource, surface->configure_serial); zxdg_surface_v6_send_configure(surface->resource, surface->configure_serial);
} }
static bool
weston_desktop_xdg_toplevel_state_compare(struct weston_desktop_xdg_toplevel *toplevel)
{
if (toplevel->requested_state.activated != toplevel->state.activated)
return false;
if (toplevel->requested_state.fullscreen != toplevel->state.fullscreen)
return false;
if (toplevel->requested_state.maximized != toplevel->state.maximized)
return false;
if (toplevel->requested_state.resizing != toplevel->state.resizing)
return false;
if (toplevel->base.surface->width == toplevel->requested_size.width &&
toplevel->base.surface->height == toplevel->requested_size.height)
return true;
if (toplevel->requested_size.width == 0 &&
toplevel->requested_size.height == 0)
return true;
return false;
}
static void static void
weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *surface) weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *surface,
bool force)
{ {
struct wl_display *display = weston_desktop_get_display(surface->desktop); struct wl_display *display = weston_desktop_get_display(surface->desktop);
struct wl_event_loop *loop = wl_display_get_event_loop(display); struct wl_event_loop *loop = wl_display_get_event_loop(display);
bool requested_same = !force;
if (surface->configure_idle != NULL) switch (surface->role) {
return; case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
surface->configure_idle = assert(0 && "not reached");
wl_event_loop_add_idle(loop, break;
weston_desktop_xdg_surface_send_configure, case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
surface); requested_same = requested_same &&
weston_desktop_xdg_toplevel_state_compare((struct weston_desktop_xdg_toplevel *) surface);
break;
case WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP:
break;
}
if (surface->configure_idle != NULL) {
if (!requested_same)
return;
wl_event_source_remove(surface->configure_idle);
surface->configure_idle = NULL;
} else {
if (requested_same)
return;
surface->configure_idle =
wl_event_loop_add_idle(loop,
weston_desktop_xdg_surface_send_configure,
surface);
}
} }
static void static void

Loading…
Cancel
Save