aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-19 15:07:07 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-19 16:18:33 +1000
commit2b5a404ac920339a2b9ce32d4718272dee4668b9 (patch)
tree681f45a530a1f8d5966161291c3cb482e52edb6e /sway/tree
parentMerge pull request #2453 from ianyfan/commands (diff)
downloadsway-2b5a404ac920339a2b9ce32d4718272dee4668b9.tar.gz
sway-2b5a404ac920339a2b9ce32d4718272dee4668b9.tar.zst
sway-2b5a404ac920339a2b9ce32d4718272dee4668b9.zip
Replace hacky L_FLOATING container with a list
Workspaces previously had a magical `workspace->floating` container, which had a layout of L_FLOATING and whose children were actual floating views. This allowed some conveniences, but was a hacky solution because the container has to be exempt from focus, coordinate transactions with the workspace, and omit emitting IPC events (which we didn't do). This commit changes it to be a list directly in the sway_workspace. The L_FLOATING layout is no longer used so this has been removed as well. * Fixes incorrect check in the swap command (it checked if the containers had the L_FLOATING layout, but this layout applied to the magical container). * Introduces workspace_add_floating
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/arrange.c10
-rw-r--r--sway/tree/container.c54
-rw-r--r--sway/tree/layout.c29
-rw-r--r--sway/tree/root.c2
-rw-r--r--sway/tree/view.c6
-rw-r--r--sway/tree/workspace.c44
6 files changed, 68 insertions, 77 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 494a8461..cf4a5d9a 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -144,9 +144,9 @@ static void apply_tabbed_or_stacked_layout(struct sway_container *parent) {
144 144
145static void arrange_children_of(struct sway_container *parent); 145static void arrange_children_of(struct sway_container *parent);
146 146
147static void arrange_floating(struct sway_container *floating) { 147static void arrange_floating(list_t *floating) {
148 for (int i = 0; i < floating->children->length; ++i) { 148 for (int i = 0; i < floating->length; ++i) {
149 struct sway_container *floater = floating->children->items[i]; 149 struct sway_container *floater = floating->items[i];
150 if (floater->type == C_VIEW) { 150 if (floater->type == C_VIEW) {
151 view_autoconfigure(floater->sway_view); 151 view_autoconfigure(floater->sway_view);
152 } else { 152 } else {
@@ -154,7 +154,6 @@ static void arrange_floating(struct sway_container *floating) {
154 } 154 }
155 container_set_dirty(floater); 155 container_set_dirty(floater);
156 } 156 }
157 container_set_dirty(floating);
158} 157}
159 158
160static void arrange_children_of(struct sway_container *parent) { 159static void arrange_children_of(struct sway_container *parent) {
@@ -179,9 +178,6 @@ static void arrange_children_of(struct sway_container *parent) {
179 case L_NONE: 178 case L_NONE:
180 apply_horiz_layout(parent); 179 apply_horiz_layout(parent);
181 break; 180 break;
182 case L_FLOATING:
183 arrange_floating(parent);
184 break;
185 } 181 }
186 182
187 // Recurse into child containers 183 // Recurse into child containers
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 2a428ca5..ea20991c 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -67,7 +67,11 @@ void container_update_textures_recursive(struct sway_container *con) {
67 } 67 }
68 68
69 if (con->type == C_WORKSPACE) { 69 if (con->type == C_WORKSPACE) {
70 container_update_textures_recursive(con->sway_workspace->floating); 70 for (int i = 0; i < con->sway_workspace->floating->length; ++i) {
71 struct sway_container *floater =
72 con->sway_workspace->floating->items[i];
73 container_update_textures_recursive(floater);
74 }
71 } 75 }
72 } 76 }
73} 77}
@@ -131,6 +135,7 @@ struct sway_container *container_create(enum sway_container_type type) {
131static void container_workspace_free(struct sway_workspace *ws) { 135static void container_workspace_free(struct sway_workspace *ws) {
132 list_foreach(ws->output_priority, free); 136 list_foreach(ws->output_priority, free);
133 list_free(ws->output_priority); 137 list_free(ws->output_priority);
138 list_free(ws->floating);
134 free(ws); 139 free(ws);
135} 140}
136 141
@@ -222,15 +227,14 @@ static struct sway_container *container_workspace_destroy(
222 for (int i = 0; i < workspace->children->length; i++) { 227 for (int i = 0; i < workspace->children->length; i++) {
223 container_move_to(workspace->children->items[i], new_workspace); 228 container_move_to(workspace->children->items[i], new_workspace);
224 } 229 }
225 struct sway_container *floating = workspace->sway_workspace->floating; 230 list_t *floating = workspace->sway_workspace->floating;
226 for (int i = 0; i < floating->children->length; i++) { 231 for (int i = 0; i < floating->length; i++) {
227 container_move_to(floating->children->items[i], 232 struct sway_container *floater = floating->items[i];
228 new_workspace->sway_workspace->floating); 233 container_remove_child(floater);
234 workspace_add_floating(new_workspace, floater);
229 } 235 }
230 } 236 }
231 237
232 container_destroy_noreaping(workspace->sway_workspace->floating);
233
234 return output; 238 return output;
235} 239}
236 240
@@ -339,10 +343,6 @@ static struct sway_container *container_destroy_noreaping(
339} 343}
340 344
341bool container_reap_empty(struct sway_container *con) { 345bool container_reap_empty(struct sway_container *con) {
342 if (con->layout == L_FLOATING) {
343 // Don't reap the magical floating container that each workspace has
344 return false;
345 }
346 switch (con->type) { 346 switch (con->type) {
347 case C_ROOT: 347 case C_ROOT:
348 case C_OUTPUT: 348 case C_OUTPUT:
@@ -626,9 +626,8 @@ static struct sway_container *floating_container_at(double lx, double ly,
626 } 626 }
627 // Items at the end of the list are on top, so iterate the list in 627 // Items at the end of the list are on top, so iterate the list in
628 // reverse. 628 // reverse.
629 for (int k = ws->floating->children->length - 1; k >= 0; --k) { 629 for (int k = ws->floating->length - 1; k >= 0; --k) {
630 struct sway_container *floater = 630 struct sway_container *floater = ws->floating->items[k];
631 ws->floating->children->items[k];
632 struct wlr_box box = { 631 struct wlr_box box = {
633 .x = floater->x, 632 .x = floater->x,
634 .y = floater->y, 633 .y = floater->y,
@@ -664,9 +663,6 @@ struct sway_container *tiling_container_at(
664 return container_at_tabbed(con, lx, ly, surface, sx, sy); 663 return container_at_tabbed(con, lx, ly, surface, sx, sy);
665 case L_STACKED: 664 case L_STACKED:
666 return container_at_stacked(con, lx, ly, surface, sx, sy); 665 return container_at_stacked(con, lx, ly, surface, sx, sy);
667 case L_FLOATING:
668 sway_assert(false, "Didn't expect to see floating here");
669 return NULL;
670 case L_NONE: 666 case L_NONE:
671 return NULL; 667 return NULL;
672 } 668 }
@@ -880,9 +876,6 @@ static size_t get_tree_representation(struct sway_container *parent, char *buffe
880 case L_STACKED: 876 case L_STACKED:
881 lenient_strcat(buffer, "S["); 877 lenient_strcat(buffer, "S[");
882 break; 878 break;
883 case L_FLOATING:
884 lenient_strcat(buffer, "F[");
885 break;
886 case L_NONE: 879 case L_NONE:
887 lenient_strcat(buffer, "D["); 880 lenient_strcat(buffer, "D[");
888 break; 881 break;
@@ -1012,7 +1005,7 @@ void container_set_floating(struct sway_container *container, bool enable) {
1012 1005
1013 if (enable) { 1006 if (enable) {
1014 struct sway_container *old_parent = container_remove_child(container); 1007 struct sway_container *old_parent = container_remove_child(container);
1015 container_add_child(workspace->sway_workspace->floating, container); 1008 workspace_add_floating(workspace, container);
1016 container_init_floating(container); 1009 container_init_floating(container);
1017 if (container->type == C_VIEW) { 1010 if (container->type == C_VIEW) {
1018 view_set_tiled(container->sway_view, false); 1011 view_set_tiled(container->sway_view, false);
@@ -1069,11 +1062,8 @@ void container_set_geometry_from_floating_view(struct sway_container *con) {
1069} 1062}
1070 1063
1071bool container_is_floating(struct sway_container *container) { 1064bool container_is_floating(struct sway_container *container) {
1072 struct sway_container *workspace = container_parent(container, C_WORKSPACE); 1065 return container->parent && container->parent->type == C_WORKSPACE &&
1073 if (!workspace) { 1066 list_find(container->parent->sway_workspace->floating, container) != -1;
1074 return false;
1075 }
1076 return container->parent == workspace->sway_workspace->floating;
1077} 1067}
1078 1068
1079void container_get_box(struct sway_container *container, struct wlr_box *box) { 1069void container_get_box(struct sway_container *container, struct wlr_box *box) {
@@ -1153,7 +1143,7 @@ void container_floating_move_to(struct sway_container *con,
1153 output_get_active_workspace(new_output->sway_output); 1143 output_get_active_workspace(new_output->sway_output);
1154 if (old_workspace != new_workspace) { 1144 if (old_workspace != new_workspace) {
1155 container_remove_child(con); 1145 container_remove_child(con);
1156 container_add_child(new_workspace->sway_workspace->floating, con); 1146 workspace_add_floating(new_workspace, con);
1157 arrange_windows(old_workspace); 1147 arrange_windows(old_workspace);
1158 arrange_windows(new_workspace); 1148 arrange_windows(new_workspace);
1159 workspace_detect_urgent(old_workspace); 1149 workspace_detect_urgent(old_workspace);
@@ -1266,14 +1256,10 @@ void container_set_fullscreen(struct sway_container *container, bool enable) {
1266} 1256}
1267 1257
1268bool container_is_floating_or_child(struct sway_container *container) { 1258bool container_is_floating_or_child(struct sway_container *container) {
1269 do { 1259 while (container->parent && container->parent->type != C_WORKSPACE) {
1270 if (container->parent && container->parent->layout == L_FLOATING) {
1271 return true;
1272 }
1273 container = container->parent; 1260 container = container->parent;
1274 } while (container && container->type != C_WORKSPACE); 1261 }
1275 1262 return container_is_floating(container);
1276 return false;
1277} 1263}
1278 1264
1279bool container_is_fullscreen_or_child(struct sway_container *container) { 1265bool container_is_fullscreen_or_child(struct sway_container *container) {
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 49ec806e..2f22a3dd 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -117,9 +117,11 @@ struct sway_container *container_remove_child(struct sway_container *child) {
117 } 117 }
118 118
119 struct sway_container *parent = child->parent; 119 struct sway_container *parent = child->parent;
120 int index = index_child(child); 120 list_t *list = container_is_floating(child) ?
121 parent->sway_workspace->floating : parent->children;
122 int index = list_find(list, child);
121 if (index != -1) { 123 if (index != -1) {
122 list_del(parent->children, index); 124 list_del(list, index);
123 } 125 }
124 child->parent = NULL; 126 child->parent = NULL;
125 container_notify_subtree_changed(parent); 127 container_notify_subtree_changed(parent);
@@ -160,7 +162,8 @@ void container_move_to(struct sway_container *container,
160 struct sway_container *old_output = 162 struct sway_container *old_output =
161 container_parent(container, C_OUTPUT); 163 container_parent(container, C_OUTPUT);
162 old_parent = container_remove_child(container); 164 old_parent = container_remove_child(container);
163 container_add_child(new_ws->sway_workspace->floating, container); 165 workspace_add_floating(new_ws, container);
166 container_handle_fullscreen_reparent(container, old_parent);
164 // If changing output, center it within the workspace 167 // If changing output, center it within the workspace
165 if (old_output != new_ws->parent && !container->is_fullscreen) { 168 if (old_output != new_ws->parent && !container->is_fullscreen) {
166 container_floating_move_to_center(container); 169 container_floating_move_to_center(container);
@@ -431,9 +434,6 @@ void container_move(struct sway_container *container,
431 if ((index == parent->children->length - 1 && offs > 0) 434 if ((index == parent->children->length - 1 && offs > 0)
432 || (index == 0 && offs < 0)) { 435 || (index == 0 && offs < 0)) {
433 if (current->parent == container->parent) { 436 if (current->parent == container->parent) {
434 if (parent->parent->layout == L_FLOATING) {
435 return;
436 }
437 if (!parent->is_fullscreen && 437 if (!parent->is_fullscreen &&
438 (parent->layout == L_TABBED || 438 (parent->layout == L_TABBED ||
439 parent->layout == L_STACKED)) { 439 parent->layout == L_STACKED)) {
@@ -457,14 +457,10 @@ void container_move(struct sway_container *container,
457 sibling = parent->children->items[index + offs]; 457 sibling = parent->children->items[index + offs];
458 wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id); 458 wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id);
459 } 459 }
460 } else if (!parent->is_fullscreen && 460 } else if (!parent->is_fullscreen && (parent->layout == L_TABBED ||
461 parent->parent->layout != L_FLOATING &&
462 (parent->layout == L_TABBED ||
463 parent->layout == L_STACKED)) { 461 parent->layout == L_STACKED)) {
464 move_out_of_tabs_stacks(container, current, move_dir, offs); 462 move_out_of_tabs_stacks(container, current, move_dir, offs);
465 return; 463 return;
466 } else if (parent->parent->layout == L_FLOATING) {
467 return;
468 } else { 464 } else {
469 wlr_log(WLR_DEBUG, "Moving up to find a parallel container"); 465 wlr_log(WLR_DEBUG, "Moving up to find a parallel container");
470 current = current->parent; 466 current = current->parent;
@@ -802,13 +798,15 @@ struct sway_container *container_replace_child(struct sway_container *child,
802 if (parent == NULL) { 798 if (parent == NULL) {
803 return NULL; 799 return NULL;
804 } 800 }
805 int i = index_child(child);
806 801
807 // TODO floating 802 list_t *list = container_is_floating(child) ?
803 parent->sway_workspace->floating : parent->children;
804 int i = list_find(list, child);
805
808 if (new_child->parent) { 806 if (new_child->parent) {
809 container_remove_child(new_child); 807 container_remove_child(new_child);
810 } 808 }
811 parent->children->items[i] = new_child; 809 list->items[i] = new_child;
812 new_child->parent = parent; 810 new_child->parent = parent;
813 child->parent = NULL; 811 child->parent = NULL;
814 812
@@ -973,7 +971,8 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
973 "Cannot swap ancestor and descendant")) { 971 "Cannot swap ancestor and descendant")) {
974 return; 972 return;
975 } 973 }
976 if (!sway_assert(con1->layout != L_FLOATING && con2->layout != L_FLOATING, 974 if (!sway_assert(!container_is_floating(con1)
975 && !container_is_floating(con2),
977 "Swapping with floating containers is not supported")) { 976 "Swapping with floating containers is not supported")) {
978 return; 977 return;
979 } 978 }
diff --git a/sway/tree/root.c b/sway/tree/root.c
index 8d8f42dc..c27ff2c3 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -105,7 +105,7 @@ void root_scratchpad_show(struct sway_container *con) {
105 if (con->parent) { 105 if (con->parent) {
106 container_remove_child(con); 106 container_remove_child(con);
107 } 107 }
108 container_add_child(ws->sway_workspace->floating, con); 108 workspace_add_floating(ws, con);
109 109
110 // Make sure the container's center point overlaps this workspace 110 // Make sure the container's center point overlaps this workspace
111 double center_lx = con->x + con->width / 2; 111 double center_lx = con->x + con->width / 2;
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 7a2c1950..b77a9bb2 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -531,7 +531,7 @@ static bool should_focus(struct sway_view *view) {
531 struct sway_container *parent = view->swayc->parent; 531 struct sway_container *parent = view->swayc->parent;
532 if (parent->type == C_WORKSPACE && prev_focus == parent) { 532 if (parent->type == C_WORKSPACE && prev_focus == parent) {
533 size_t num_children = parent->children->length + 533 size_t num_children = parent->children->length +
534 parent->sway_workspace->floating->children->length; 534 parent->sway_workspace->floating->length;
535 if (num_children == 1) { 535 if (num_children == 1) {
536 return true; 536 return true;
537 } 537 }
@@ -557,7 +557,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
557 // If we're about to launch the view into the floating container, then 557 // If we're about to launch the view into the floating container, then
558 // launch it as a tiled view in the root of the workspace instead. 558 // launch it as a tiled view in the root of the workspace instead.
559 if (container_is_floating(target_sibling)) { 559 if (container_is_floating(target_sibling)) {
560 target_sibling = target_sibling->parent->parent; 560 target_sibling = target_sibling->parent;
561 } 561 }
562 562
563 view->swayc = container_view_create(target_sibling, view); 563 view->swayc = container_view_create(target_sibling, view);
@@ -1046,7 +1046,7 @@ bool view_is_visible(struct sway_view *view) {
1046 // Check view isn't in a tabbed or stacked container on an inactive tab 1046 // Check view isn't in a tabbed or stacked container on an inactive tab
1047 struct sway_seat *seat = input_manager_current_seat(input_manager); 1047 struct sway_seat *seat = input_manager_current_seat(input_manager);
1048 struct sway_container *container = view->swayc; 1048 struct sway_container *container = view->swayc;
1049 while (container->type != C_WORKSPACE && container->layout != L_FLOATING) { 1049 while (container->type != C_WORKSPACE) {
1050 if (container->parent->layout == L_TABBED || 1050 if (container->parent->layout == L_TABBED ||
1051 container->parent->layout == L_STACKED) { 1051 container->parent->layout == L_STACKED) {
1052 if (seat_get_active_child(seat, container->parent) != container) { 1052 if (seat_get_active_child(seat, container->parent) != container) {
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index a6d1870c..292f2c9a 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -67,9 +67,7 @@ struct sway_container *workspace_create(struct sway_container *output,
67 return NULL; 67 return NULL;
68 } 68 }
69 swayws->swayc = workspace; 69 swayws->swayc = workspace;
70 swayws->floating = container_create(C_CONTAINER); 70 swayws->floating = create_list();
71 swayws->floating->parent = swayws->swayc;
72 swayws->floating->layout = L_FLOATING;
73 swayws->output_priority = create_list(); 71 swayws->output_priority = create_list();
74 workspace->sway_workspace = swayws; 72 workspace->sway_workspace = swayws;
75 workspace_output_add_priority(workspace, output); 73 workspace_output_add_priority(workspace, output);
@@ -392,17 +390,15 @@ bool workspace_switch(struct sway_container *workspace,
392 struct sway_container *next_output = workspace->parent; 390 struct sway_container *next_output = workspace->parent;
393 struct sway_container *next_output_prev_ws = 391 struct sway_container *next_output_prev_ws =
394 seat_get_active_child(seat, next_output); 392 seat_get_active_child(seat, next_output);
395 struct sway_container *floating = 393 list_t *floating = next_output_prev_ws->sway_workspace->floating;
396 next_output_prev_ws->sway_workspace->floating;
397 bool has_sticky = false; 394 bool has_sticky = false;
398 if (workspace != next_output_prev_ws) { 395 if (workspace != next_output_prev_ws) {
399 for (int i = 0; i < floating->children->length; ++i) { 396 for (int i = 0; i < floating->length; ++i) {
400 struct sway_container *floater = floating->children->items[i]; 397 struct sway_container *floater = floating->items[i];
401 if (floater->is_sticky) { 398 if (floater->is_sticky) {
402 has_sticky = true; 399 has_sticky = true;
403 container_remove_child(floater); 400 container_remove_child(floater);
404 container_add_child(workspace->sway_workspace->floating, 401 workspace_add_floating(workspace, floater);
405 floater);
406 if (floater == focus) { 402 if (floater == focus) {
407 seat_set_focus(seat, NULL); 403 seat_set_focus(seat, NULL);
408 seat_set_focus(seat, floater); 404 seat_set_focus(seat, floater);
@@ -455,9 +451,9 @@ bool workspace_is_empty(struct sway_container *ws) {
455 return false; 451 return false;
456 } 452 }
457 // Sticky views are not considered to be part of this workspace 453 // Sticky views are not considered to be part of this workspace
458 struct sway_container *floating = ws->sway_workspace->floating; 454 list_t *floating = ws->sway_workspace->floating;
459 for (int i = 0; i < floating->children->length; ++i) { 455 for (int i = 0; i < floating->length; ++i) {
460 struct sway_container *floater = floating->children->items[i]; 456 struct sway_container *floater = floating->items[i];
461 if (!floater->is_sticky) { 457 if (!floater->is_sticky) {
462 return false; 458 return false;
463 } 459 }
@@ -548,9 +544,9 @@ void workspace_for_each_container(struct sway_container *ws,
548 container_for_each_child(container, f, data); 544 container_for_each_child(container, f, data);
549 } 545 }
550 // Floating 546 // Floating
551 for (int i = 0; i < ws->sway_workspace->floating->children->length; ++i) { 547 for (int i = 0; i < ws->sway_workspace->floating->length; ++i) {
552 struct sway_container *container = 548 struct sway_container *container =
553 ws->sway_workspace->floating->children->items[i]; 549 ws->sway_workspace->floating->items[i];
554 f(container, data); 550 f(container, data);
555 container_for_each_child(container, f, data); 551 container_for_each_child(container, f, data);
556 } 552 }
@@ -573,9 +569,8 @@ struct sway_container *workspace_find_container(struct sway_container *ws,
573 } 569 }
574 } 570 }
575 // Floating 571 // Floating
576 for (int i = 0; i < ws->sway_workspace->floating->children->length; ++i) { 572 for (int i = 0; i < ws->sway_workspace->floating->length; ++i) {
577 struct sway_container *child = 573 struct sway_container *child = ws->sway_workspace->floating->items[i];
578 ws->sway_workspace->floating->children->items[i];
579 if (test(child, data)) { 574 if (test(child, data)) {
580 return child; 575 return child;
581 } 576 }
@@ -597,3 +592,18 @@ struct sway_container *workspace_wrap_children(struct sway_container *ws) {
597 container_add_child(ws, middle); 592 container_add_child(ws, middle);
598 return middle; 593 return middle;
599} 594}
595
596void workspace_add_floating(struct sway_container *workspace,
597 struct sway_container *con) {
598 if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) {
599 return;
600 }
601 if (!sway_assert(con->parent == NULL, "Expected an orphan container")) {
602 return;
603 }
604
605 list_add(workspace->sway_workspace->floating, con);
606 con->parent = workspace;
607 container_set_dirty(workspace);
608 container_set_dirty(con);
609}