diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 2292f1fc8..6c2df108e 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; @@ -416,6 +417,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 e5b3b0f7d..feab00225 100644 --- a/types/scene/surface.c +++ b/types/scene/surface.c @@ -230,12 +230,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); @@ -248,6 +247,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, @@ -256,15 +270,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)); @@ -303,8 +327,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);