aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2023-12-08 12:16:12 +0100
committerSimon Ser <contact@emersion.fr>2023-12-25 11:47:15 +0100
commit4b3553409abc9c52d5b6b2dd61ad0fed04283356 (patch)
tree10d125542371ceca50ce28cb869f24bcae2455f5
parent9201431c291ccd26d0958e1a8ab9cb9c84763677 (diff)
xdg-shell: use wlr_surface_synced for popups
-rw-r--r--include/types/wlr_xdg_shell.h1
-rw-r--r--include/wlr/types/wlr_xdg_shell.h4
-rw-r--r--types/xdg_shell/wlr_xdg_popup.c31
-rw-r--r--types/xdg_shell/wlr_xdg_surface.c3
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;
}
}