aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/container.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-03-29 23:41:33 -0400
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-03-29 23:41:33 -0400
commitdc8c9fbeb664518c76066cc28ee29452c6c30128 (patch)
tree88c2de0d08e00b2a30cb20cdfadfa6e53f5c59b4 /sway/tree/container.c
parentMerge pull request #1653 from swaywm/revert-1647-refactor-tree (diff)
downloadsway-dc8c9fbeb664518c76066cc28ee29452c6c30128.tar.gz
sway-dc8c9fbeb664518c76066cc28ee29452c6c30128.tar.zst
sway-dc8c9fbeb664518c76066cc28ee29452c6c30128.zip
Revert "Merge pull request #1653 from swaywm/revert-1647-refactor-tree"
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c221
1 files changed, 104 insertions, 117 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index bbafe9ec..40047dcf 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -7,14 +7,14 @@
7#include <wlr/types/wlr_output_layout.h> 7#include <wlr/types/wlr_output_layout.h>
8#include <wlr/types/wlr_wl_shell.h> 8#include <wlr/types/wlr_wl_shell.h>
9#include "sway/config.h" 9#include "sway/config.h"
10#include "sway/container.h" 10#include "sway/tree/container.h"
11#include "sway/input/input-manager.h" 11#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 12#include "sway/input/seat.h"
13#include "sway/layout.h" 13#include "sway/tree/layout.h"
14#include "sway/output.h" 14#include "sway/output.h"
15#include "sway/server.h" 15#include "sway/server.h"
16#include "sway/view.h" 16#include "sway/tree/view.h"
17#include "sway/workspace.h" 17#include "sway/tree/workspace.h"
18#include "sway/ipc-server.h" 18#include "sway/ipc-server.h"
19#include "log.h" 19#include "log.h"
20 20
@@ -33,48 +33,15 @@ static list_t *get_bfs_queue() {
33 return bfs_queue; 33 return bfs_queue;
34} 34}
35 35
36static void notify_new_container(swayc_t *container) { 36static void notify_new_container(struct sway_container *container) {
37 wl_signal_emit(&root_container.sway_root->events.new_container, container); 37 wl_signal_emit(&root_container.sway_root->events.new_container, container);
38 ipc_event_window(container, "new"); 38 ipc_event_window(container, "new");
39} 39}
40 40
41swayc_t *swayc_by_test(swayc_t *container, 41static struct sway_container *container_create(enum sway_container_type type) {
42 bool (*test)(swayc_t *view, void *data), void *data) {
43 if (!container->children) {
44 return NULL;
45 }
46 // TODO: floating windows
47 for (int i = 0; i < container->children->length; ++i) {
48 swayc_t *child = container->children->items[i];
49 if (test(child, data)) {
50 return child;
51 } else {
52 swayc_t *res = swayc_by_test(child, test, data);
53 if (res) {
54 return res;
55 }
56 }
57 }
58 return NULL;
59}
60
61void swayc_descendants_of_type(swayc_t *root, enum swayc_types type,
62 void (*func)(swayc_t *item, void *data), void *data) {
63 for (int i = 0; i < root->children->length; ++i) {
64 swayc_t *item = root->children->items[i];
65 if (item->type == type) {
66 func(item, data);
67 }
68 if (item->children && item->children->length) {
69 swayc_descendants_of_type(item, type, func, data);
70 }
71 }
72}
73
74static swayc_t *new_swayc(enum swayc_types type) {
75 // next id starts at 1 because 0 is assigned to root_container in layout.c 42 // next id starts at 1 because 0 is assigned to root_container in layout.c
76 static size_t next_id = 1; 43 static size_t next_id = 1;
77 swayc_t *c = calloc(1, sizeof(swayc_t)); 44 struct sway_container *c = calloc(1, sizeof(struct sway_container));
78 if (!c) { 45 if (!c) {
79 return NULL; 46 return NULL;
80 } 47 }
@@ -82,8 +49,6 @@ static swayc_t *new_swayc(enum swayc_types type) {
82 c->layout = L_NONE; 49 c->layout = L_NONE;
83 c->workspace_layout = L_NONE; 50 c->workspace_layout = L_NONE;
84 c->type = type; 51 c->type = type;
85 c->nb_master = 1;
86 c->nb_slave_groups = 1;
87 if (type != C_VIEW) { 52 if (type != C_VIEW) {
88 c->children = create_list(); 53 c->children = create_list();
89 } 54 }
@@ -93,18 +58,18 @@ static swayc_t *new_swayc(enum swayc_types type) {
93 return c; 58 return c;
94} 59}
95 60
96static void free_swayc(swayc_t *cont) { 61static void container_destroy(struct sway_container *cont) {
97 if (!sway_assert(cont, "free_swayc passed NULL")) { 62 if (cont == NULL) {
98 return; 63 return;
99 } 64 }
100 65
101 wl_signal_emit(&cont->events.destroy, cont); 66 wl_signal_emit(&cont->events.destroy, cont);
102 67
103 if (cont->children) { 68 if (cont->children) {
104 // remove children until there are no more, free_swayc calls 69 // remove children until there are no more, container_destroy calls
105 // remove_child, which removes child from this container 70 // container_remove_child, which removes child from this container
106 while (cont->children->length) { 71 while (cont->children->length) {
107 free_swayc(cont->children->items[0]); 72 container_destroy(cont->children->items[0]);
108 } 73 }
109 list_free(cont->children); 74 list_free(cont->children);
110 } 75 }
@@ -113,7 +78,7 @@ static void free_swayc(swayc_t *cont) {
113 list_free(cont->marks); 78 list_free(cont->marks);
114 } 79 }
115 if (cont->parent) { 80 if (cont->parent) {
116 remove_child(cont); 81 container_remove_child(cont);
117 } 82 }
118 if (cont->name) { 83 if (cont->name) {
119 free(cont->name); 84 free(cont->name);
@@ -121,7 +86,8 @@ static void free_swayc(swayc_t *cont) {
121 free(cont); 86 free(cont);
122} 87}
123 88
124swayc_t *new_output(struct sway_output *sway_output) { 89struct sway_container *container_output_create(
90 struct sway_output *sway_output) {
125 struct wlr_box size; 91 struct wlr_box size;
126 wlr_output_effective_resolution(sway_output->wlr_output, &size.width, 92 wlr_output_effective_resolution(sway_output->wlr_output, &size.width,
127 &size.height); 93 &size.height);
@@ -156,22 +122,22 @@ swayc_t *new_output(struct sway_output *sway_output) {
156 return NULL; 122 return NULL;
157 } 123 }
158 124
159 swayc_t *output = new_swayc(C_OUTPUT); 125 struct sway_container *output = container_create(C_OUTPUT);
160 output->sway_output = sway_output; 126 output->sway_output = sway_output;
161 output->name = strdup(name); 127 output->name = strdup(name);
162 if (output->name == NULL) { 128 if (output->name == NULL) {
163 free_swayc(output); 129 container_destroy(output);
164 return NULL; 130 return NULL;
165 } 131 }
166 132
167 apply_output_config(oc, output); 133 apply_output_config(oc, output);
168 134
169 add_child(&root_container, output); 135 container_add_child(&root_container, output);
170 136
171 // Create workspace 137 // Create workspace
172 char *ws_name = workspace_next_name(output->name); 138 char *ws_name = workspace_next_name(output->name);
173 wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); 139 wlr_log(L_DEBUG, "Creating default workspace %s", ws_name);
174 swayc_t *ws = new_workspace(output, ws_name); 140 struct sway_container *ws = container_workspace_create(output, ws_name);
175 // Set each seat's focus if not already set 141 // Set each seat's focus if not already set
176 struct sway_seat *seat = NULL; 142 struct sway_seat *seat = NULL;
177 wl_list_for_each(seat, &input_manager->seats, link) { 143 wl_list_for_each(seat, &input_manager->seats, link) {
@@ -185,12 +151,14 @@ swayc_t *new_output(struct sway_output *sway_output) {
185 return output; 151 return output;
186} 152}
187 153
188swayc_t *new_workspace(swayc_t *output, const char *name) { 154struct sway_container *container_workspace_create(
189 if (!sway_assert(output, "new_workspace called with null output")) { 155 struct sway_container *output, const char *name) {
156 if (!sway_assert(output,
157 "container_workspace_create called with null output")) {
190 return NULL; 158 return NULL;
191 } 159 }
192 wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); 160 wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name);
193 swayc_t *workspace = new_swayc(C_WORKSPACE); 161 struct sway_container *workspace = container_create(C_WORKSPACE);
194 162
195 workspace->x = output->x; 163 workspace->x = output->x;
196 workspace->y = output->y; 164 workspace->y = output->y;
@@ -198,21 +166,23 @@ swayc_t *new_workspace(swayc_t *output, const char *name) {
198 workspace->height = output->height; 166 workspace->height = output->height;
199 workspace->name = !name ? NULL : strdup(name); 167 workspace->name = !name ? NULL : strdup(name);
200 workspace->prev_layout = L_NONE; 168 workspace->prev_layout = L_NONE;
201 workspace->layout = default_layout(output); 169 workspace->layout = container_get_default_layout(output);
202 workspace->workspace_layout = default_layout(output); 170 workspace->workspace_layout = container_get_default_layout(output);
203 171
204 add_child(output, workspace); 172 container_add_child(output, workspace);
205 sort_workspaces(output); 173 container_sort_workspaces(output);
206 notify_new_container(workspace); 174 notify_new_container(workspace);
207 return workspace; 175 return workspace;
208} 176}
209 177
210swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) { 178struct sway_container *container_view_create(struct sway_container *sibling,
211 if (!sway_assert(sibling, "new_view called with NULL sibling/parent")) { 179 struct sway_view *sway_view) {
180 if (!sway_assert(sibling,
181 "container_view_create called with NULL sibling/parent")) {
212 return NULL; 182 return NULL;
213 } 183 }
214 const char *title = view_get_title(sway_view); 184 const char *title = view_get_title(sway_view);
215 swayc_t *swayc = new_swayc(C_VIEW); 185 struct sway_container *swayc = container_create(C_VIEW);
216 wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s", 186 wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s",
217 swayc, title, sibling, sibling ? sibling->type : 0, sibling->name); 187 swayc, title, sibling, sibling ? sibling->type : 0, sibling->name);
218 // Setup values 188 // Setup values
@@ -223,17 +193,18 @@ swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) {
223 193
224 if (sibling->type == C_WORKSPACE) { 194 if (sibling->type == C_WORKSPACE) {
225 // Case of focused workspace, just create as child of it 195 // Case of focused workspace, just create as child of it
226 add_child(sibling, swayc); 196 container_add_child(sibling, swayc);
227 } else { 197 } else {
228 // Regular case, create as sibling of current container 198 // Regular case, create as sibling of current container
229 add_sibling(sibling, swayc); 199 container_add_sibling(sibling, swayc);
230 } 200 }
231 notify_new_container(swayc); 201 notify_new_container(swayc);
232 return swayc; 202 return swayc;
233} 203}
234 204
235swayc_t *destroy_output(swayc_t *output) { 205struct sway_container *container_output_destroy(struct sway_container *output) {
236 if (!sway_assert(output, "null output passed to destroy_output")) { 206 if (!sway_assert(output,
207 "null output passed to container_output_destroy")) {
237 return NULL; 208 return NULL;
238 } 209 }
239 210
@@ -245,12 +216,13 @@ swayc_t *destroy_output(swayc_t *output) {
245 int p = root_container.children->items[0] == output; 216 int p = root_container.children->items[0] == output;
246 // Move workspace from this output to another output 217 // Move workspace from this output to another output
247 while (output->children->length) { 218 while (output->children->length) {
248 swayc_t *child = output->children->items[0]; 219 struct sway_container *child = output->children->items[0];
249 remove_child(child); 220 container_remove_child(child);
250 add_child(root_container.children->items[p], child); 221 container_add_child(root_container.children->items[p], child);
251 } 222 }
252 sort_workspaces(root_container.children->items[p]); 223 container_sort_workspaces(root_container.children->items[p]);
253 arrange_windows(root_container.children->items[p], -1, -1); 224 arrange_windows(root_container.children->items[p],
225 -1, -1);
254 } 226 }
255 } 227 }
256 228
@@ -259,18 +231,18 @@ swayc_t *destroy_output(swayc_t *output) {
259 wl_list_remove(&output->sway_output->mode.link); 231 wl_list_remove(&output->sway_output->mode.link);
260 232
261 wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); 233 wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name);
262 free_swayc(output); 234 container_destroy(output);
263 235
264 return &root_container; 236 return &root_container;
265} 237}
266 238
267swayc_t *destroy_view(swayc_t *view) { 239struct sway_container *container_view_destroy(struct sway_container *view) {
268 if (!view) { 240 if (!view) {
269 return NULL; 241 return NULL;
270 } 242 }
271 wlr_log(L_DEBUG, "Destroying view '%s'", view->name); 243 wlr_log(L_DEBUG, "Destroying view '%s'", view->name);
272 swayc_t *parent = view->parent; 244 struct sway_container *parent = view->parent;
273 free_swayc(view); 245 container_destroy(view);
274 246
275 // TODO WLR: Destroy empty containers 247 // TODO WLR: Destroy empty containers
276 /* 248 /*
@@ -281,7 +253,55 @@ swayc_t *destroy_view(swayc_t *view) {
281 return parent; 253 return parent;
282} 254}
283 255
284swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { 256struct sway_container *container_set_layout(struct sway_container *container,
257 enum sway_container_layout layout) {
258 if (container->type == C_WORKSPACE) {
259 container->workspace_layout = layout;
260 if (layout == L_HORIZ || layout == L_VERT) {
261 container->layout = layout;
262 }
263 } else {
264 container->layout = layout;
265 }
266 return container;
267}
268
269void container_descendents(struct sway_container *root,
270 enum sway_container_type type,
271 void (*func)(struct sway_container *item, void *data), void *data) {
272 for (int i = 0; i < root->children->length; ++i) {
273 struct sway_container *item = root->children->items[i];
274 if (item->type == type) {
275 func(item, data);
276 }
277 if (item->children && item->children->length) {
278 container_descendents(item, type, func, data);
279 }
280 }
281}
282
283struct sway_container *container_find(struct sway_container *container,
284 bool (*test)(struct sway_container *view, void *data), void *data) {
285 if (!container->children) {
286 return NULL;
287 }
288 // TODO: floating windows
289 for (int i = 0; i < container->children->length; ++i) {
290 struct sway_container *child = container->children->items[i];
291 if (test(child, data)) {
292 return child;
293 } else {
294 struct sway_container *res = container_find(child, test, data);
295 if (res) {
296 return res;
297 }
298 }
299 }
300 return NULL;
301}
302
303struct sway_container *container_parent(struct sway_container *container,
304 enum sway_container_type type) {
285 if (!sway_assert(container, "container is NULL")) { 305 if (!sway_assert(container, "container is NULL")) {
286 return NULL; 306 return NULL;
287 } 307 }
@@ -294,7 +314,8 @@ swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
294 return container; 314 return container;
295} 315}
296 316
297swayc_t *swayc_at(swayc_t *parent, double lx, double ly, 317struct sway_container *container_at(struct sway_container *parent,
318 double lx, double ly,
298 struct wlr_surface **surface, double *sx, double *sy) { 319 struct wlr_surface **surface, double *sx, double *sy) {
299 list_t *queue = get_bfs_queue(); 320 list_t *queue = get_bfs_queue();
300 if (!queue) { 321 if (!queue) {
@@ -303,13 +324,13 @@ swayc_t *swayc_at(swayc_t *parent, double lx, double ly,
303 324
304 list_add(queue, parent); 325 list_add(queue, parent);
305 326
306 swayc_t *swayc = NULL; 327 struct sway_container *swayc = NULL;
307 while (queue->length) { 328 while (queue->length) {
308 swayc = queue->items[0]; 329 swayc = queue->items[0];
309 list_del(queue, 0); 330 list_del(queue, 0);
310 if (swayc->type == C_VIEW) { 331 if (swayc->type == C_VIEW) {
311 struct sway_view *sview = swayc->sway_view; 332 struct sway_view *sview = swayc->sway_view;
312 swayc_t *soutput = swayc_parent_by_type(swayc, C_OUTPUT); 333 struct sway_container *soutput = container_parent(swayc, C_OUTPUT);
313 struct wlr_box *output_box = 334 struct wlr_box *output_box =
314 wlr_output_layout_get_box( 335 wlr_output_layout_get_box(
315 root_container.sway_root->output_layout, 336 root_container.sway_root->output_layout,
@@ -379,30 +400,8 @@ swayc_t *swayc_at(swayc_t *parent, double lx, double ly,
379 return NULL; 400 return NULL;
380} 401}
381 402
382void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 403void container_for_each_descendent(struct sway_container *con,
383 if (container) { 404 void (*f)(struct sway_container *con, void *data), void *data) {
384 int i;
385 if (container->children) {
386 for (i = 0; i < container->children->length; ++i) {
387 swayc_t *child = container->children->items[i];
388 container_map(child, f, data);
389 }
390 }
391 // TODO
392 /*
393 if (container->floating) {
394 for (i = 0; i < container->floating->length; ++i) {
395 swayc_t *child = container->floating->items[i];
396 container_map(child, f, data);
397 }
398 }
399 */
400 f(container, data);
401 }
402}
403
404void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data),
405 void *data) {
406 list_t *queue = get_bfs_queue(); 405 list_t *queue = get_bfs_queue();
407 if (!queue) { 406 if (!queue) {
408 return; 407 return;
@@ -415,7 +414,7 @@ void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data),
415 414
416 list_add(queue, con); 415 list_add(queue, con);
417 416
418 swayc_t *current = NULL; 417 struct sway_container *current = NULL;
419 while (queue->length) { 418 while (queue->length) {
420 current = queue->items[0]; 419 current = queue->items[0];
421 list_del(queue, 0); 420 list_del(queue, 0);
@@ -424,15 +423,3 @@ void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data),
424 list_cat(queue, current->children); 423 list_cat(queue, current->children);
425 } 424 }
426} 425}
427
428swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) {
429 if (container->type == C_WORKSPACE) {
430 container->workspace_layout = layout;
431 if (layout == L_HORIZ || layout == L_VERT) {
432 container->layout = layout;
433 }
434 } else {
435 container->layout = layout;
436 }
437 return container;
438}