From bf72bed1edeeca1875649d9899ae20fd667b80c5 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Fri, 15 Nov 2024 20:05:10 +0300 Subject: [PATCH] scene: allow at most one scene surface per surface --- include/wlr/types/wlr_scene.h | 11 ++++++++- types/scene/surface.c | 42 ++++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 0e3e7750a..6e5b8f774 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -123,7 +123,8 @@ struct wlr_scene_surface { struct { struct wlr_box clip; - struct wlr_addon addon; + struct wlr_addon scene_buffer_addon; + struct wlr_addon surface_addon; struct wl_listener outputs_update; struct wl_listener output_enter; @@ -402,6 +403,14 @@ struct wlr_scene_rect *wlr_scene_rect_from_node(struct wlr_scene_node *node); struct wlr_scene_surface *wlr_scene_surface_try_from_buffer( struct wlr_scene_buffer *scene_buffer); +/** + * Get a struct wlr_scene_surface from a struct wlr_surface. + * + * Returns NULL if there's no struct wlr_scene_surface created for this + * struct wlr_surface. + */ +struct wlr_scene_surface *wlr_scene_surface_try_from_wlr_surface(struct wlr_surface *surface); + /** * Add a node displaying a solid-colored rectangle to the scene-graph. * diff --git a/types/scene/surface.c b/types/scene/surface.c index 2aff5af37..8708e7bf9 100644 --- a/types/scene/surface.c +++ b/types/scene/surface.c @@ -228,12 +228,11 @@ static bool scene_buffer_point_accepts_input(struct wlr_scene_buffer *scene_buff return wlr_surface_point_accepts_input(scene_surface->surface, *sx, *sy); } -static void surface_addon_destroy(struct wlr_addon *addon) { - struct wlr_scene_surface *surface = wl_container_of(addon, surface, addon); - +static void scene_surface_destroy(struct wlr_scene_surface *surface) { scene_buffer_unmark_client_buffer(surface->buffer); - wlr_addon_finish(&surface->addon); + wlr_addon_finish(&surface->scene_buffer_addon); + wlr_addon_finish(&surface->surface_addon); wl_list_remove(&surface->outputs_update.link); wl_list_remove(&surface->output_enter.link); @@ -246,6 +245,21 @@ static void surface_addon_destroy(struct wlr_addon *addon) { free(surface); } +static void scene_buffer_addon_destroy(struct wlr_addon *addon) { + struct wlr_scene_surface *surface = wl_container_of(addon, surface, scene_buffer_addon); + scene_surface_destroy(surface); +} + +static const struct wlr_addon_interface scene_buffer_addon_impl = { + .name = "wlr_scene_surface", + .destroy = scene_buffer_addon_destroy, +}; + +static void surface_addon_destroy(struct wlr_addon *addon) { + struct wlr_scene_surface *surface = wl_container_of(addon, surface, surface_addon); + scene_surface_destroy(surface); +} + static const struct wlr_addon_interface surface_addon_impl = { .name = "wlr_scene_surface", .destroy = surface_addon_destroy, @@ -254,15 +268,25 @@ static const struct wlr_addon_interface surface_addon_impl = { struct wlr_scene_surface *wlr_scene_surface_try_from_buffer( struct wlr_scene_buffer *scene_buffer) { struct wlr_addon *addon = wlr_addon_find(&scene_buffer->node.addons, - scene_buffer, &surface_addon_impl); + scene_buffer, &scene_buffer_addon_impl); if (!addon) { return NULL; } - struct wlr_scene_surface *surface = wl_container_of(addon, surface, addon); + struct wlr_scene_surface *surface = wl_container_of(addon, surface, scene_buffer_addon); return surface; } +struct wlr_scene_surface *wlr_scene_surface_try_from_wlr_surface(struct wlr_surface *surface) { + struct wlr_addon *addon = wlr_addon_find(&surface->addons, NULL, &surface_addon_impl); + if (addon == NULL) { + return NULL; + } + + struct wlr_scene_surface *scene_surface = wl_container_of(addon, scene_surface, surface_addon); + return scene_surface; +} + struct wlr_scene_surface *wlr_scene_surface_create(struct wlr_scene_tree *parent, struct wlr_surface *wlr_surface) { struct wlr_scene_surface *surface = calloc(1, sizeof(*surface)); @@ -301,8 +325,10 @@ struct wlr_scene_surface *wlr_scene_surface_create(struct wlr_scene_tree *parent surface->surface_commit.notify = handle_scene_surface_surface_commit; wl_signal_add(&wlr_surface->events.commit, &surface->surface_commit); - wlr_addon_init(&surface->addon, &scene_buffer->node.addons, - scene_buffer, &surface_addon_impl); + wlr_addon_init(&surface->scene_buffer_addon, &scene_buffer->node.addons, + scene_buffer, &scene_buffer_addon_impl); + + wlr_addon_init(&surface->surface_addon, &wlr_surface->addons, NULL, &surface_addon_impl); surface_reconfigure(surface);