diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h index 94262b4b..da12427e 100644 --- a/include/wlr/types/wlr_compositor.h +++ b/include/wlr/types/wlr_compositor.h @@ -81,6 +81,15 @@ struct wlr_surface_role { * For example, this applies to cursor surfaces. */ bool no_object; + /** + * Called when the client sends the wl_surface.commit request. May be NULL. + * Typically used to check that the pending state is valid, and send + * protocol errors if not. + * + * If the role is represented by an object, this is only called if + * such object exists. + */ + void (*client_commit)(struct wlr_surface *surface); /** * Called when a new surface state is committed. May be NULL. * diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c index d9c7b3c1..c3cc59a3 100644 --- a/types/wlr_compositor.c +++ b/types/wlr_compositor.c @@ -565,6 +565,11 @@ static void surface_handle_commit(struct wl_client *client, struct wlr_surface *surface = wlr_surface_from_resource(resource); surface_finalize_pending(surface); + if (surface->role != NULL && surface->role->client_commit != NULL && + (surface->role_resource != NULL || surface->role->no_object)) { + surface->role->client_commit(surface); + } + wl_signal_emit_mutable(&surface->events.client_commit, NULL); if (surface->pending.cached_state_locks > 0 || !wl_list_empty(&surface->cached)) {