aboutsummaryrefslogtreecommitdiff
path: root/sway/tree/container.c
diff options
context:
space:
mode:
authorAlexander Orzechowski <alex@ozal.ski>2024-01-18 10:00:45 -0500
committerKirill Primak <vyivel@eclair.cafe>2024-01-18 18:36:54 +0300
commit1eb16d136774c8fb3c9085df45156264f0db8814 (patch)
tree9c348ab37edae50b76a388d7e8d8dcd011cea33b /sway/tree/container.c
parentdbd2fbf4301d441be4f9a04a1df6d93c81c361f6 (diff)
scene_graph: Maintain `wlr_scene_node`s for the sway tree.
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c74
1 files changed, 71 insertions, 3 deletions
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);
}