aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-08-18 10:29:46 -0400
committerLibravatar GitHub <noreply@github.com>2018-08-18 10:29:46 -0400
commit744724b3cb28c2ee9d265dcbf78b1cbf2b2e3fef (patch)
tree7a5ebeae1d5e15f047f09698978fa84f61756faa /sway/tree
parentMerge pull request #2460 from RyanDwyer/implement-mousedown (diff)
parentImplement iterators per container type (diff)
downloadsway-744724b3cb28c2ee9d265dcbf78b1cbf2b2e3fef.tar.gz
sway-744724b3cb28c2ee9d265dcbf78b1cbf2b2e3fef.tar.zst
sway-744724b3cb28c2ee9d265dcbf78b1cbf2b2e3fef.zip
Merge pull request #2473 from RyanDwyer/iterators-per-type
Implement iterators per container type
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/container.c62
-rw-r--r--sway/tree/output.c52
-rw-r--r--sway/tree/root.c78
-rw-r--r--sway/tree/view.c6
-rw-r--r--sway/tree/workspace.c71
5 files changed, 215 insertions, 54 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 337245fd..1ceae175 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -432,8 +432,10 @@ struct sway_container *container_close(struct sway_container *con) {
432 432
433 if (con->type == C_VIEW) { 433 if (con->type == C_VIEW) {
434 view_close(con->sway_view); 434 view_close(con->sway_view);
435 } else { 435 } else if (con->type == C_CONTAINER) {
436 container_for_each_descendant(con, container_close_func, NULL); 436 container_for_each_child(con, container_close_func, NULL);
437 } else if (con->type == C_WORKSPACE) {
438 workspace_for_each_container(con, container_close_func, NULL);
437 } 439 }
438 440
439 return parent; 441 return parent;
@@ -465,23 +467,12 @@ struct sway_container *container_view_create(struct sway_container *sibling,
465 return swayc; 467 return swayc;
466} 468}
467 469
468void container_descendants(struct sway_container *root, 470struct sway_container *container_find_child(struct sway_container *container,
469 enum sway_container_type type,
470 void (*func)(struct sway_container *item, void *data), void *data) {
471 if (!root->children || !root->children->length) {
472 return;
473 }
474 for (int i = 0; i < root->children->length; ++i) {
475 struct sway_container *item = root->children->items[i];
476 if (item->type == type) {
477 func(item, data);
478 }
479 container_descendants(item, type, func, data);
480 }
481}
482
483struct sway_container *container_find(struct sway_container *container,
484 bool (*test)(struct sway_container *view, void *data), void *data) { 471 bool (*test)(struct sway_container *view, void *data), void *data) {
472 if (!sway_assert(container->type == C_CONTAINER ||
473 container->type == C_VIEW, "Expected a container or view")) {
474 return NULL;
475 }
485 if (!container->children) { 476 if (!container->children) {
486 return NULL; 477 return NULL;
487 } 478 }
@@ -489,15 +480,11 @@ struct sway_container *container_find(struct sway_container *container,
489 struct sway_container *child = container->children->items[i]; 480 struct sway_container *child = container->children->items[i];
490 if (test(child, data)) { 481 if (test(child, data)) {
491 return child; 482 return child;
492 } else {
493 struct sway_container *res = container_find(child, test, data);
494 if (res) {
495 return res;
496 }
497 } 483 }
498 } 484 struct sway_container *res = container_find_child(child, test, data);
499 if (container->type == C_WORKSPACE) { 485 if (res) {
500 return container_find(container->sway_workspace->floating, test, data); 486 return res;
487 }
501 } 488 }
502 return NULL; 489 return NULL;
503} 490}
@@ -743,26 +730,20 @@ struct sway_container *container_at(struct sway_container *workspace,
743 return NULL; 730 return NULL;
744} 731}
745 732
746void container_for_each_descendant(struct sway_container *container, 733void container_for_each_child(struct sway_container *container,
747 void (*f)(struct sway_container *container, void *data), 734 void (*f)(struct sway_container *container, void *data),
748 void *data) { 735 void *data) {
749 if (!container) { 736 if (!sway_assert(container->type == C_CONTAINER ||
737 container->type == C_VIEW, "Expected a container or view")) {
750 return; 738 return;
751 } 739 }
740 f(container, data);
752 if (container->children) { 741 if (container->children) {
753 for (int i = 0; i < container->children->length; ++i) { 742 for (int i = 0; i < container->children->length; ++i) {
754 struct sway_container *child = container->children->items[i]; 743 struct sway_container *child = container->children->items[i];
755 container_for_each_descendant(child, f, data); 744 container_for_each_child(child, f, data);
756 } 745 }
757 } 746 }
758 if (container->type == C_WORKSPACE) {
759 struct sway_container *floating = container->sway_workspace->floating;
760 for (int i = 0; i < floating->children->length; ++i) {
761 struct sway_container *child = floating->children->items[i];
762 container_for_each_descendant(child, f, data);
763 }
764 }
765 f(container, data);
766} 747}
767 748
768bool container_has_ancestor(struct sway_container *descendant, 749bool container_has_ancestor(struct sway_container *descendant,
@@ -1198,13 +1179,12 @@ void container_set_dirty(struct sway_container *container) {
1198 list_add(server.dirty_containers, container); 1179 list_add(server.dirty_containers, container);
1199} 1180}
1200 1181
1201static bool find_urgent_iterator(struct sway_container *con, 1182static bool find_urgent_iterator(struct sway_container *con, void *data) {
1202 void *data) {
1203 return con->type == C_VIEW && view_is_urgent(con->sway_view); 1183 return con->type == C_VIEW && view_is_urgent(con->sway_view);
1204} 1184}
1205 1185
1206bool container_has_urgent_child(struct sway_container *container) { 1186bool container_has_urgent_child(struct sway_container *container) {
1207 return container_find(container, find_urgent_iterator, NULL); 1187 return container_find_child(container, find_urgent_iterator, NULL);
1208} 1188}
1209 1189
1210void container_end_mouse_operation(struct sway_container *container) { 1190void container_end_mouse_operation(struct sway_container *container) {
@@ -1236,7 +1216,7 @@ void container_set_fullscreen(struct sway_container *container, bool enable) {
1236 container_set_fullscreen(workspace->sway_workspace->fullscreen, false); 1216 container_set_fullscreen(workspace->sway_workspace->fullscreen, false);
1237 } 1217 }
1238 1218
1239 container_for_each_descendant(container, set_fullscreen_iterator, &enable); 1219 container_for_each_child(container, set_fullscreen_iterator, &enable);
1240 1220
1241 container->is_fullscreen = enable; 1221 container->is_fullscreen = enable;
1242 1222
diff --git a/sway/tree/output.c b/sway/tree/output.c
index ab955359..6da63064 100644
--- a/sway/tree/output.c
+++ b/sway/tree/output.c
@@ -103,6 +103,57 @@ struct sway_container *output_create(
103 return output; 103 return output;
104} 104}
105 105
106void output_for_each_workspace(struct sway_container *output,
107 void (*f)(struct sway_container *con, void *data), void *data) {
108 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) {
109 return;
110 }
111 for (int i = 0; i < output->children->length; ++i) {
112 struct sway_container *workspace = output->children->items[i];
113 f(workspace, data);
114 }
115}
116
117void output_for_each_container(struct sway_container *output,
118 void (*f)(struct sway_container *con, void *data), void *data) {
119 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) {
120 return;
121 }
122 for (int i = 0; i < output->children->length; ++i) {
123 struct sway_container *workspace = output->children->items[i];
124 workspace_for_each_container(workspace, f, data);
125 }
126}
127
128struct sway_container *output_find_workspace(struct sway_container *output,
129 bool (*test)(struct sway_container *con, void *data), void *data) {
130 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) {
131 return NULL;
132 }
133 for (int i = 0; i < output->children->length; ++i) {
134 struct sway_container *workspace = output->children->items[i];
135 if (test(workspace, data)) {
136 return workspace;
137 }
138 }
139 return NULL;
140}
141
142struct sway_container *output_find_container(struct sway_container *output,
143 bool (*test)(struct sway_container *con, void *data), void *data) {
144 if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) {
145 return NULL;
146 }
147 struct sway_container *result = NULL;
148 for (int i = 0; i < output->children->length; ++i) {
149 struct sway_container *workspace = output->children->items[i];
150 if ((result = workspace_find_container(workspace, test, data))) {
151 return result;
152 }
153 }
154 return NULL;
155}
156
106static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { 157static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
107 struct sway_container *a = *(void **)_a; 158 struct sway_container *a = *(void **)_a;
108 struct sway_container *b = *(void **)_b; 159 struct sway_container *b = *(void **)_b;
@@ -122,4 +173,3 @@ static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
122void output_sort_workspaces(struct sway_container *output) { 173void output_sort_workspaces(struct sway_container *output) {
123 list_stable_sort(output->children, sort_workspace_cmp_qsort); 174 list_stable_sort(output->children, sort_workspace_cmp_qsort);
124} 175}
125
diff --git a/sway/tree/root.c b/sway/tree/root.c
index fc908cc1..8d8f42dc 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -256,3 +256,81 @@ void root_record_workspace_pid(pid_t pid) {
256 &pw->output_destroy); 256 &pw->output_destroy);
257 wl_list_insert(&pid_workspaces, &pw->link); 257 wl_list_insert(&pid_workspaces, &pw->link);
258} 258}
259
260void root_for_each_workspace(void (*f)(struct sway_container *con, void *data),
261 void *data) {
262 for (int i = 0; i < root_container.children->length; ++i) {
263 struct sway_container *output = root_container.children->items[i];
264 output_for_each_workspace(output, f, data);
265 }
266}
267
268void root_for_each_container(void (*f)(struct sway_container *con, void *data),
269 void *data) {
270 for (int i = 0; i < root_container.children->length; ++i) {
271 struct sway_container *output = root_container.children->items[i];
272 output_for_each_container(output, f, data);
273 }
274
275 // Scratchpad
276 for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) {
277 struct sway_container *container =
278 root_container.sway_root->scratchpad->items[i];
279 // If the container has a parent then it's visible on a workspace
280 // and will have been iterated in the previous for loop. So we only
281 // iterate the hidden scratchpad containers here.
282 if (!container->parent) {
283 f(container, data);
284 container_for_each_child(container, f, data);
285 }
286 }
287}
288
289struct sway_container *root_find_output(
290 bool (*test)(struct sway_container *con, void *data), void *data) {
291 for (int i = 0; i < root_container.children->length; ++i) {
292 struct sway_container *output = root_container.children->items[i];
293 if (test(output, data)) {
294 return output;
295 }
296 }
297 return NULL;
298}
299
300struct sway_container *root_find_workspace(
301 bool (*test)(struct sway_container *con, void *data), void *data) {
302 struct sway_container *result = NULL;
303 for (int i = 0; i < root_container.children->length; ++i) {
304 struct sway_container *output = root_container.children->items[i];
305 if ((result = output_find_workspace(output, test, data))) {
306 return result;
307 }
308 }
309 return NULL;
310}
311
312struct sway_container *root_find_container(
313 bool (*test)(struct sway_container *con, void *data), void *data) {
314 struct sway_container *result = NULL;
315 for (int i = 0; i < root_container.children->length; ++i) {
316 struct sway_container *output = root_container.children->items[i];
317 if ((result = output_find_container(output, test, data))) {
318 return result;
319 }
320 }
321
322 // Scratchpad
323 for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) {
324 struct sway_container *container =
325 root_container.sway_root->scratchpad->items[i];
326 if (!container->parent) {
327 if (test(container, data)) {
328 return container;
329 }
330 if ((result = container_find_child(container, test, data))) {
331 return result;
332 }
333 }
334 }
335 return NULL;
336}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 950494d8..4495c150 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -899,8 +899,8 @@ static bool find_by_mark_iterator(struct sway_container *con,
899} 899}
900 900
901struct sway_view *view_find_mark(char *mark) { 901struct sway_view *view_find_mark(char *mark) {
902 struct sway_container *container = container_find(&root_container, 902 struct sway_container *container = root_find_container(
903 find_by_mark_iterator, mark); 903 find_by_mark_iterator, mark);
904 if (!container) { 904 if (!container) {
905 return NULL; 905 return NULL;
906 } 906 }
@@ -908,7 +908,7 @@ struct sway_view *view_find_mark(char *mark) {
908} 908}
909 909
910bool view_find_and_unmark(char *mark) { 910bool view_find_and_unmark(char *mark) {
911 struct sway_container *container = container_find(&root_container, 911 struct sway_container *container = root_find_container(
912 find_by_mark_iterator, mark); 912 find_by_mark_iterator, mark);
913 if (!container) { 913 if (!container) {
914 return false; 914 return false;
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 1c0e6515..b7090de6 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -244,8 +244,7 @@ struct sway_container *workspace_by_number(const char* name) {
244 if (wbnd.len <= 0) { 244 if (wbnd.len <= 0) {
245 return NULL; 245 return NULL;
246 } 246 }
247 return container_find(&root_container, 247 return root_find_workspace(_workspace_by_number, (void *) &wbnd);
248 _workspace_by_number, (void *) &wbnd);
249} 248}
250 249
251static bool _workspace_by_name(struct sway_container *view, void *data) { 250static bool _workspace_by_name(struct sway_container *view, void *data) {
@@ -274,11 +273,11 @@ struct sway_container *workspace_by_name(const char *name) {
274 } else if (strcmp(name, "current") == 0) { 273 } else if (strcmp(name, "current") == 0) {
275 return current_workspace; 274 return current_workspace;
276 } else if (strcasecmp(name, "back_and_forth") == 0) { 275 } else if (strcasecmp(name, "back_and_forth") == 0) {
277 return prev_workspace_name ? container_find(&root_container, 276 return prev_workspace_name ?
278 _workspace_by_name, (void *)prev_workspace_name) : NULL; 277 root_find_workspace(_workspace_by_name, (void*)prev_workspace_name)
278 : NULL;
279 } else { 279 } else {
280 return container_find(&root_container, _workspace_by_name, 280 return root_find_workspace(_workspace_by_name, (void*)name);
281 (void *)name);
282 } 281 }
283} 282}
284 283
@@ -518,8 +517,7 @@ struct sway_container *workspace_output_get_highest_available(
518 continue; 517 continue;
519 } 518 }
520 519
521 struct sway_container *output = container_find(&root_container, 520 struct sway_container *output = root_find_output(_output_by_name, name);
522 _output_by_name, name);
523 if (output) { 521 if (output) {
524 return output; 522 return output;
525 } 523 }
@@ -528,8 +526,13 @@ struct sway_container *workspace_output_get_highest_available(
528 return NULL; 526 return NULL;
529} 527}
530 528
529static bool find_urgent_iterator(struct sway_container *con, void *data) {
530 return con->type == C_VIEW && view_is_urgent(con->sway_view);
531}
532
531void workspace_detect_urgent(struct sway_container *workspace) { 533void workspace_detect_urgent(struct sway_container *workspace) {
532 bool new_urgent = container_has_urgent_child(workspace); 534 bool new_urgent = (bool)workspace_find_container(workspace,
535 find_urgent_iterator, NULL);
533 536
534 if (workspace->sway_workspace->urgent != new_urgent) { 537 if (workspace->sway_workspace->urgent != new_urgent) {
535 workspace->sway_workspace->urgent = new_urgent; 538 workspace->sway_workspace->urgent = new_urgent;
@@ -538,6 +541,56 @@ void workspace_detect_urgent(struct sway_container *workspace) {
538 } 541 }
539} 542}
540 543
544void workspace_for_each_container(struct sway_container *ws,
545 void (*f)(struct sway_container *con, void *data), void *data) {
546 if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) {
547 return;
548 }
549 // Tiling
550 for (int i = 0; i < ws->children->length; ++i) {
551 struct sway_container *container = ws->children->items[i];
552 f(container, data);
553 container_for_each_child(container, f, data);
554 }
555 // Floating
556 for (int i = 0; i < ws->sway_workspace->floating->children->length; ++i) {
557 struct sway_container *container =
558 ws->sway_workspace->floating->children->items[i];
559 f(container, data);
560 container_for_each_child(container, f, data);
561 }
562}
563
564struct sway_container *workspace_find_container(struct sway_container *ws,
565 bool (*test)(struct sway_container *con, void *data), void *data) {
566 if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) {
567 return NULL;
568 }
569 struct sway_container *result = NULL;
570 // Tiling
571 for (int i = 0; i < ws->children->length; ++i) {
572 struct sway_container *child = ws->children->items[i];
573 if (test(child, data)) {
574 return child;
575 }
576 if ((result = container_find_child(child, test, data))) {
577 return result;
578 }
579 }
580 // Floating
581 for (int i = 0; i < ws->sway_workspace->floating->children->length; ++i) {
582 struct sway_container *child =
583 ws->sway_workspace->floating->children->items[i];
584 if (test(child, data)) {
585 return child;
586 }
587 if ((result = container_find_child(child, test, data))) {
588 return result;
589 }
590 }
591 return NULL;
592}
593
541struct sway_container *workspace_wrap_children(struct sway_container *ws) { 594struct sway_container *workspace_wrap_children(struct sway_container *ws) {
542 struct sway_container *middle = container_create(C_CONTAINER); 595 struct sway_container *middle = container_create(C_CONTAINER);
543 middle->layout = ws->layout; 596 middle->layout = ws->layout;