aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}