From 69d9a4e2cbd5fae3dcb7b30530092e03465dc67b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 8 Dec 2023 12:34:18 +0100 Subject: [PATCH] xdg-shell: use wlr_surface_synced for wlr_xdg_surface --- include/wlr/types/wlr_xdg_shell.h | 2 ++ types/xdg_shell/wlr_xdg_surface.c | 53 ++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 9df690f9..fbc771a7 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -281,6 +281,8 @@ struct wlr_xdg_surface { // private state + struct wlr_surface_synced synced; + struct wl_listener role_resource_destroy; }; diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 035d345e..7dd39708 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -256,11 +256,11 @@ static const struct xdg_surface_interface xdg_surface_implementation = { .set_window_geometry = xdg_surface_handle_set_window_geometry, }; -static void xdg_surface_role_commit(struct wlr_surface *wlr_surface) { +static void xdg_surface_role_client_commit(struct wlr_surface *wlr_surface) { struct wlr_xdg_surface *surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface); assert(surface != NULL); - if (wlr_surface_has_buffer(wlr_surface) && !surface->configured) { + if (wlr_surface_state_has_buffer(&wlr_surface->pending) && !surface->configured) { wl_resource_post_error(surface->resource, XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, "xdg_surface has never been configured"); @@ -273,6 +273,11 @@ static void xdg_surface_role_commit(struct wlr_surface *wlr_surface) { "xdg_surface must have a role object"); return; } +} + +static void xdg_surface_role_commit(struct wlr_surface *wlr_surface) { + struct wlr_xdg_surface *surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface); + assert(surface != NULL); if (surface->surface->unmap_commit) { reset_xdg_surface_role_object(surface); @@ -285,8 +290,6 @@ static void xdg_surface_role_commit(struct wlr_surface *wlr_surface) { surface->initialized = true; } - surface->current = surface->pending; - switch (surface->role) { case WLR_XDG_SURFACE_ROLE_NONE: assert(0 && "not reached"); @@ -322,12 +325,17 @@ static void xdg_surface_role_destroy(struct wlr_surface *wlr_surface) { destroy_xdg_surface(surface); } -static struct wlr_surface_role xdg_surface_role = { +static const struct wlr_surface_role xdg_surface_role = { .name = "xdg_surface", + .client_commit = xdg_surface_role_client_commit, .commit = xdg_surface_role_commit, .destroy = xdg_surface_role_destroy, }; +static const struct wlr_surface_synced_impl surface_synced_impl = { + .state_size = sizeof(struct wlr_xdg_surface_state), +}; + struct wlr_xdg_surface *wlr_xdg_surface_try_from_wlr_surface( struct wlr_surface *surface) { if (surface->role != &xdg_surface_role || surface->role_resource == NULL) { @@ -343,12 +351,24 @@ void create_xdg_surface(struct wlr_xdg_client *client, struct wlr_surface *wlr_s return; } + if (wlr_surface_has_buffer(wlr_surface)) { + wl_resource_post_error(client->resource, + XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, + "xdg_surface must not have a buffer at creation"); + return; + } + struct wlr_xdg_surface *surface = calloc(1, sizeof(*surface)); if (surface == NULL) { wl_client_post_no_memory(client->client); return; } + if (!wlr_surface_synced_init(&surface->synced, wlr_surface, + &surface_synced_impl, &surface->pending, &surface->current)) { + goto error_surface; + } + surface->client = client; surface->role = WLR_XDG_SURFACE_ROLE_NONE; surface->surface = wlr_surface; @@ -356,18 +376,7 @@ void create_xdg_surface(struct wlr_xdg_client *client, struct wlr_surface *wlr_s &xdg_surface_interface, wl_resource_get_version(client->resource), id); if (surface->resource == NULL) { - free(surface); - wl_client_post_no_memory(client->client); - return; - } - - if (wlr_surface_has_buffer(surface->surface)) { - wl_resource_destroy(surface->resource); - free(surface); - wl_resource_post_error(client->resource, - XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, - "xdg_surface must not have a buffer at creation"); - return; + goto error_synced; } wl_list_init(&surface->configure_list); @@ -388,6 +397,14 @@ void create_xdg_surface(struct wlr_xdg_client *client, struct wlr_surface *wlr_s wlr_surface_set_role_object(wlr_surface, surface->resource); wl_signal_emit_mutable(&surface->client->shell->events.new_surface, surface); + + return; + +error_synced: + wlr_surface_synced_finish(&surface->synced); +error_surface: + free(surface); + wl_client_post_no_memory(client->client); } bool set_xdg_surface_role(struct wlr_xdg_surface *surface, enum wlr_xdg_surface_role role) { @@ -465,7 +482,7 @@ void destroy_xdg_surface(struct wlr_xdg_surface *surface) { wl_signal_emit_mutable(&surface->events.destroy, NULL); wl_list_remove(&surface->link); - + wlr_surface_synced_finish(&surface->synced); wl_resource_set_user_data(surface->resource, NULL); free(surface); }