xdg-shell: use wlr_surface_synced for popups

This commit is contained in:
Simon Ser 2023-12-08 12:16:12 +01:00
parent 9201431c29
commit 4b3553409a
4 changed files with 32 additions and 7 deletions

View file

@ -20,6 +20,7 @@ void create_xdg_popup(struct wlr_xdg_surface *surface,
struct wlr_xdg_positioner *positioner, uint32_t id); struct wlr_xdg_positioner *positioner, uint32_t id);
void reset_xdg_popup(struct wlr_xdg_popup *popup); void reset_xdg_popup(struct wlr_xdg_popup *popup);
void destroy_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); void handle_xdg_popup_committed(struct wlr_xdg_popup *popup);
struct wlr_xdg_popup_configure *send_xdg_popup_configure( struct wlr_xdg_popup_configure *send_xdg_popup_configure(
struct wlr_xdg_popup *popup); struct wlr_xdg_popup *popup);

View file

@ -110,6 +110,10 @@ struct wlr_xdg_popup {
} events; } events;
struct wl_list grab_link; // wlr_xdg_popup_grab.popups struct wl_list grab_link; // wlr_xdg_popup_grab.popups
// private state
struct wlr_surface_synced synced;
}; };
// each seat gets a popup grab // each seat gets a popup grab

View file

@ -236,16 +236,16 @@ static struct wlr_xdg_popup_grab *get_xdg_shell_popup_grab_from_seat(
return xdg_grab; 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) { if (!popup->parent) {
wl_resource_post_error(popup->base->resource, wl_resource_post_error(popup->base->resource,
XDG_SURFACE_ERROR_NOT_CONSTRUCTED, XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
"xdg_popup has no parent"); "xdg_popup has no parent");
return; return;
} }
}
popup->current = popup->pending; void handle_xdg_popup_committed(struct wlr_xdg_popup *popup) {
if (popup->base->initial_commit && !popup->sent_initial_configure) { if (popup->base->initial_commit && !popup->sent_initial_configure) {
wlr_xdg_surface_schedule_configure(popup->base); wlr_xdg_surface_schedule_configure(popup->base);
popup->sent_initial_configure = true; popup->sent_initial_configure = true;
@ -358,6 +358,10 @@ static const struct xdg_popup_interface xdg_popup_implementation = {
.reposition = xdg_popup_handle_reposition, .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) { static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_xdg_popup *popup = struct wlr_xdg_popup *popup =
wlr_xdg_popup_from_resource(resource); wlr_xdg_popup_from_resource(resource);
@ -396,14 +400,17 @@ void create_xdg_popup(struct wlr_xdg_surface *surface,
} }
surface->popup->base = 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->popup->resource = wl_resource_create(
surface->client->client, &xdg_popup_interface, surface->client->client, &xdg_popup_interface,
wl_resource_get_version(surface->resource), id); wl_resource_get_version(surface->resource), id);
if (surface->popup->resource == NULL) { if (surface->popup->resource == NULL) {
free(surface->popup); goto error_synced;
surface->popup = NULL;
wl_resource_post_no_memory(surface->resource);
return;
} }
wl_resource_set_implementation(surface->popup->resource, wl_resource_set_implementation(surface->popup->resource,
&xdg_popup_implementation, surface->popup, &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); set_xdg_surface_role_object(surface, surface->popup->resource);
wl_signal_emit_mutable(&surface->client->shell->events.new_popup, surface->popup); 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) { 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); wl_signal_emit_mutable(&popup->events.destroy, NULL);
wlr_surface_synced_finish(&popup->synced);
popup->base->popup = NULL; popup->base->popup = NULL;
wl_list_remove(&popup->link); wl_list_remove(&popup->link);
wl_resource_set_user_data(popup->resource, NULL); wl_resource_set_user_data(popup->resource, NULL);

View file

@ -284,6 +284,9 @@ static void xdg_surface_role_client_commit(struct wlr_surface *wlr_surface) {
} }
break; break;
case WLR_XDG_SURFACE_ROLE_POPUP: case WLR_XDG_SURFACE_ROLE_POPUP:
if (surface->popup != NULL) {
handle_xdg_popup_client_commit(surface->popup);
}
break; break;
} }
} }