From 4b3553409abc9c52d5b6b2dd61ad0fed04283356 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 8 Dec 2023 12:16:12 +0100 Subject: [PATCH] xdg-shell: use wlr_surface_synced for popups --- include/types/wlr_xdg_shell.h | 1 + include/wlr/types/wlr_xdg_shell.h | 4 ++++ types/xdg_shell/wlr_xdg_popup.c | 31 ++++++++++++++++++++++++------- types/xdg_shell/wlr_xdg_surface.c | 3 +++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/types/wlr_xdg_shell.h b/include/types/wlr_xdg_shell.h index 1ae142fd..f3f12ec9 100644 --- a/include/types/wlr_xdg_shell.h +++ b/include/types/wlr_xdg_shell.h @@ -20,6 +20,7 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, struct wlr_xdg_positioner *positioner, uint32_t id); void reset_xdg_popup(struct wlr_xdg_popup *popup); void destroy_xdg_popup(struct wlr_xdg_popup *popup); +void handle_xdg_popup_client_commit(struct wlr_xdg_popup *popup); void handle_xdg_popup_committed(struct wlr_xdg_popup *popup); struct wlr_xdg_popup_configure *send_xdg_popup_configure( struct wlr_xdg_popup *popup); diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 168d76d9..5c490455 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -110,6 +110,10 @@ struct wlr_xdg_popup { } events; struct wl_list grab_link; // wlr_xdg_popup_grab.popups + + // private state + + struct wlr_surface_synced synced; }; // each seat gets a popup grab diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index 6a6a6e43..e376344b 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -236,16 +236,16 @@ static struct wlr_xdg_popup_grab *get_xdg_shell_popup_grab_from_seat( return xdg_grab; } -void handle_xdg_popup_committed(struct wlr_xdg_popup *popup) { +void handle_xdg_popup_client_commit(struct wlr_xdg_popup *popup) { if (!popup->parent) { wl_resource_post_error(popup->base->resource, XDG_SURFACE_ERROR_NOT_CONSTRUCTED, "xdg_popup has no parent"); return; } +} - popup->current = popup->pending; - +void handle_xdg_popup_committed(struct wlr_xdg_popup *popup) { if (popup->base->initial_commit && !popup->sent_initial_configure) { wlr_xdg_surface_schedule_configure(popup->base); popup->sent_initial_configure = true; @@ -358,6 +358,10 @@ static const struct xdg_popup_interface xdg_popup_implementation = { .reposition = xdg_popup_handle_reposition, }; +static const struct wlr_surface_synced_impl surface_synced_impl = { + .state_size = sizeof(struct wlr_xdg_popup_state), +}; + static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) { struct wlr_xdg_popup *popup = wlr_xdg_popup_from_resource(resource); @@ -396,14 +400,17 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, } surface->popup->base = surface; + if (!wlr_surface_synced_init(&surface->popup->synced, surface->surface, + &surface_synced_impl, &surface->popup->pending, + &surface->popup->current)) { + goto error_popup; + } + surface->popup->resource = wl_resource_create( surface->client->client, &xdg_popup_interface, wl_resource_get_version(surface->resource), id); if (surface->popup->resource == NULL) { - free(surface->popup); - surface->popup = NULL; - wl_resource_post_no_memory(surface->resource); - return; + goto error_synced; } wl_resource_set_implementation(surface->popup->resource, &xdg_popup_implementation, surface->popup, @@ -429,6 +436,15 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, set_xdg_surface_role_object(surface, surface->popup->resource); wl_signal_emit_mutable(&surface->client->shell->events.new_popup, surface->popup); + + return; + +error_synced: + wlr_surface_synced_finish(&surface->popup->synced); +error_popup: + free(surface->popup); + surface->popup = NULL; + wl_resource_post_no_memory(surface->resource); } void reset_xdg_popup(struct wlr_xdg_popup *popup) { @@ -465,6 +481,7 @@ void destroy_xdg_popup(struct wlr_xdg_popup *popup) { wl_signal_emit_mutable(&popup->events.destroy, NULL); + wlr_surface_synced_finish(&popup->synced); popup->base->popup = NULL; wl_list_remove(&popup->link); wl_resource_set_user_data(popup->resource, NULL); diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index 9d46208e..0e2ed3d0 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -284,6 +284,9 @@ static void xdg_surface_role_client_commit(struct wlr_surface *wlr_surface) { } break; case WLR_XDG_SURFACE_ROLE_POPUP: + if (surface->popup != NULL) { + handle_xdg_popup_client_commit(surface->popup); + } break; } }