aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--include/sway/tree/container.h3
-rw-r--r--include/sway/tree/workspace.h5
-rw-r--r--sway/commands/floating.c2
-rw-r--r--sway/commands/focus.c2
-rw-r--r--sway/commands/move.c2
-rw-r--r--sway/commands/scratchpad.c9
-rw-r--r--sway/commands/swap.c2
-rw-r--r--sway/debug-tree.c2
-rw-r--r--sway/desktop/output.c31
-rw-r--r--sway/desktop/render.c5
-rw-r--r--sway/desktop/transaction.c4
-rw-r--r--sway/input/cursor.c4
-rw-r--r--sway/input/seat.c18
-rw-r--r--sway/ipc-json.c11
-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
20 files changed, 109 insertions, 136 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index c8410801..5eccedc1 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -40,7 +40,6 @@ enum sway_container_layout {
40 L_VERT, 40 L_VERT,
41 L_STACKED, 41 L_STACKED,
42 L_TABBED, 42 L_TABBED,
43 L_FLOATING,
44}; 43};
45 44
46enum sway_container_border { 45enum sway_container_border {
@@ -87,7 +86,7 @@ struct sway_container_state {
87 86
88 // Workspace properties 87 // Workspace properties
89 struct sway_container *ws_fullscreen; 88 struct sway_container *ws_fullscreen;
90 struct sway_container *ws_floating; 89 list_t *ws_floating;
91}; 90};
92 91
93struct sway_container { 92struct sway_container {
diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h
index c9dbb538..35c91017 100644
--- a/include/sway/tree/workspace.h
+++ b/include/sway/tree/workspace.h
@@ -9,7 +9,7 @@ struct sway_view;
9struct sway_workspace { 9struct sway_workspace {
10 struct sway_container *swayc; 10 struct sway_container *swayc;
11 struct sway_container *fullscreen; 11 struct sway_container *fullscreen;
12 struct sway_container *floating; 12 list_t *floating; // struct sway_container
13 list_t *output_priority; 13 list_t *output_priority;
14 bool urgent; 14 bool urgent;
15}; 15};
@@ -63,4 +63,7 @@ struct sway_container *workspace_find_container(struct sway_container *ws,
63 */ 63 */
64struct sway_container *workspace_wrap_children(struct sway_container *ws); 64struct sway_container *workspace_wrap_children(struct sway_container *ws);
65 65
66void workspace_add_floating(struct sway_container *workspace,
67 struct sway_container *con);
68
66#endif 69#endif
diff --git a/sway/commands/floating.c b/sway/commands/floating.c
index c9467ef0..beafd9fb 100644
--- a/sway/commands/floating.c
+++ b/sway/commands/floating.c
@@ -33,7 +33,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
33 // If the container is in a floating split container, 33 // If the container is in a floating split container,
34 // operate on the split container instead of the child. 34 // operate on the split container instead of the child.
35 if (container_is_floating_or_child(container)) { 35 if (container_is_floating_or_child(container)) {
36 while (container->parent->layout != L_FLOATING) { 36 while (container->parent->type != C_WORKSPACE) {
37 container = container->parent; 37 container = container->parent;
38 } 38 }
39 } 39 }
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index fe15b4c7..6659a683 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -39,7 +39,7 @@ static struct cmd_results *focus_mode(struct sway_container *con,
39 // If the container is in a floating split container, 39 // If the container is in a floating split container,
40 // operate on the split container instead of the child. 40 // operate on the split container instead of the child.
41 if (container_is_floating_or_child(con)) { 41 if (container_is_floating_or_child(con)) {
42 while (con->parent->layout != L_FLOATING) { 42 while (con->parent->type != C_WORKSPACE) {
43 con = con->parent; 43 con = con->parent;
44 } 44 }
45 } 45 }
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 33d1ee4a..e788d32f 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -449,7 +449,7 @@ static struct cmd_results *move_to_scratchpad(struct sway_container *con) {
449 // If the container is in a floating split container, 449 // If the container is in a floating split container,
450 // operate on the split container instead of the child. 450 // operate on the split container instead of the child.
451 if (container_is_floating_or_child(con)) { 451 if (container_is_floating_or_child(con)) {
452 while (con->parent->layout != L_FLOATING) { 452 while (con->parent->type != C_WORKSPACE) {
453 con = con->parent; 453 con = con->parent;
454 } 454 }
455 } 455 }
diff --git a/sway/commands/scratchpad.c b/sway/commands/scratchpad.c
index 0e573aeb..7da20015 100644
--- a/sway/commands/scratchpad.c
+++ b/sway/commands/scratchpad.c
@@ -16,7 +16,7 @@ static void scratchpad_toggle_auto(void) {
16 // If the focus is in a floating split container, 16 // If the focus is in a floating split container,
17 // operate on the split container instead of the child. 17 // operate on the split container instead of the child.
18 if (container_is_floating_or_child(focus)) { 18 if (container_is_floating_or_child(focus)) {
19 while (focus->parent->layout != L_FLOATING) { 19 while (focus->parent->type != C_WORKSPACE) {
20 focus = focus->parent; 20 focus = focus->parent;
21 } 21 }
22 } 22 }
@@ -33,9 +33,8 @@ static void scratchpad_toggle_auto(void) {
33 33
34 // Check if there is an unfocused scratchpad window on the current workspace 34 // Check if there is an unfocused scratchpad window on the current workspace
35 // and focus it. 35 // and focus it.
36 for (int i = 0; i < ws->sway_workspace->floating->children->length; ++i) { 36 for (int i = 0; i < ws->sway_workspace->floating->length; ++i) {
37 struct sway_container *floater = 37 struct sway_container *floater = ws->sway_workspace->floating->items[i];
38 ws->sway_workspace->floating->children->items[i];
39 if (floater->scratchpad && focus != floater) { 38 if (floater->scratchpad && focus != floater) {
40 wlr_log(WLR_DEBUG, 39 wlr_log(WLR_DEBUG,
41 "Focusing other scratchpad window (%s) in this workspace", 40 "Focusing other scratchpad window (%s) in this workspace",
@@ -103,7 +102,7 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) {
103 // If the container is in a floating split container, 102 // If the container is in a floating split container,
104 // operate on the split container instead of the child. 103 // operate on the split container instead of the child.
105 if (container_is_floating_or_child(con)) { 104 if (container_is_floating_or_child(con)) {
106 while (con->parent->layout != L_FLOATING) { 105 while (con->parent->type != C_WORKSPACE) {
107 con = con->parent; 106 con = con->parent;
108 } 107 }
109 } 108 }
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index 615e6b1d..f881a002 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -72,7 +72,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
72 || container_has_ancestor(other, current)) { 72 || container_has_ancestor(other, current)) {
73 error = cmd_results_new(CMD_FAILURE, "swap", 73 error = cmd_results_new(CMD_FAILURE, "swap",
74 "Cannot swap ancestor and descendant"); 74 "Cannot swap ancestor and descendant");
75 } else if (current->layout == L_FLOATING || other->layout == L_FLOATING) { 75 } else if (container_is_floating(current) || container_is_floating(other)) {
76 error = cmd_results_new(CMD_FAILURE, "swap", 76 error = cmd_results_new(CMD_FAILURE, "swap",
77 "Swapping with floating containers is not supported"); 77 "Swapping with floating containers is not supported");
78 } 78 }
diff --git a/sway/debug-tree.c b/sway/debug-tree.c
index f3465afe..0cb499e7 100644
--- a/sway/debug-tree.c
+++ b/sway/debug-tree.c
@@ -22,8 +22,6 @@ static const char *layout_to_str(enum sway_container_layout layout) {
22 return "L_STACKED"; 22 return "L_STACKED";
23 case L_TABBED: 23 case L_TABBED:
24 return "L_TABBED"; 24 return "L_TABBED";
25 case L_FLOATING:
26 return "L_FLOATING";
27 case L_NONE: 25 case L_NONE:
28 return "L_NONE"; 26 return "L_NONE";
29 } 27 }
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 1e4f196b..2253eb51 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -316,31 +316,21 @@ static void send_frame_done_container_iterator(struct sway_container *con,
316 send_frame_done_iterator, data->when); 316 send_frame_done_iterator, data->when);
317} 317}
318 318
319static void send_frame_done_container(struct sway_output *output,
320 struct sway_container *con, struct timespec *when) {
321 struct send_frame_done_data data = {
322 .output = output,
323 .when = when,
324 };
325 output_for_each_container(output->swayc,
326 send_frame_done_container_iterator, &data);
327}
328
329static void send_frame_done(struct sway_output *output, struct timespec *when) { 319static void send_frame_done(struct sway_output *output, struct timespec *when) {
330 if (output_has_opaque_overlay_layer_surface(output)) { 320 if (output_has_opaque_overlay_layer_surface(output)) {
331 goto send_frame_overlay; 321 goto send_frame_overlay;
332 } 322 }
333 323
324 struct send_frame_done_data data = {
325 .output = output,
326 .when = when,
327 };
334 struct sway_container *workspace = output_get_active_workspace(output); 328 struct sway_container *workspace = output_get_active_workspace(output);
335 if (workspace->current.ws_fullscreen) { 329 if (workspace->current.ws_fullscreen) {
336 if (workspace->current.ws_fullscreen->type == C_VIEW) { 330 send_frame_done_container_iterator(
337 output_view_for_each_surface(output, 331 workspace->current.ws_fullscreen, &data);
338 workspace->current.ws_fullscreen->sway_view, 332 container_for_each_child(workspace->current.ws_fullscreen,
339 send_frame_done_iterator, when); 333 send_frame_done_container_iterator, &data);
340 } else {
341 send_frame_done_container(output, workspace->current.ws_fullscreen,
342 when);
343 }
344#ifdef HAVE_XWAYLAND 334#ifdef HAVE_XWAYLAND
345 send_frame_done_unmanaged(output, 335 send_frame_done_unmanaged(output,
346 &root_container.sway_root->xwayland_unmanaged, when); 336 &root_container.sway_root->xwayland_unmanaged, when);
@@ -351,9 +341,8 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) {
351 send_frame_done_layer(output, 341 send_frame_done_layer(output,
352 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); 342 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when);
353 343
354 send_frame_done_container(output, workspace, when); 344 workspace_for_each_container(workspace,
355 send_frame_done_container(output, workspace->sway_workspace->floating, 345 send_frame_done_container_iterator, &data);
356 when);
357 346
358#ifdef HAVE_XWAYLAND 347#ifdef HAVE_XWAYLAND
359 send_frame_done_unmanaged(output, 348 send_frame_done_unmanaged(output,
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 7c48d0d2..aa70903e 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -754,8 +754,6 @@ static void render_container(struct sway_output *output,
754 case L_TABBED: 754 case L_TABBED:
755 render_container_tabbed(output, damage, con, parent_focused); 755 render_container_tabbed(output, damage, con, parent_focused);
756 break; 756 break;
757 case L_FLOATING:
758 sway_assert(false, "Didn't expect to see floating here");
759 } 757 }
760} 758}
761 759
@@ -806,8 +804,7 @@ static void render_floating(struct sway_output *soutput,
806 if (!workspace_is_visible(ws)) { 804 if (!workspace_is_visible(ws)) {
807 continue; 805 continue;
808 } 806 }
809 list_t *floating = 807 list_t *floating = ws->current.ws_floating;
810 ws->current.ws_floating->current.children;
811 for (int k = 0; k < floating->length; ++k) { 808 for (int k = 0; k < floating->length; ++k) {
812 struct sway_container *floater = floating->items[k]; 809 struct sway_container *floater = floating->items[k];
813 render_floating_container(soutput, damage, floater); 810 render_floating_container(soutput, damage, floater);
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index c300558a..692fb447 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -111,8 +111,9 @@ static void copy_pending_state(struct sway_container *container,
111 state->using_csd = view->using_csd; 111 state->using_csd = view->using_csd;
112 } else if (container->type == C_WORKSPACE) { 112 } else if (container->type == C_WORKSPACE) {
113 state->ws_fullscreen = container->sway_workspace->fullscreen; 113 state->ws_fullscreen = container->sway_workspace->fullscreen;
114 state->ws_floating = container->sway_workspace->floating; 114 state->ws_floating = create_list();
115 state->children = create_list(); 115 state->children = create_list();
116 list_cat(state->ws_floating, container->sway_workspace->floating);
116 list_cat(state->children, container->children); 117 list_cat(state->children, container->children);
117 } else { 118 } else {
118 state->children = create_list(); 119 state->children = create_list();
@@ -189,6 +190,7 @@ static void transaction_apply(struct sway_transaction *transaction) {
189 // Any child containers which are being deleted will be cleaned up in 190 // Any child containers which are being deleted will be cleaned up in
190 // transaction_destroy(). 191 // transaction_destroy().
191 list_free(container->current.children); 192 list_free(container->current.children);
193 list_free(container->current.ws_floating);
192 194
193 memcpy(&container->current, &instruction->state, 195 memcpy(&container->current, &instruction->state,
194 sizeof(struct sway_container_state)); 196 sizeof(struct sway_container_state));
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 762b8081..ba5e0400 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -724,7 +724,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
724 uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT; 724 uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
725 if (button == btn_move && state == WLR_BUTTON_PRESSED && 725 if (button == btn_move && state == WLR_BUTTON_PRESSED &&
726 (mod_pressed || on_titlebar)) { 726 (mod_pressed || on_titlebar)) {
727 while (cont->parent->layout != L_FLOATING) { 727 while (cont->parent->type != C_WORKSPACE) {
728 cont = cont->parent; 728 cont = cont->parent;
729 } 729 }
730 seat_begin_move(seat, cont, button); 730 seat_begin_move(seat, cont, button);
@@ -746,7 +746,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
746 BTN_LEFT : BTN_RIGHT; 746 BTN_LEFT : BTN_RIGHT;
747 if (mod_pressed && button == btn_resize) { 747 if (mod_pressed && button == btn_resize) {
748 struct sway_container *floater = cont; 748 struct sway_container *floater = cont;
749 while (floater->parent->layout != L_FLOATING) { 749 while (floater->parent->type != C_WORKSPACE) {
750 floater = floater->parent; 750 floater = floater->parent;
751 } 751 }
752 edge = 0; 752 edge = 0;
diff --git a/sway/input/seat.c b/sway/input/seat.c
index d35c62a0..caee37a6 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -688,7 +688,8 @@ void seat_set_focus_warp(struct sway_seat *seat,
688 // If we've focused a floating container, bring it to the front. 688 // If we've focused a floating container, bring it to the front.
689 // We do this by putting it at the end of the floating list. 689 // We do this by putting it at the end of the floating list.
690 if (container && container_is_floating(container)) { 690 if (container && container_is_floating(container)) {
691 list_move_to_end(container->parent->children, container); 691 list_move_to_end(
692 container->parent->sway_workspace->floating, container);
692 } 693 }
693 694
694 // clean up unfocused empty workspace on new output 695 // clean up unfocused empty workspace on new output
@@ -850,7 +851,7 @@ void seat_set_exclusive_client(struct sway_seat *seat,
850struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 851struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
851 struct sway_container *con) { 852 struct sway_container *con) {
852 if (con->type == C_WORKSPACE && !con->children->length && 853 if (con->type == C_WORKSPACE && !con->children->length &&
853 !con->sway_workspace->floating->children->length) { 854 !con->sway_workspace->floating->length) {
854 return con; 855 return con;
855 } 856 }
856 if (con->type == C_VIEW) { 857 if (con->type == C_VIEW) {
@@ -873,7 +874,7 @@ struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
873 struct sway_seat_container *current; 874 struct sway_seat_container *current;
874 wl_list_for_each(current, &seat->focus_stack, link) { 875 wl_list_for_each(current, &seat->focus_stack, link) {
875 struct sway_container *con = current->container; 876 struct sway_container *con = current->container;
876 if (con->layout != L_FLOATING && !container_is_floating_or_child(con) && 877 if (!container_is_floating_or_child(con) &&
877 container_has_ancestor(current->container, ancestor)) { 878 container_has_ancestor(current->container, ancestor)) {
878 return con; 879 return con;
879 } 880 }
@@ -884,13 +885,13 @@ struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
884struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, 885struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
885 struct sway_container *ancestor) { 886 struct sway_container *ancestor) {
886 if (ancestor->type == C_WORKSPACE && 887 if (ancestor->type == C_WORKSPACE &&
887 !ancestor->sway_workspace->floating->children->length) { 888 !ancestor->sway_workspace->floating->length) {
888 return NULL; 889 return NULL;
889 } 890 }
890 struct sway_seat_container *current; 891 struct sway_seat_container *current;
891 wl_list_for_each(current, &seat->focus_stack, link) { 892 wl_list_for_each(current, &seat->focus_stack, link) {
892 struct sway_container *con = current->container; 893 struct sway_container *con = current->container;
893 if (con->layout != L_FLOATING && container_is_floating_or_child(con) && 894 if (container_is_floating_or_child(con) &&
894 container_has_ancestor(current->container, ancestor)) { 895 container_has_ancestor(current->container, ancestor)) {
895 return con; 896 return con;
896 } 897 }
@@ -898,11 +899,6 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
898 return NULL; 899 return NULL;
899} 900}
900 901
901static bool impl_focus_active_child(struct sway_container *con, void *data) {
902 struct sway_container *parent = data;
903 return con->parent == parent && con->layout != L_FLOATING;
904}
905
906struct sway_container *seat_get_active_child(struct sway_seat *seat, 902struct sway_container *seat_get_active_child(struct sway_seat *seat,
907 struct sway_container *parent) { 903 struct sway_container *parent) {
908 if (parent->type == C_VIEW) { 904 if (parent->type == C_VIEW) {
@@ -911,7 +907,7 @@ struct sway_container *seat_get_active_child(struct sway_seat *seat,
911 struct sway_seat_container *current; 907 struct sway_seat_container *current;
912 wl_list_for_each(current, &seat->focus_stack, link) { 908 wl_list_for_each(current, &seat->focus_stack, link) {
913 struct sway_container *con = current->container; 909 struct sway_container *con = current->container;
914 if (con->parent == parent && con->layout != L_FLOATING) { 910 if (con->parent == parent) {
915 return con; 911 return con;
916 } 912 }
917 } 913 }
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index 4c2bcc98..f40af043 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -23,8 +23,6 @@ static const char *ipc_json_layout_description(enum sway_container_layout l) {
23 return "tabbed"; 23 return "tabbed";
24 case L_STACKED: 24 case L_STACKED:
25 return "stacked"; 25 return "stacked";
26 case L_FLOATING:
27 return "floating";
28 case L_NONE: 26 case L_NONE:
29 break; 27 break;
30 } 28 }
@@ -180,10 +178,11 @@ static void ipc_json_describe_workspace(struct sway_container *workspace,
180 178
181 // Floating 179 // Floating
182 json_object *floating_array = json_object_new_array(); 180 json_object *floating_array = json_object_new_array();
183 struct sway_container *floating = workspace->sway_workspace->floating; 181 list_t *floating = workspace->sway_workspace->floating;
184 for (int i = 0; i < floating->children->length; ++i) { 182 for (int i = 0; i < floating->length; ++i) {
185 struct sway_container *floater = floating->children->items[i]; 183 struct sway_container *floater = floating->items[i];
186 json_object_array_add(floating_array, ipc_json_describe_container_recursive(floater)); 184 json_object_array_add(floating_array,
185 ipc_json_describe_container_recursive(floater));
187 } 186 }
188 json_object_object_add(object, "floating_nodes", floating_array); 187 json_object_object_add(object, "floating_nodes", floating_array);
189} 188}
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}