aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-26 12:05:16 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-26 12:05:16 +1000
commit5dbbab7bdc56fc513eea2f9a39d722859a3b0c2e (patch)
tree2aad57ba7f7eec9fdb51b98859f6da826a4d39a1 /sway
parentMerge pull request #2488 from RyanDwyer/separate-gaps-functions (diff)
downloadsway-5dbbab7bdc56fc513eea2f9a39d722859a3b0c2e.tar.gz
sway-5dbbab7bdc56fc513eea2f9a39d722859a3b0c2e.tar.zst
sway-5dbbab7bdc56fc513eea2f9a39d722859a3b0c2e.zip
Remove layout.c
When we have type safety we'll need to have functions for workspace_add_tiling and so on. This means the existing container functions will be just for containers, so they are being moved to container.c. At this point layout.c doesn't contain much else, so I've relocated everything and removed the file. * container_swap and its static functions have been moved to the swap command and made static. * container_recursive_resize has been moved to the resize command and made static. * The following have been moved to container.c: * container_handle_fullscreen_reparent * container_insert_child * container_add_sibling * container_add_child * container_remove_child * container_replace_child * container_split * enum movement_direction and sway_dir_to_wlr have been moved to util.c. Side note: Several commands included layout.h which then included root.h. With layout.h gone, root.h has to be included by those commands.
Diffstat (limited to 'sway')
-rw-r--r--sway/commands/exec_always.c1
-rw-r--r--sway/commands/floating.c1
-rw-r--r--sway/commands/focus.c2
-rw-r--r--sway/commands/fullscreen.c1
-rw-r--r--sway/commands/hide_edge_borders.c1
-rw-r--r--sway/commands/move.c1
-rw-r--r--sway/commands/output.c1
-rw-r--r--sway/commands/resize.c21
-rw-r--r--sway/commands/show_marks.c1
-rw-r--r--sway/commands/sticky.c1
-rw-r--r--sway/commands/swap.c128
-rw-r--r--sway/commands/unmark.c1
-rw-r--r--sway/commands/urgent.c1
-rw-r--r--sway/config.c2
-rw-r--r--sway/config/output.c1
-rw-r--r--sway/criteria.c1
-rw-r--r--sway/debug-tree.c2
-rw-r--r--sway/desktop/layer_shell.c1
-rw-r--r--sway/desktop/output.c2
-rw-r--r--sway/desktop/render.c2
-rw-r--r--sway/desktop/xdg_shell.c1
-rw-r--r--sway/desktop/xdg_shell_v6.c1
-rw-r--r--sway/desktop/xwayland.c1
-rw-r--r--sway/input/cursor.c1
-rw-r--r--sway/input/seat.c3
-rw-r--r--sway/ipc-server.c1
-rw-r--r--sway/main.c2
-rw-r--r--sway/meson.build1
-rw-r--r--sway/server.c2
-rw-r--r--sway/tree/arrange.c1
-rw-r--r--sway/tree/container.c221
-rw-r--r--sway/tree/layout.c403
-rw-r--r--sway/tree/view.c1
33 files changed, 386 insertions, 425 deletions
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index 5ce7919b..bc07c2aa 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -8,6 +8,7 @@
8#include "sway/commands.h" 8#include "sway/commands.h"
9#include "sway/config.h" 9#include "sway/config.h"
10#include "sway/tree/container.h" 10#include "sway/tree/container.h"
11#include "sway/tree/root.h"
11#include "sway/tree/workspace.h" 12#include "sway/tree/workspace.h"
12#include "log.h" 13#include "log.h"
13#include "stringop.h" 14#include "stringop.h"
diff --git a/sway/commands/floating.c b/sway/commands/floating.c
index beafd9fb..436376e3 100644
--- a/sway/commands/floating.c
+++ b/sway/commands/floating.c
@@ -6,7 +6,6 @@
6#include "sway/output.h" 6#include "sway/output.h"
7#include "sway/tree/arrange.h" 7#include "sway/tree/arrange.h"
8#include "sway/tree/container.h" 8#include "sway/tree/container.h"
9#include "sway/tree/layout.h"
10#include "sway/tree/view.h" 9#include "sway/tree/view.h"
11#include "sway/tree/workspace.h" 10#include "sway/tree/workspace.h"
12#include "list.h" 11#include "list.h"
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index a9fa9a0f..f342e524 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -6,9 +6,11 @@
6#include "sway/input/seat.h" 6#include "sway/input/seat.h"
7#include "sway/output.h" 7#include "sway/output.h"
8#include "sway/tree/arrange.h" 8#include "sway/tree/arrange.h"
9#include "sway/tree/root.h"
9#include "sway/tree/view.h" 10#include "sway/tree/view.h"
10#include "sway/tree/workspace.h" 11#include "sway/tree/workspace.h"
11#include "stringop.h" 12#include "stringop.h"
13#include "util.h"
12 14
13static bool parse_movement_direction(const char *name, 15static bool parse_movement_direction(const char *name,
14 enum movement_direction *out) { 16 enum movement_direction *out) {
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
index a0661200..ac65dffb 100644
--- a/sway/commands/fullscreen.c
+++ b/sway/commands/fullscreen.c
@@ -5,7 +5,6 @@
5#include "sway/tree/container.h" 5#include "sway/tree/container.h"
6#include "sway/tree/view.h" 6#include "sway/tree/view.h"
7#include "sway/tree/workspace.h" 7#include "sway/tree/workspace.h"
8#include "sway/tree/layout.h"
9#include "util.h" 8#include "util.h"
10 9
11struct cmd_results *cmd_fullscreen(int argc, char **argv) { 10struct cmd_results *cmd_fullscreen(int argc, char **argv) {
diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c
index d59c9fdb..e494f6aa 100644
--- a/sway/commands/hide_edge_borders.c
+++ b/sway/commands/hide_edge_borders.c
@@ -1,6 +1,7 @@
1#include "sway/commands.h" 1#include "sway/commands.h"
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/tree/container.h" 3#include "sway/tree/container.h"
4#include "sway/tree/root.h"
4#include "sway/tree/view.h" 5#include "sway/tree/view.h"
5 6
6static void _configure_view(struct sway_container *con, void *data) { 7static void _configure_view(struct sway_container *con, void *data) {
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 2744b354..d0f6b9ea 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -19,6 +19,7 @@
19#include "stringop.h" 19#include "stringop.h"
20#include "list.h" 20#include "list.h"
21#include "log.h" 21#include "log.h"
22#include "util.h"
22 23
23static const char *expected_syntax = 24static const char *expected_syntax =
24 "Expected 'move <left|right|up|down> <[px] px>' or " 25 "Expected 'move <left|right|up|down> <[px] px>' or "
diff --git a/sway/commands/output.c b/sway/commands/output.c
index ef1b7a69..00910843 100644
--- a/sway/commands/output.c
+++ b/sway/commands/output.c
@@ -1,7 +1,6 @@
1#include "sway/commands.h" 1#include "sway/commands.h"
2#include "sway/config.h" 2#include "sway/config.h"
3#include "sway/output.h" 3#include "sway/output.h"
4#include "sway/tree/layout.h"
5#include "list.h" 4#include "list.h"
6#include "log.h" 5#include "log.h"
7 6
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index ea1e36ff..ad659ef5 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -159,6 +159,27 @@ static int parallel_size(struct sway_container *c, enum resize_axis a) {
159 return normalize_axis(a) == RESIZE_AXIS_HORIZONTAL ? c->width : c->height; 159 return normalize_axis(a) == RESIZE_AXIS_HORIZONTAL ? c->width : c->height;
160} 160}
161 161
162static void container_recursive_resize(struct sway_container *container,
163 double amount, enum wlr_edges edge) {
164 bool layout_match = true;
165 wlr_log(WLR_DEBUG, "Resizing %p with amount: %f", container, amount);
166 if (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT) {
167 container->width += amount;
168 layout_match = container->layout == L_HORIZ;
169 } else if (edge == WLR_EDGE_TOP || edge == WLR_EDGE_BOTTOM) {
170 container->height += amount;
171 layout_match = container->layout == L_VERT;
172 }
173 if (container->children) {
174 for (int i = 0; i < container->children->length; i++) {
175 struct sway_container *child = container->children->items[i];
176 double amt = layout_match ?
177 amount / container->children->length : amount;
178 container_recursive_resize(child, amt, edge);
179 }
180 }
181}
182
162static void resize_tiled(struct sway_container *parent, int amount, 183static void resize_tiled(struct sway_container *parent, int amount,
163 enum resize_axis axis) { 184 enum resize_axis axis) {
164 struct sway_container *focused = parent; 185 struct sway_container *focused = parent;
diff --git a/sway/commands/show_marks.c b/sway/commands/show_marks.c
index dd7d170c..1844e917 100644
--- a/sway/commands/show_marks.c
+++ b/sway/commands/show_marks.c
@@ -2,6 +2,7 @@
2#include <string.h> 2#include <string.h>
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/config.h" 4#include "sway/config.h"
5#include "sway/tree/root.h"
5#include "sway/tree/view.h" 6#include "sway/tree/view.h"
6#include "sway/output.h" 7#include "sway/output.h"
7#include "list.h" 8#include "list.h"
diff --git a/sway/commands/sticky.c b/sway/commands/sticky.c
index 72ef4282..8692e08d 100644
--- a/sway/commands/sticky.c
+++ b/sway/commands/sticky.c
@@ -6,7 +6,6 @@
6#include "sway/output.h" 6#include "sway/output.h"
7#include "sway/tree/arrange.h" 7#include "sway/tree/arrange.h"
8#include "sway/tree/container.h" 8#include "sway/tree/container.h"
9#include "sway/tree/layout.h"
10#include "sway/tree/view.h" 9#include "sway/tree/view.h"
11#include "sway/tree/workspace.h" 10#include "sway/tree/workspace.h"
12#include "list.h" 11#include "list.h"
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index f881a002..f25c43a1 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -1,15 +1,141 @@
1#define _POSIX_C_SOURCE 200809L
1#include <strings.h> 2#include <strings.h>
2#include <wlr/util/log.h> 3#include <wlr/util/log.h>
3#include "config.h" 4#include "config.h"
5#include "log.h"
4#include "sway/commands.h" 6#include "sway/commands.h"
5#include "sway/tree/arrange.h" 7#include "sway/tree/arrange.h"
6#include "sway/tree/layout.h" 8#include "sway/tree/root.h"
7#include "sway/tree/view.h" 9#include "sway/tree/view.h"
10#include "sway/tree/workspace.h"
8#include "stringop.h" 11#include "stringop.h"
9 12
10static const char* EXPECTED_SYNTAX = 13static const char* EXPECTED_SYNTAX =
11 "Expected 'swap container with id|con_id|mark <arg>'"; 14 "Expected 'swap container with id|con_id|mark <arg>'";
12 15
16static void swap_places(struct sway_container *con1,
17 struct sway_container *con2) {
18 struct sway_container *temp = malloc(sizeof(struct sway_container));
19 temp->x = con1->x;
20 temp->y = con1->y;
21 temp->width = con1->width;
22 temp->height = con1->height;
23 temp->parent = con1->parent;
24
25 con1->x = con2->x;
26 con1->y = con2->y;
27 con1->width = con2->width;
28 con1->height = con2->height;
29
30 con2->x = temp->x;
31 con2->y = temp->y;
32 con2->width = temp->width;
33 con2->height = temp->height;
34
35 int temp_index = container_sibling_index(con1);
36 container_insert_child(con2->parent, con1, container_sibling_index(con2));
37 container_insert_child(temp->parent, con2, temp_index);
38
39 free(temp);
40}
41
42static void swap_focus(struct sway_container *con1,
43 struct sway_container *con2, struct sway_seat *seat,
44 struct sway_container *focus) {
45 if (focus == con1 || focus == con2) {
46 struct sway_container *ws1 = container_parent(con1, C_WORKSPACE);
47 struct sway_container *ws2 = container_parent(con2, C_WORKSPACE);
48 if (focus == con1 && (con2->parent->layout == L_TABBED
49 || con2->parent->layout == L_STACKED)) {
50 if (workspace_is_visible(ws2)) {
51 seat_set_focus_warp(seat, con2, false, true);
52 }
53 seat_set_focus(seat, ws1 != ws2 ? con2 : con1);
54 } else if (focus == con2 && (con1->parent->layout == L_TABBED
55 || con1->parent->layout == L_STACKED)) {
56 if (workspace_is_visible(ws1)) {
57 seat_set_focus_warp(seat, con1, false, true);
58 }
59 seat_set_focus(seat, ws1 != ws2 ? con1 : con2);
60 } else if (ws1 != ws2) {
61 seat_set_focus(seat, focus == con1 ? con2 : con1);
62 } else {
63 seat_set_focus(seat, focus);
64 }
65 } else {
66 seat_set_focus(seat, focus);
67 }
68}
69
70static void container_swap(struct sway_container *con1,
71 struct sway_container *con2) {
72 if (!sway_assert(con1 && con2, "Cannot swap with nothing")) {
73 return;
74 }
75 if (!sway_assert(con1->type >= C_CONTAINER && con2->type >= C_CONTAINER,
76 "Can only swap containers and views")) {
77 return;
78 }
79 if (!sway_assert(!container_has_ancestor(con1, con2)
80 && !container_has_ancestor(con2, con1),
81 "Cannot swap ancestor and descendant")) {
82 return;
83 }
84 if (!sway_assert(!container_is_floating(con1)
85 && !container_is_floating(con2),
86 "Swapping with floating containers is not supported")) {
87 return;
88 }
89
90 wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
91
92 int fs1 = con1->is_fullscreen;
93 int fs2 = con2->is_fullscreen;
94 if (fs1) {
95 container_set_fullscreen(con1, false);
96 }
97 if (fs2) {
98 container_set_fullscreen(con2, false);
99 }
100
101 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
102 struct sway_container *focus = seat_get_focus(seat);
103 struct sway_container *vis1 = container_parent(
104 seat_get_focus_inactive(seat, container_parent(con1, C_OUTPUT)),
105 C_WORKSPACE);
106 struct sway_container *vis2 = container_parent(
107 seat_get_focus_inactive(seat, container_parent(con2, C_OUTPUT)),
108 C_WORKSPACE);
109
110 char *stored_prev_name = NULL;
111 if (prev_workspace_name) {
112 stored_prev_name = strdup(prev_workspace_name);
113 }
114
115 swap_places(con1, con2);
116
117 if (!workspace_is_visible(vis1)) {
118 seat_set_focus(seat, seat_get_focus_inactive(seat, vis1));
119 }
120 if (!workspace_is_visible(vis2)) {
121 seat_set_focus(seat, seat_get_focus_inactive(seat, vis2));
122 }
123
124 swap_focus(con1, con2, seat, focus);
125
126 if (stored_prev_name) {
127 free(prev_workspace_name);
128 prev_workspace_name = stored_prev_name;
129 }
130
131 if (fs1) {
132 container_set_fullscreen(con2, true);
133 }
134 if (fs2) {
135 container_set_fullscreen(con1, true);
136 }
137}
138
13static bool test_con_id(struct sway_container *container, void *con_id) { 139static bool test_con_id(struct sway_container *container, void *con_id) {
14 return container->id == (size_t)con_id; 140 return container->id == (size_t)con_id;
15} 141}
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c
index c183785b..62127c97 100644
--- a/sway/commands/unmark.c
+++ b/sway/commands/unmark.c
@@ -2,6 +2,7 @@
2#include <string.h> 2#include <string.h>
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/config.h" 4#include "sway/config.h"
5#include "sway/tree/root.h"
5#include "sway/tree/view.h" 6#include "sway/tree/view.h"
6#include "list.h" 7#include "list.h"
7#include "log.h" 8#include "log.h"
diff --git a/sway/commands/urgent.c b/sway/commands/urgent.c
index 51c497c4..bccb33fe 100644
--- a/sway/commands/urgent.c
+++ b/sway/commands/urgent.c
@@ -4,7 +4,6 @@
4#include "sway/tree/arrange.h" 4#include "sway/tree/arrange.h"
5#include "sway/tree/container.h" 5#include "sway/tree/container.h"
6#include "sway/tree/view.h" 6#include "sway/tree/view.h"
7#include "sway/tree/layout.h"
8#include "util.h" 7#include "util.h"
9 8
10struct cmd_results *cmd_urgent(int argc, char **argv) { 9struct cmd_results *cmd_urgent(int argc, char **argv) {
diff --git a/sway/config.c b/sway/config.c
index 642abbac..8105722a 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -27,7 +27,7 @@
27#include "sway/criteria.h" 27#include "sway/criteria.h"
28#include "sway/swaynag.h" 28#include "sway/swaynag.h"
29#include "sway/tree/arrange.h" 29#include "sway/tree/arrange.h"
30#include "sway/tree/layout.h" 30#include "sway/tree/root.h"
31#include "sway/tree/workspace.h" 31#include "sway/tree/workspace.h"
32#include "cairo.h" 32#include "cairo.h"
33#include "pango.h" 33#include "pango.h"
diff --git a/sway/config/output.c b/sway/config/output.c
index 7f9b1007..199267bf 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -9,6 +9,7 @@
9#include <wlr/types/wlr_output_layout.h> 9#include <wlr/types/wlr_output_layout.h>
10#include "sway/config.h" 10#include "sway/config.h"
11#include "sway/output.h" 11#include "sway/output.h"
12#include "sway/tree/root.h"
12#include "log.h" 13#include "log.h"
13 14
14int output_name_cmp(const void *item, const void *data) { 15int output_name_cmp(const void *item, const void *data) {
diff --git a/sway/criteria.c b/sway/criteria.c
index 81c2325a..5452c4ee 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -6,6 +6,7 @@
6#include "sway/criteria.h" 6#include "sway/criteria.h"
7#include "sway/tree/container.h" 7#include "sway/tree/container.h"
8#include "sway/config.h" 8#include "sway/config.h"
9#include "sway/tree/root.h"
9#include "sway/tree/view.h" 10#include "sway/tree/view.h"
10#include "stringop.h" 11#include "stringop.h"
11#include "list.h" 12#include "list.h"
diff --git a/sway/debug-tree.c b/sway/debug-tree.c
index ea0826b9..2768cf58 100644
--- a/sway/debug-tree.c
+++ b/sway/debug-tree.c
@@ -9,7 +9,7 @@
9#include "sway/output.h" 9#include "sway/output.h"
10#include "sway/server.h" 10#include "sway/server.h"
11#include "sway/tree/container.h" 11#include "sway/tree/container.h"
12#include "sway/tree/layout.h" 12#include "sway/tree/root.h"
13#include "cairo.h" 13#include "cairo.h"
14#include "config.h" 14#include "config.h"
15#include "pango.h" 15#include "pango.h"
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index a2935883..1fae5db2 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -14,7 +14,6 @@
14#include "sway/output.h" 14#include "sway/output.h"
15#include "sway/server.h" 15#include "sway/server.h"
16#include "sway/tree/arrange.h" 16#include "sway/tree/arrange.h"
17#include "sway/tree/layout.h"
18#include "log.h" 17#include "log.h"
19 18
20static void apply_exclusive(struct wlr_box *usable_area, 19static void apply_exclusive(struct wlr_box *usable_area,
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 401d3c44..35fce1a6 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -23,7 +23,7 @@
23#include "sway/server.h" 23#include "sway/server.h"
24#include "sway/tree/arrange.h" 24#include "sway/tree/arrange.h"
25#include "sway/tree/container.h" 25#include "sway/tree/container.h"
26#include "sway/tree/layout.h" 26#include "sway/tree/root.h"
27#include "sway/tree/view.h" 27#include "sway/tree/view.h"
28#include "sway/tree/workspace.h" 28#include "sway/tree/workspace.h"
29 29
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 5cf8abc0..b5a10370 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -24,7 +24,7 @@
24#include "sway/server.h" 24#include "sway/server.h"
25#include "sway/tree/arrange.h" 25#include "sway/tree/arrange.h"
26#include "sway/tree/container.h" 26#include "sway/tree/container.h"
27#include "sway/tree/layout.h" 27#include "sway/tree/root.h"
28#include "sway/tree/view.h" 28#include "sway/tree/view.h"
29#include "sway/tree/workspace.h" 29#include "sway/tree/workspace.h"
30 30
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index f5aaa575..7d1824f1 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -13,7 +13,6 @@
13#include "sway/server.h" 13#include "sway/server.h"
14#include "sway/tree/arrange.h" 14#include "sway/tree/arrange.h"
15#include "sway/tree/container.h" 15#include "sway/tree/container.h"
16#include "sway/tree/layout.h"
17#include "sway/tree/view.h" 16#include "sway/tree/view.h"
18 17
19static const struct sway_view_child_impl popup_impl; 18static const struct sway_view_child_impl popup_impl;
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index f623b77b..522fddca 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -12,7 +12,6 @@
12#include "sway/server.h" 12#include "sway/server.h"
13#include "sway/tree/arrange.h" 13#include "sway/tree/arrange.h"
14#include "sway/tree/container.h" 14#include "sway/tree/container.h"
15#include "sway/tree/layout.h"
16#include "sway/tree/view.h" 15#include "sway/tree/view.h"
17 16
18static const struct sway_view_child_impl popup_impl; 17static const struct sway_view_child_impl popup_impl;
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 6fcc850d..4e401008 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -14,7 +14,6 @@
14#include "sway/server.h" 14#include "sway/server.h"
15#include "sway/tree/arrange.h" 15#include "sway/tree/arrange.h"
16#include "sway/tree/container.h" 16#include "sway/tree/container.h"
17#include "sway/tree/layout.h"
18#include "sway/tree/view.h" 17#include "sway/tree/view.h"
19 18
20static const char *atom_map[ATOM_LAST] = { 19static const char *atom_map[ATOM_LAST] = {
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index ba5e0400..00240e84 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -20,6 +20,7 @@
20#include "sway/layers.h" 20#include "sway/layers.h"
21#include "sway/output.h" 21#include "sway/output.h"
22#include "sway/tree/arrange.h" 22#include "sway/tree/arrange.h"
23#include "sway/tree/root.h"
23#include "sway/tree/view.h" 24#include "sway/tree/view.h"
24#include "sway/tree/workspace.h" 25#include "sway/tree/workspace.h"
25#include "wlr-layer-shell-unstable-v1-protocol.h" 26#include "wlr-layer-shell-unstable-v1-protocol.h"
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 997d7815..269823ee 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -25,10 +25,9 @@
25#include "sway/output.h" 25#include "sway/output.h"
26#include "sway/tree/arrange.h" 26#include "sway/tree/arrange.h"
27#include "sway/tree/container.h" 27#include "sway/tree/container.h"
28#include "sway/tree/container.h" 28#include "sway/tree/root.h"
29#include "sway/tree/view.h" 29#include "sway/tree/view.h"
30#include "sway/tree/workspace.h" 30#include "sway/tree/workspace.h"
31#include "sway/tree/workspace.h"
32 31
33static void seat_device_destroy(struct sway_seat_device *seat_device) { 32static void seat_device_destroy(struct sway_seat_device *seat_device) {
34 if (!seat_device) { 33 if (!seat_device) {
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 34e940ad..1ac0521e 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -31,6 +31,7 @@
31#include "sway/server.h" 31#include "sway/server.h"
32#include "sway/input/input-manager.h" 32#include "sway/input/input-manager.h"
33#include "sway/input/seat.h" 33#include "sway/input/seat.h"
34#include "sway/tree/root.h"
34#include "sway/tree/view.h" 35#include "sway/tree/view.h"
35#include "list.h" 36#include "list.h"
36#include "log.h" 37#include "log.h"
diff --git a/sway/main.c b/sway/main.c
index 3ba4ba75..7ed10c86 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -23,7 +23,7 @@
23#include "sway/desktop/transaction.h" 23#include "sway/desktop/transaction.h"
24#include "sway/server.h" 24#include "sway/server.h"
25#include "sway/swaynag.h" 25#include "sway/swaynag.h"
26#include "sway/tree/layout.h" 26#include "sway/tree/root.h"
27#include "sway/ipc-server.h" 27#include "sway/ipc-server.h"
28#include "ipc-client.h" 28#include "ipc-client.h"
29#include "readline.h" 29#include "readline.h"
diff --git a/sway/meson.build b/sway/meson.build
index 676422d0..bcb44e8b 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -150,7 +150,6 @@ sway_sources = files(
150 150
151 'tree/arrange.c', 151 'tree/arrange.c',
152 'tree/container.c', 152 'tree/container.c',
153 'tree/layout.c',
154 'tree/root.c', 153 'tree/root.c',
155 'tree/view.c', 154 'tree/view.c',
156 'tree/workspace.c', 155 'tree/workspace.c',
diff --git a/sway/server.c b/sway/server.c
index 00acaa01..7fa6007e 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -24,7 +24,7 @@
24#include "sway/desktop/idle_inhibit_v1.h" 24#include "sway/desktop/idle_inhibit_v1.h"
25#include "sway/input/input-manager.h" 25#include "sway/input/input-manager.h"
26#include "sway/server.h" 26#include "sway/server.h"
27#include "sway/tree/layout.h" 27#include "sway/tree/root.h"
28#include "config.h" 28#include "config.h"
29#ifdef HAVE_XWAYLAND 29#ifdef HAVE_XWAYLAND
30#include "sway/xwayland.h" 30#include "sway/xwayland.h"
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 0da61a4c..60e5b951 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -7,7 +7,6 @@
7#include <wlr/types/wlr_output_layout.h> 7#include <wlr/types/wlr_output_layout.h>
8#include "sway/tree/arrange.h" 8#include "sway/tree/arrange.h"
9#include "sway/tree/container.h" 9#include "sway/tree/container.h"
10#include "sway/tree/layout.h"
11#include "sway/output.h" 10#include "sway/output.h"
12#include "sway/tree/workspace.h" 11#include "sway/tree/workspace.h"
13#include "sway/tree/view.h" 12#include "sway/tree/view.h"
diff --git a/sway/tree/container.c b/sway/tree/container.c
index f9611342..f13e2e96 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -19,7 +19,6 @@
19#include "sway/output.h" 19#include "sway/output.h"
20#include "sway/server.h" 20#include "sway/server.h"
21#include "sway/tree/arrange.h" 21#include "sway/tree/arrange.h"
22#include "sway/tree/layout.h"
23#include "sway/tree/view.h" 22#include "sway/tree/view.h"
24#include "sway/tree/workspace.h" 23#include "sway/tree/workspace.h"
25#include "log.h" 24#include "log.h"
@@ -1159,3 +1158,223 @@ void container_add_gaps(struct sway_container *c) {
1159int container_sibling_index(const struct sway_container *child) { 1158int container_sibling_index(const struct sway_container *child) {
1160 return list_find(child->parent->children, child); 1159 return list_find(child->parent->children, child);
1161} 1160}
1161
1162void container_handle_fullscreen_reparent(struct sway_container *con,
1163 struct sway_container *old_parent) {
1164 if (!con->is_fullscreen) {
1165 return;
1166 }
1167 struct sway_container *old_workspace = old_parent;
1168 if (old_workspace && old_workspace->type != C_WORKSPACE) {
1169 old_workspace = container_parent(old_workspace, C_WORKSPACE);
1170 }
1171 struct sway_container *new_workspace = container_parent(con, C_WORKSPACE);
1172 if (old_workspace == new_workspace) {
1173 return;
1174 }
1175 // Unmark the old workspace as fullscreen
1176 if (old_workspace) {
1177 old_workspace->sway_workspace->fullscreen = NULL;
1178 }
1179
1180 // Mark the new workspace as fullscreen
1181 if (new_workspace->sway_workspace->fullscreen) {
1182 container_set_fullscreen(
1183 new_workspace->sway_workspace->fullscreen, false);
1184 }
1185 new_workspace->sway_workspace->fullscreen = con;
1186
1187 // Resize container to new output dimensions
1188 struct sway_container *output = new_workspace->parent;
1189 con->x = output->x;
1190 con->y = output->y;
1191 con->width = output->width;
1192 con->height = output->height;
1193
1194 if (con->type == C_VIEW) {
1195 struct sway_view *view = con->sway_view;
1196 view->x = output->x;
1197 view->y = output->y;
1198 view->width = output->width;
1199 view->height = output->height;
1200 } else {
1201 arrange_windows(new_workspace);
1202 }
1203}
1204
1205void container_insert_child(struct sway_container *parent,
1206 struct sway_container *child, int i) {
1207 struct sway_container *old_parent = child->parent;
1208 if (old_parent) {
1209 container_remove_child(child);
1210 }
1211 wlr_log(WLR_DEBUG, "Inserting id:%zd at index %d", child->id, i);
1212 list_insert(parent->children, i, child);
1213 child->parent = parent;
1214 container_handle_fullscreen_reparent(child, old_parent);
1215}
1216
1217struct sway_container *container_add_sibling(struct sway_container *fixed,
1218 struct sway_container *active) {
1219 // TODO handle floating
1220 struct sway_container *old_parent = NULL;
1221 if (active->parent) {
1222 old_parent = active->parent;
1223 container_remove_child(active);
1224 }
1225 struct sway_container *parent = fixed->parent;
1226 int i = container_sibling_index(fixed);
1227 list_insert(parent->children, i + 1, active);
1228 active->parent = parent;
1229 container_handle_fullscreen_reparent(active, old_parent);
1230 return active->parent;
1231}
1232
1233void container_add_child(struct sway_container *parent,
1234 struct sway_container *child) {
1235 wlr_log(WLR_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",
1236 child, child->type, child->width, child->height,
1237 parent, parent->type, parent->width, parent->height);
1238 struct sway_container *old_parent = child->parent;
1239 list_add(parent->children, child);
1240 child->parent = parent;
1241 container_handle_fullscreen_reparent(child, old_parent);
1242 if (old_parent) {
1243 container_set_dirty(old_parent);
1244 }
1245 container_set_dirty(child);
1246}
1247
1248struct sway_container *container_remove_child(struct sway_container *child) {
1249 if (child->is_fullscreen) {
1250 struct sway_container *workspace = container_parent(child, C_WORKSPACE);
1251 workspace->sway_workspace->fullscreen = NULL;
1252 }
1253
1254 struct sway_container *parent = child->parent;
1255 list_t *list = container_is_floating(child) ?
1256 parent->sway_workspace->floating : parent->children;
1257 int index = list_find(list, child);
1258 if (index != -1) {
1259 list_del(list, index);
1260 }
1261 child->parent = NULL;
1262 container_notify_subtree_changed(parent);
1263
1264 container_set_dirty(parent);
1265 container_set_dirty(child);
1266
1267 return parent;
1268}
1269
1270enum sway_container_layout container_get_default_layout(
1271 struct sway_container *con) {
1272 if (con->type != C_OUTPUT) {
1273 con = container_parent(con, C_OUTPUT);
1274 }
1275
1276 if (!sway_assert(con != NULL,
1277 "container_get_default_layout must be called on an attached"
1278 " container below the root container")) {
1279 return 0;
1280 }
1281
1282 if (config->default_layout != L_NONE) {
1283 return config->default_layout;
1284 } else if (config->default_orientation != L_NONE) {
1285 return config->default_orientation;
1286 } else if (con->width >= con->height) {
1287 return L_HORIZ;
1288 } else {
1289 return L_VERT;
1290 }
1291}
1292
1293struct sway_container *container_replace_child(struct sway_container *child,
1294 struct sway_container *new_child) {
1295 struct sway_container *parent = child->parent;
1296 if (parent == NULL) {
1297 return NULL;
1298 }
1299
1300 list_t *list = container_is_floating(child) ?
1301 parent->sway_workspace->floating : parent->children;
1302 int i = list_find(list, child);
1303
1304 if (new_child->parent) {
1305 container_remove_child(new_child);
1306 }
1307 list->items[i] = new_child;
1308 new_child->parent = parent;
1309 child->parent = NULL;
1310
1311 // Set geometry for new child
1312 new_child->x = child->x;
1313 new_child->y = child->y;
1314 new_child->width = child->width;
1315 new_child->height = child->height;
1316
1317 // reset geometry for child
1318 child->width = 0;
1319 child->height = 0;
1320
1321 return parent;
1322}
1323
1324struct sway_container *container_split(struct sway_container *child,
1325 enum sway_container_layout layout) {
1326 // TODO floating: cannot split a floating container
1327 if (!sway_assert(child, "child cannot be null")) {
1328 return NULL;
1329 }
1330 if (child->type == C_WORKSPACE && child->children->length == 0) {
1331 // Special case: this just behaves like splitt
1332 child->prev_split_layout = child->layout;
1333 child->layout = layout;
1334 return child;
1335 }
1336
1337 struct sway_container *cont = container_create(C_CONTAINER);
1338
1339 wlr_log(WLR_DEBUG, "creating container %p around %p", cont, child);
1340
1341 child->type == C_WORKSPACE ? workspace_remove_gaps(child)
1342 : container_remove_gaps(child);
1343
1344 cont->prev_split_layout = L_NONE;
1345 cont->width = child->width;
1346 cont->height = child->height;
1347 cont->x = child->x;
1348 cont->y = child->y;
1349
1350 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
1351 bool set_focus = (seat_get_focus(seat) == child);
1352
1353 container_add_gaps(cont);
1354
1355 if (child->type == C_WORKSPACE) {
1356 struct sway_container *workspace = child;
1357 while (workspace->children->length) {
1358 struct sway_container *ws_child = workspace->children->items[0];
1359 container_remove_child(ws_child);
1360 container_add_child(cont, ws_child);
1361 }
1362
1363 container_add_child(workspace, cont);
1364 enum sway_container_layout old_layout = workspace->layout;
1365 workspace->layout = layout;
1366 cont->layout = old_layout;
1367 } else {
1368 cont->layout = layout;
1369 container_replace_child(child, cont);
1370 container_add_child(cont, child);
1371 }
1372
1373 if (set_focus) {
1374 seat_set_focus(seat, cont);
1375 seat_set_focus(seat, child);
1376 }
1377
1378 container_notify_subtree_changed(cont);
1379 return cont;
1380}
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
deleted file mode 100644
index 85fe7643..00000000
--- a/sway/tree/layout.c
+++ /dev/null
@@ -1,403 +0,0 @@
1#define _POSIX_C_SOURCE 200809L
2#include <math.h>
3#include <stdbool.h>
4#include <stdlib.h>
5#include <string.h>
6#include <wlr/types/wlr_output.h>
7#include <wlr/types/wlr_output_layout.h>
8#include "config.h"
9#include "sway/debug.h"
10#include "sway/tree/arrange.h"
11#include "sway/tree/container.h"
12#include "sway/tree/layout.h"
13#include "sway/output.h"
14#include "sway/tree/workspace.h"
15#include "sway/tree/view.h"
16#include "sway/input/seat.h"
17#include "sway/ipc-server.h"
18#include "list.h"
19#include "log.h"
20
21void container_handle_fullscreen_reparent(struct sway_container *con,
22 struct sway_container *old_parent) {
23 if (!con->is_fullscreen) {
24 return;
25 }
26 struct sway_container *old_workspace = old_parent;
27 if (old_workspace && old_workspace->type != C_WORKSPACE) {
28 old_workspace = container_parent(old_workspace, C_WORKSPACE);
29 }
30 struct sway_container *new_workspace = container_parent(con, C_WORKSPACE);
31 if (old_workspace == new_workspace) {
32 return;
33 }
34 // Unmark the old workspace as fullscreen
35 if (old_workspace) {
36 old_workspace->sway_workspace->fullscreen = NULL;
37 }
38
39 // Mark the new workspace as fullscreen
40 if (new_workspace->sway_workspace->fullscreen) {
41 container_set_fullscreen(
42 new_workspace->sway_workspace->fullscreen, false);
43 }
44 new_workspace->sway_workspace->fullscreen = con;
45
46 // Resize container to new output dimensions
47 struct sway_container *output = new_workspace->parent;
48 con->x = output->x;
49 con->y = output->y;
50 con->width = output->width;
51 con->height = output->height;
52
53 if (con->type == C_VIEW) {
54 struct sway_view *view = con->sway_view;
55 view->x = output->x;
56 view->y = output->y;
57 view->width = output->width;
58 view->height = output->height;
59 } else {
60 arrange_windows(new_workspace);
61 }
62}
63
64void container_insert_child(struct sway_container *parent,
65 struct sway_container *child, int i) {
66 struct sway_container *old_parent = child->parent;
67 if (old_parent) {
68 container_remove_child(child);
69 }
70 wlr_log(WLR_DEBUG, "Inserting id:%zd at index %d", child->id, i);
71 list_insert(parent->children, i, child);
72 child->parent = parent;
73 container_handle_fullscreen_reparent(child, old_parent);
74}
75
76struct sway_container *container_add_sibling(struct sway_container *fixed,
77 struct sway_container *active) {
78 // TODO handle floating
79 struct sway_container *old_parent = NULL;
80 if (active->parent) {
81 old_parent = active->parent;
82 container_remove_child(active);
83 }
84 struct sway_container *parent = fixed->parent;
85 int i = container_sibling_index(fixed);
86 list_insert(parent->children, i + 1, active);
87 active->parent = parent;
88 container_handle_fullscreen_reparent(active, old_parent);
89 return active->parent;
90}
91
92void container_add_child(struct sway_container *parent,
93 struct sway_container *child) {
94 wlr_log(WLR_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",
95 child, child->type, child->width, child->height,
96 parent, parent->type, parent->width, parent->height);
97 struct sway_container *old_parent = child->parent;
98 list_add(parent->children, child);
99 child->parent = parent;
100 container_handle_fullscreen_reparent(child, old_parent);
101 if (old_parent) {
102 container_set_dirty(old_parent);
103 }
104 container_set_dirty(child);
105}
106
107struct sway_container *container_remove_child(struct sway_container *child) {
108 if (child->is_fullscreen) {
109 struct sway_container *workspace = container_parent(child, C_WORKSPACE);
110 workspace->sway_workspace->fullscreen = NULL;
111 }
112
113 struct sway_container *parent = child->parent;
114 list_t *list = container_is_floating(child) ?
115 parent->sway_workspace->floating : parent->children;
116 int index = list_find(list, child);
117 if (index != -1) {
118 list_del(list, index);
119 }
120 child->parent = NULL;
121 container_notify_subtree_changed(parent);
122
123 container_set_dirty(parent);
124 container_set_dirty(child);
125
126 return parent;
127}
128
129bool sway_dir_to_wlr(enum movement_direction dir, enum wlr_direction *out) {
130 switch (dir) {
131 case MOVE_UP:
132 *out = WLR_DIRECTION_UP;
133 break;
134 case MOVE_DOWN:
135 *out = WLR_DIRECTION_DOWN;
136 break;
137 case MOVE_LEFT:
138 *out = WLR_DIRECTION_LEFT;
139 break;
140 case MOVE_RIGHT:
141 *out = WLR_DIRECTION_RIGHT;
142 break;
143 default:
144 return false;
145 }
146
147 return true;
148}
149
150enum sway_container_layout container_get_default_layout(
151 struct sway_container *con) {
152 if (con->type != C_OUTPUT) {
153 con = container_parent(con, C_OUTPUT);
154 }
155
156 if (!sway_assert(con != NULL,
157 "container_get_default_layout must be called on an attached"
158 " container below the root container")) {
159 return 0;
160 }
161
162 if (config->default_layout != L_NONE) {
163 return config->default_layout;
164 } else if (config->default_orientation != L_NONE) {
165 return config->default_orientation;
166 } else if (con->width >= con->height) {
167 return L_HORIZ;
168 } else {
169 return L_VERT;
170 }
171}
172
173struct sway_container *container_replace_child(struct sway_container *child,
174 struct sway_container *new_child) {
175 struct sway_container *parent = child->parent;
176 if (parent == NULL) {
177 return NULL;
178 }
179
180 list_t *list = container_is_floating(child) ?
181 parent->sway_workspace->floating : parent->children;
182 int i = list_find(list, child);
183
184 if (new_child->parent) {
185 container_remove_child(new_child);
186 }
187 list->items[i] = new_child;
188 new_child->parent = parent;
189 child->parent = NULL;
190
191 // Set geometry for new child
192 new_child->x = child->x;
193 new_child->y = child->y;
194 new_child->width = child->width;
195 new_child->height = child->height;
196
197 // reset geometry for child
198 child->width = 0;
199 child->height = 0;
200
201 return parent;
202}
203
204struct sway_container *container_split(struct sway_container *child,
205 enum sway_container_layout layout) {
206 // TODO floating: cannot split a floating container
207 if (!sway_assert(child, "child cannot be null")) {
208 return NULL;
209 }
210 if (child->type == C_WORKSPACE && child->children->length == 0) {
211 // Special case: this just behaves like splitt
212 child->prev_split_layout = child->layout;
213 child->layout = layout;
214 return child;
215 }
216
217 struct sway_container *cont = container_create(C_CONTAINER);
218
219 wlr_log(WLR_DEBUG, "creating container %p around %p", cont, child);
220
221 child->type == C_WORKSPACE ? workspace_remove_gaps(child)
222 : container_remove_gaps(child);
223
224 cont->prev_split_layout = L_NONE;
225 cont->width = child->width;
226 cont->height = child->height;
227 cont->x = child->x;
228 cont->y = child->y;
229
230 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
231 bool set_focus = (seat_get_focus(seat) == child);
232
233 container_add_gaps(cont);
234
235 if (child->type == C_WORKSPACE) {
236 struct sway_container *workspace = child;
237 while (workspace->children->length) {
238 struct sway_container *ws_child = workspace->children->items[0];
239 container_remove_child(ws_child);
240 container_add_child(cont, ws_child);
241 }
242
243 container_add_child(workspace, cont);
244 enum sway_container_layout old_layout = workspace->layout;
245 workspace->layout = layout;
246 cont->layout = old_layout;
247 } else {
248 cont->layout = layout;
249 container_replace_child(child, cont);
250 container_add_child(cont, child);
251 }
252
253 if (set_focus) {
254 seat_set_focus(seat, cont);
255 seat_set_focus(seat, child);
256 }
257
258 container_notify_subtree_changed(cont);
259 return cont;
260}
261
262void container_recursive_resize(struct sway_container *container,
263 double amount, enum wlr_edges edge) {
264 bool layout_match = true;
265 wlr_log(WLR_DEBUG, "Resizing %p with amount: %f", container, amount);
266 if (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT) {
267 container->width += amount;
268 layout_match = container->layout == L_HORIZ;
269 } else if (edge == WLR_EDGE_TOP || edge == WLR_EDGE_BOTTOM) {
270 container->height += amount;
271 layout_match = container->layout == L_VERT;
272 }
273 if (container->children) {
274 for (int i = 0; i < container->children->length; i++) {
275 struct sway_container *child = container->children->items[i];
276 double amt = layout_match ?
277 amount / container->children->length : amount;
278 container_recursive_resize(child, amt, edge);
279 }
280 }
281}
282
283static void swap_places(struct sway_container *con1,
284 struct sway_container *con2) {
285 struct sway_container *temp = malloc(sizeof(struct sway_container));
286 temp->x = con1->x;
287 temp->y = con1->y;
288 temp->width = con1->width;
289 temp->height = con1->height;
290 temp->parent = con1->parent;
291
292 con1->x = con2->x;
293 con1->y = con2->y;
294 con1->width = con2->width;
295 con1->height = con2->height;
296
297 con2->x = temp->x;
298 con2->y = temp->y;
299 con2->width = temp->width;
300 con2->height = temp->height;
301
302 int temp_index = container_sibling_index(con1);
303 container_insert_child(con2->parent, con1, container_sibling_index(con2));
304 container_insert_child(temp->parent, con2, temp_index);
305
306 free(temp);
307}
308
309static void swap_focus(struct sway_container *con1,
310 struct sway_container *con2, struct sway_seat *seat,
311 struct sway_container *focus) {
312 if (focus == con1 || focus == con2) {
313 struct sway_container *ws1 = container_parent(con1, C_WORKSPACE);
314 struct sway_container *ws2 = container_parent(con2, C_WORKSPACE);
315 if (focus == con1 && (con2->parent->layout == L_TABBED
316 || con2->parent->layout == L_STACKED)) {
317 if (workspace_is_visible(ws2)) {
318 seat_set_focus_warp(seat, con2, false, true);
319 }
320 seat_set_focus(seat, ws1 != ws2 ? con2 : con1);
321 } else if (focus == con2 && (con1->parent->layout == L_TABBED
322 || con1->parent->layout == L_STACKED)) {
323 if (workspace_is_visible(ws1)) {
324 seat_set_focus_warp(seat, con1, false, true);
325 }
326 seat_set_focus(seat, ws1 != ws2 ? con1 : con2);
327 } else if (ws1 != ws2) {
328 seat_set_focus(seat, focus == con1 ? con2 : con1);
329 } else {
330 seat_set_focus(seat, focus);
331 }
332 } else {
333 seat_set_focus(seat, focus);
334 }
335}
336
337void container_swap(struct sway_container *con1, struct sway_container *con2) {
338 if (!sway_assert(con1 && con2, "Cannot swap with nothing")) {
339 return;
340 }
341 if (!sway_assert(con1->type >= C_CONTAINER && con2->type >= C_CONTAINER,
342 "Can only swap containers and views")) {
343 return;
344 }
345 if (!sway_assert(!container_has_ancestor(con1, con2)
346 && !container_has_ancestor(con2, con1),
347 "Cannot swap ancestor and descendant")) {
348 return;
349 }
350 if (!sway_assert(!container_is_floating(con1)
351 && !container_is_floating(con2),
352 "Swapping with floating containers is not supported")) {
353 return;
354 }
355
356 wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
357
358 int fs1 = con1->is_fullscreen;
359 int fs2 = con2->is_fullscreen;
360 if (fs1) {
361 container_set_fullscreen(con1, false);
362 }
363 if (fs2) {
364 container_set_fullscreen(con2, false);
365 }
366
367 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
368 struct sway_container *focus = seat_get_focus(seat);
369 struct sway_container *vis1 = container_parent(
370 seat_get_focus_inactive(seat, container_parent(con1, C_OUTPUT)),
371 C_WORKSPACE);
372 struct sway_container *vis2 = container_parent(
373 seat_get_focus_inactive(seat, container_parent(con2, C_OUTPUT)),
374 C_WORKSPACE);
375
376 char *stored_prev_name = NULL;
377 if (prev_workspace_name) {
378 stored_prev_name = strdup(prev_workspace_name);
379 }
380
381 swap_places(con1, con2);
382
383 if (!workspace_is_visible(vis1)) {
384 seat_set_focus(seat, seat_get_focus_inactive(seat, vis1));
385 }
386 if (!workspace_is_visible(vis2)) {
387 seat_set_focus(seat, seat_get_focus_inactive(seat, vis2));
388 }
389
390 swap_focus(con1, con2, seat, focus);
391
392 if (stored_prev_name) {
393 free(prev_workspace_name);
394 prev_workspace_name = stored_prev_name;
395 }
396
397 if (fs1) {
398 container_set_fullscreen(con2, true);
399 }
400 if (fs2) {
401 container_set_fullscreen(con1, true);
402 }
403}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index ba4a880f..2870d4f5 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -18,7 +18,6 @@
18#include "sway/input/seat.h" 18#include "sway/input/seat.h"
19#include "sway/tree/arrange.h" 19#include "sway/tree/arrange.h"
20#include "sway/tree/container.h" 20#include "sway/tree/container.h"
21#include "sway/tree/layout.h"
22#include "sway/tree/view.h" 21#include "sway/tree/view.h"
23#include "sway/tree/workspace.h" 22#include "sway/tree/workspace.h"
24#include "sway/config.h" 23#include "sway/config.h"