From 1eb16d136774c8fb3c9085df45156264f0db8814 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Thu, 18 Jan 2024 10:00:45 -0500 Subject: scene_graph: Maintain `wlr_scene_node`s for the sway tree. --- sway/tree/container.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 8c344a6d..9ed08929 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -27,6 +27,24 @@ #include "log.h" #include "stringop.h" +static struct wlr_scene_rect *alloc_rect_node(struct wlr_scene_tree *parent, + bool *failed) { + if (*failed) { + return NULL; + } + + // just pass in random values. These will be overwritten when + // they need to be used. + struct wlr_scene_rect *rect = wlr_scene_rect_create( + parent, 0, 0, (float[4]){0.f, 0.f, 0.f, 1.f}); + if (!rect) { + sway_log(SWAY_ERROR, "Failed to allocate a wlr_scene_rect"); + *failed = true; + } + + return rect; +} + struct sway_container *container_create(struct sway_view *view) { struct sway_container *c = calloc(1, sizeof(struct sway_container)); if (!c) { @@ -34,14 +52,62 @@ struct sway_container *container_create(struct sway_view *view) { return NULL; } node_init(&c->node, N_CONTAINER, c); - c->pending.layout = L_NONE; - c->view = view; - c->alpha = 1.0f; + + // Container tree structure + // - scene tree + // - title bar + // - border + // - background + // - title text + // - marks text + // - border + // - border top/bottom/left/right + // - content_tree (we put the content node here so when we disable the + // border everything gets disabled. We only render the content iff there + // is a border as well) + bool failed = false; + c->scene_tree = alloc_scene_tree(root->staging, &failed); + + c->title_bar.tree = alloc_scene_tree(c->scene_tree, &failed); + c->title_bar.border = alloc_scene_tree(c->title_bar.tree, &failed); + c->title_bar.background = alloc_scene_tree(c->title_bar.tree, &failed); + + // for opacity purposes we need to carfully create the scene such that + // none of our rect nodes as well as text buffers don't overlap. To do + // this we have to create rects such that they go around text buffers + for (int i = 0; i < 4; i++) { + alloc_rect_node(c->title_bar.border, &failed); + } + + for (int i = 0; i < 5; i++) { + alloc_rect_node(c->title_bar.background, &failed); + } + + c->border.tree = alloc_scene_tree(c->scene_tree, &failed); + c->content_tree = alloc_scene_tree(c->border.tree, &failed); + + if (view) { + // only containers with views can have borders + c->border.top = alloc_rect_node(c->border.tree, &failed); + c->border.bottom = alloc_rect_node(c->border.tree, &failed); + c->border.left = alloc_rect_node(c->border.tree, &failed); + c->border.right = alloc_rect_node(c->border.tree, &failed); + } + + if (failed) { + wlr_scene_node_destroy(&c->scene_tree->node); + free(c); + return NULL; + } if (!view) { c->pending.children = create_list(); c->current.children = create_list(); } + + c->pending.layout = L_NONE; + c->view = view; + c->alpha = 1.0f; c->marks = create_list(); c->outputs = create_list(); @@ -85,6 +151,8 @@ void container_destroy(struct sway_container *con) { } } + scene_node_disown_children(con->content_tree); + wlr_scene_node_destroy(&con->scene_tree->node); free(con); } -- cgit v1.2.3