From f5917f0247600b65edec1735234d00de57d577a8 Mon Sep 17 00:00:00 2001 From: Rose Hudson Date: Tue, 22 Aug 2023 11:52:45 +0200 Subject: [PATCH] scene_output_layout: make output adding explicit Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3709 --- include/wlr/types/wlr_scene.h | 20 ++++++++++++++----- tinywl/tinywl.c | 8 ++++++-- types/scene/output_layout.c | 36 ++++++----------------------------- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 2dd9401f..3af839ab 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -30,6 +30,7 @@ struct wlr_output; struct wlr_output_layout; +struct wlr_output_layout_output; struct wlr_xdg_surface; struct wlr_layer_surface_v1; struct wlr_drag_icon; @@ -37,6 +38,7 @@ struct wlr_surface; struct wlr_scene_node; struct wlr_scene_buffer; +struct wlr_scene_output_layout; struct wlr_presentation; struct wlr_linux_dmabuf_v1; @@ -515,14 +517,22 @@ struct wlr_scene_output *wlr_scene_get_scene_output(struct wlr_scene *scene, /** * Attach an output layout to a scene. * - * Adding, removing, or repositioning an output in the output layout - * will respectively add, remove or reposition a corresponding - * scene-graph output. When the output layout is destroyed, scene-graph - * outputs which were created by this helper will be destroyed. + * With an attached `wlr_scene_output_layout`, removing or repositioning an output in the output + * layout will respectively remove or reposition a corresponding scene-graph output. When the output + * layout is destroyed, scene-graph outputs which were attached to this helper will be destroyed. + * + * When adding an output to the output_layout, users must also create a `wlr_scene_output` and pass + * it to wlr_scene_output_layout_add_output(). */ -bool wlr_scene_attach_output_layout(struct wlr_scene *scene, +struct wlr_scene_output_layout *wlr_scene_attach_output_layout(struct wlr_scene *scene, struct wlr_output_layout *output_layout); +/** + * Add an output to the scene, with its positioning defined by the output layout. + */ +void wlr_scene_output_layout_add_output(struct wlr_scene_output_layout *sol, + struct wlr_output_layout_output *lo, struct wlr_scene_output *so); + /** * Add a node displaying a surface and all of its sub-surfaces to the * scene-graph. diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c index e91ad283..67d2be77 100644 --- a/tinywl/tinywl.c +++ b/tinywl/tinywl.c @@ -39,6 +39,7 @@ struct tinywl_server { struct wlr_renderer *renderer; struct wlr_allocator *allocator; struct wlr_scene *scene; + struct wlr_scene_output_layout *scene_layout; struct wlr_xdg_shell *xdg_shell; struct wl_listener new_xdg_surface; @@ -646,7 +647,10 @@ static void server_new_output(struct wl_listener *listener, void *data) { * display, which Wayland clients can see to find out information about the * output (such as DPI, scale factor, manufacturer, etc). */ - wlr_output_layout_add_auto(server->output_layout, wlr_output); + struct wlr_output_layout_output *l_output = wlr_output_layout_add_auto(server->output_layout, + wlr_output); + struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output); + wlr_scene_output_layout_add_output(server->scene_layout, l_output, scene_output); } static void xdg_toplevel_map(struct wl_listener *listener, void *data) { @@ -906,7 +910,7 @@ int main(int argc, char *argv[]) { * necessary. */ server.scene = wlr_scene_create(); - wlr_scene_attach_output_layout(server.scene, server.output_layout); + server.scene_layout = wlr_scene_attach_output_layout(server.scene, server.output_layout); /* Set up xdg-shell version 3. The xdg-shell is a Wayland protocol which is * used for application windows. For more detail on shells, refer to my diff --git a/types/scene/output_layout.c b/types/scene/output_layout.c index 1d1484ad..81dc752a 100644 --- a/types/scene/output_layout.c +++ b/types/scene/output_layout.c @@ -8,7 +8,6 @@ struct wlr_scene_output_layout { struct wl_list outputs; // wlr_scene_output_layout_output.link - struct wl_listener layout_add; struct wl_listener layout_change; struct wl_listener layout_destroy; struct wl_listener scene_destroy; @@ -53,7 +52,6 @@ static void scene_output_layout_destroy(struct wlr_scene_output_layout *sol) { wl_list_for_each_safe(solo, tmp, &sol->outputs, link) { scene_output_layout_output_destroy(solo); } - wl_list_remove(&sol->layout_add.link); wl_list_remove(&sol->layout_change.link); wl_list_remove(&sol->layout_destroy.link); wl_list_remove(&sol->scene_destroy.link); @@ -72,19 +70,14 @@ static void scene_output_layout_handle_layout_change( } } -static void scene_output_layout_add(struct wlr_scene_output_layout *sol, - struct wlr_output_layout_output *lo) { +void wlr_scene_output_layout_add_output(struct wlr_scene_output_layout *sol, + struct wlr_output_layout_output *lo, struct wlr_scene_output *so) { struct wlr_scene_output_layout_output *solo = calloc(1, sizeof(*solo)); if (solo == NULL) { return; } - solo->scene_output = wlr_scene_output_create(sol->scene, lo->output); - if (solo->scene_output == NULL) { - free(solo); - return; - } - + solo->scene_output = so; solo->layout_output = lo; solo->layout_output_destroy.notify = @@ -101,15 +94,6 @@ static void scene_output_layout_add(struct wlr_scene_output_layout *sol, wlr_scene_output_set_position(solo->scene_output, lo->x, lo->y); } -static void scene_output_layout_handle_layout_add( - struct wl_listener *listener, void *data) { - struct wlr_scene_output_layout *sol = - wl_container_of(listener, sol, layout_add); - struct wlr_output_layout_output *lo = data; - - scene_output_layout_add(sol, lo); -} - static void scene_output_layout_handle_layout_destroy( struct wl_listener *listener, void *data) { struct wlr_scene_output_layout *sol = @@ -124,11 +108,11 @@ static void scene_output_layout_handle_scene_destroy( scene_output_layout_destroy(sol); } -bool wlr_scene_attach_output_layout(struct wlr_scene *scene, +struct wlr_scene_output_layout *wlr_scene_attach_output_layout(struct wlr_scene *scene, struct wlr_output_layout *output_layout) { struct wlr_scene_output_layout *sol = calloc(1, sizeof(*sol)); if (sol == NULL) { - return false; + return NULL; } sol->scene = scene; @@ -142,16 +126,8 @@ bool wlr_scene_attach_output_layout(struct wlr_scene *scene, sol->layout_change.notify = scene_output_layout_handle_layout_change; wl_signal_add(&output_layout->events.change, &sol->layout_change); - sol->layout_add.notify = scene_output_layout_handle_layout_add; - wl_signal_add(&output_layout->events.add, &sol->layout_add); - sol->scene_destroy.notify = scene_output_layout_handle_scene_destroy; wl_signal_add(&scene->tree.node.events.destroy, &sol->scene_destroy); - struct wlr_output_layout_output *lo; - wl_list_for_each(lo, &output_layout->outputs, link) { - scene_output_layout_add(sol, lo); - } - - return true; + return sol; }