aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/node.c
blob: ffa7f2cc8940ac470b99783dc407cce38ba58a1f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#define _POSIX_C_SOURCE 200809L
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/container.h"
#include "sway/tree/node.h"
#include "sway/tree/root.h"
#include "sway/tree/workspace.h"
#include "log.h"

void node_init(struct sway_node *node, enum sway_node_type type, void *thing) {
	static size_t next_id = 1;
	node->id = next_id++;
	node->type = type;
	node->sway_root = thing;
	wl_signal_init(&node->events.destroy);
}

const char *node_type_to_str(enum sway_node_type type) {
	switch (type) {
	case N_ROOT:
		return "N_ROOT";
	case N_OUTPUT:
		return "N_OUTPUT";
	case N_WORKSPACE:
		return "N_WORKSPACE";
	case N_CONTAINER:
		return "N_CONTAINER";
	}
	return "";
}

void node_set_dirty(struct sway_node *node) {
	if (node->dirty) {
		return;
	}
	node->dirty = true;
	list_add(server.dirty_nodes, node);
}

bool node_is_view(struct sway_node *node) {
	return node->type == N_CONTAINER && node->sway_container->view;
}

char *node_get_name(struct sway_node *node) {
	switch (node->type) {
	case N_ROOT:
		return "root";
	case N_OUTPUT:
		return node->sway_output->wlr_output->name;
	case N_WORKSPACE:
		return node->sway_workspace->name;
	case N_CONTAINER:
		return node->sway_container->title;
	}
	return NULL;
}

void node_get_box(struct sway_node *node, struct wlr_box *box) {
	switch (node->type) {
	case N_ROOT:
		root_get_box(root, box);
		break;
	case N_OUTPUT:
		output_get_box(node->sway_output, box);
		break;
	case N_WORKSPACE:
		workspace_get_box(node->sway_workspace, box);
		break;
	case N_CONTAINER:
		container_get_box(node->sway_container, box);
		break;
	}
}

struct sway_output *node_get_output(struct sway_node *node) {
	switch (node->type) {
	case N_CONTAINER: {
		struct sway_workspace *ws = node->sway_container->workspace;
		return ws ? ws->output : NULL;
    }
	case N_WORKSPACE:
		return node->sway_workspace->output;
	case N_OUTPUT:
		return node->sway_output;
	case N_ROOT:
		return NULL;
	}
	return NULL;
}

enum sway_container_layout node_get_layout(struct sway_node *node) {
	switch (node->type) {
	case N_CONTAINER:
		return node->sway_container->layout;
	case N_WORKSPACE:
		return node->sway_workspace->layout;
	case N_OUTPUT:
	case N_ROOT:
		return L_NONE;
	}
	return L_NONE;
}

struct sway_node *node_get_parent(struct sway_node *node) {
	switch (node->type) {
	case N_CONTAINER: {
			struct sway_container *con = node->sway_container;
			if (con->parent) {
				return &con->parent->node;
			}
			if (con->workspace) {
				return &con->workspace->node;
			}
		}
		return NULL;
	case N_WORKSPACE: {
			struct sway_workspace *ws = node->sway_workspace;
			if (ws->output) {
				return &ws->output->node;
			}
		}
		return NULL;
	case N_OUTPUT:
		return &root->node;
	case N_ROOT:
		return NULL;
	}
	return NULL;
}

list_t *node_get_children(struct sway_node *node) {
	switch (node->type) {
	case N_CONTAINER:
		return node->sway_container->children;
	case N_WORKSPACE:
		return node->sway_workspace->tiling;
	case N_OUTPUT:
	case N_ROOT:
		return NULL;
	}
	return NULL;
}

bool node_has_ancestor(struct sway_node *node, struct sway_node *ancestor) {
	if (ancestor->type == N_ROOT && node->type == N_CONTAINER &&
			node->sway_container->fullscreen_mode == FULLSCREEN_GLOBAL) {
		return true;
	}
	struct sway_node *parent = node_get_parent(node);
	while (parent) {
		if (parent == ancestor) {
			return true;
		}
		if (ancestor->type == N_ROOT && parent->type == N_CONTAINER &&
				parent->sway_container->fullscreen_mode == FULLSCREEN_GLOBAL) {
			return true;
		}
		parent = node_get_parent(parent);
	}
	return false;
}