mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-05 00:37:59 +02:00
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>
This commit is contained in:
parent
c84423baea
commit
d51f826c0b
2 changed files with 113 additions and 63 deletions
|
|
@ -118,18 +118,56 @@ weston_desktop_xdg_surface_send_configure(void *data)
|
|||
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
|
||||
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_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)
|
||||
return;
|
||||
surface->configure_idle =
|
||||
wl_event_loop_add_idle(loop,
|
||||
weston_desktop_xdg_surface_send_configure,
|
||||
surface);
|
||||
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
|
||||
|
|
@ -138,11 +176,8 @@ weston_desktop_xdg_surface_set_maximized(struct weston_desktop_surface *dsurface
|
|||
{
|
||||
struct weston_desktop_xdg_surface *surface = user_data;
|
||||
|
||||
if (surface->state.maximized == maximized)
|
||||
return;
|
||||
|
||||
surface->requested_state.maximized = maximized;
|
||||
weston_desktop_xdg_surface_schedule_configure(surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(surface, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (surface->state.fullscreen == fullscreen)
|
||||
return;
|
||||
|
||||
surface->requested_state.fullscreen = fullscreen;
|
||||
weston_desktop_xdg_surface_schedule_configure(surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(surface, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (surface->state.resizing == resizing)
|
||||
return;
|
||||
|
||||
surface->requested_state.resizing = resizing;
|
||||
weston_desktop_xdg_surface_schedule_configure(surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(surface, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (surface->state.activated == activated)
|
||||
return;
|
||||
|
||||
surface->requested_state.activated = activated;
|
||||
weston_desktop_xdg_surface_schedule_configure(surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(surface, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -190,16 +216,11 @@ weston_desktop_xdg_surface_set_size(struct weston_desktop_surface *dsurface,
|
|||
int32_t width, int32_t height)
|
||||
{
|
||||
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.height = height;
|
||||
|
||||
if ((wsurface->width == width && wsurface->height == height) ||
|
||||
(width == 0 && height == 0))
|
||||
return;
|
||||
|
||||
weston_desktop_xdg_surface_schedule_configure(surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(surface, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -217,7 +238,7 @@ weston_desktop_xdg_surface_committed(struct weston_desktop_surface *dsurface,
|
|||
surface->requested_size.height != wsurface->height;
|
||||
|
||||
if (reconfigure) {
|
||||
weston_desktop_xdg_surface_schedule_configure(surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(surface, true);
|
||||
} else {
|
||||
surface->state = surface->next_state;
|
||||
if (surface->has_next_geometry) {
|
||||
|
|
|
|||
|
|
@ -281,7 +281,8 @@ static const struct zxdg_positioner_v6_interface weston_desktop_xdg_positioner_i
|
|||
};
|
||||
|
||||
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
|
||||
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,
|
||||
toplevel->base.desktop_surface);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base, 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;
|
||||
|
||||
if (toplevel->state.maximized == maximized)
|
||||
return;
|
||||
|
||||
toplevel->requested_state.maximized = maximized;
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (toplevel->state.fullscreen == fullscreen)
|
||||
return;
|
||||
|
||||
toplevel->requested_state.fullscreen = fullscreen;
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (toplevel->state.resizing == resizing)
|
||||
return;
|
||||
|
||||
toplevel->requested_state.resizing = resizing;
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (toplevel->state.activated == activated)
|
||||
return;
|
||||
|
||||
toplevel->requested_state.activated = activated;
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -606,17 +595,11 @@ weston_desktop_xdg_toplevel_set_size(struct weston_desktop_surface *dsurface,
|
|||
int32_t width, int32_t height)
|
||||
{
|
||||
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.height = height;
|
||||
|
||||
if ((wsurface->width == width && wsurface->height == height) ||
|
||||
(width == 0 && height == 0))
|
||||
return;
|
||||
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&toplevel->base, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -793,7 +776,7 @@ static void
|
|||
weston_desktop_xdg_popup_committed(struct weston_desktop_xdg_popup *popup)
|
||||
{
|
||||
if (!popup->committed)
|
||||
weston_desktop_xdg_surface_schedule_configure(&popup->base);
|
||||
weston_desktop_xdg_surface_schedule_configure(&popup->base, true);
|
||||
popup->committed = true;
|
||||
weston_desktop_xdg_popup_update_position(popup->base.desktop_surface,
|
||||
popup);
|
||||
|
|
@ -874,18 +857,64 @@ weston_desktop_xdg_surface_send_configure(void *user_data)
|
|||
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
|
||||
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_event_loop *loop = wl_display_get_event_loop(display);
|
||||
bool requested_same = !force;
|
||||
|
||||
if (surface->configure_idle != NULL)
|
||||
return;
|
||||
surface->configure_idle =
|
||||
wl_event_loop_add_idle(loop,
|
||||
weston_desktop_xdg_surface_send_configure,
|
||||
surface);
|
||||
switch (surface->role) {
|
||||
case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
|
||||
assert(0 && "not reached");
|
||||
break;
|
||||
case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue