From db4afc240820b541bc433b76840633d2170817b9 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Thu, 29 Jul 2021 23:03:14 +0300 Subject: [PATCH] xdg-surface: add pending state struct wlr_xdg_surface_state is introduced to hold the geometry and configure serial to be applied on next wl_surface.commit. This commit fixes our handling for ack_configure: instead of making the request mutate our current state, it mutates the pending state only. Co-authored-by: Simon Ser --- include/wlr/types/wlr_xdg_shell.h | 9 +++++++-- types/xdg_shell/wlr_xdg_surface.c | 31 +++++++++++++++---------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 2ca7e203..c214769a 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -161,6 +161,11 @@ struct wlr_xdg_surface_configure { struct wlr_xdg_toplevel_configure *toplevel_configure; }; +struct wlr_xdg_surface_state { + uint32_t configure_serial; + struct wlr_box geometry; +}; + /** * An xdg-surface is a user interface element requiring management by the * compositor. An xdg-surface alone isn't useful, a role should be assigned to @@ -191,10 +196,10 @@ struct wlr_xdg_surface { uint32_t configure_next_serial; struct wl_list configure_list; - bool has_next_geometry; - struct wlr_box next_geometry; struct wlr_box geometry; + struct wlr_xdg_surface_state pending; + struct wl_listener surface_destroy; struct wl_listener surface_commit; diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 1613c3b4..c2ef7658 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -88,12 +88,10 @@ void unmap_xdg_surface(struct wlr_xdg_surface *surface) { } surface->configure_next_serial = 0; - surface->has_next_geometry = false; memset(&surface->geometry, 0, sizeof(struct wlr_box)); - memset(&surface->next_geometry, 0, sizeof(struct wlr_box)); + memset(&surface->pending, 0, sizeof(struct wlr_xdg_surface_state)); } - static void xdg_surface_handle_ack_configure(struct wl_client *client, struct wl_resource *resource, uint32_t serial) { struct wlr_xdg_surface *surface = wlr_xdg_surface_from_resource(resource); @@ -144,7 +142,7 @@ static void xdg_surface_handle_ack_configure(struct wl_client *client, } surface->configured = true; - surface->configure_serial = serial; + surface->pending.configure_serial = serial; wlr_signal_emit_safe(&surface->events.ack_configure, configure); xdg_surface_configure_destroy(configure); @@ -252,11 +250,10 @@ static void xdg_surface_handle_set_window_geometry(struct wl_client *client, return; } - surface->has_next_geometry = true; - surface->next_geometry.height = height; - surface->next_geometry.width = width; - surface->next_geometry.x = x; - surface->next_geometry.y = y; + surface->pending.geometry.x = x; + surface->pending.geometry.y = y; + surface->pending.geometry.width = width; + surface->pending.geometry.height = height; } static void xdg_surface_handle_destroy(struct wl_client *client, @@ -313,6 +310,14 @@ static void xdg_surface_handle_surface_commit(struct wl_listener *listener, } } +static void surface_commit_state(struct wlr_xdg_surface *surface, + struct wlr_xdg_surface_state *state) { + surface->configure_serial = state->configure_serial; + if (!wlr_box_empty(&state->geometry)) { + surface->geometry = state->geometry; + } +} + void handle_xdg_surface_commit(struct wlr_surface *wlr_surface) { struct wlr_xdg_surface *surface = wlr_xdg_surface_from_wlr_surface(wlr_surface); @@ -320,13 +325,7 @@ void handle_xdg_surface_commit(struct wlr_surface *wlr_surface) { return; } - if (surface->has_next_geometry) { - surface->has_next_geometry = false; - surface->geometry.x = surface->next_geometry.x; - surface->geometry.y = surface->next_geometry.y; - surface->geometry.width = surface->next_geometry.width; - surface->geometry.height = surface->next_geometry.height; - } + surface_commit_state(surface, &surface->pending); switch (surface->role) { case WLR_XDG_SURFACE_ROLE_NONE: