aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-06 22:57:34 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-09 10:11:25 +1000
commitbb66e6d578fdc68fb33d0fde921390d74f20bb31 (patch)
tree99d3763eee97acb870c16a762c0ee40af787c295 /sway
parentMake main properties be the pending state (diff)
downloadsway-bb66e6d578fdc68fb33d0fde921390d74f20bb31.tar.gz
sway-bb66e6d578fdc68fb33d0fde921390d74f20bb31.tar.zst
sway-bb66e6d578fdc68fb33d0fde921390d74f20bb31.zip
Refactor everything that needs to arrange windows
* The arrange_foo functions are now replaced with arrange_and_commit, or with manually created transactions and arrange_windows x2. * The arrange functions are now only called from the highest level functions rather than from both high level and low level functions. * Due to the previous point, view_set_fullscreen_raw and view_set_fullscreen are both merged into one function again. * Floating and fullscreen are now working with transactions.
Diffstat (limited to 'sway')
-rw-r--r--sway/commands/border.c7
-rw-r--r--sway/commands/floating.c3
-rw-r--r--sway/commands/fullscreen.c4
-rw-r--r--sway/commands/layout.c2
-rw-r--r--sway/commands/move.c41
-rw-r--r--sway/commands/reload.c2
-rw-r--r--sway/commands/resize.c2
-rw-r--r--sway/commands/split.c2
-rw-r--r--sway/commands/swap.c12
-rw-r--r--sway/config.c4
-rw-r--r--sway/desktop/layer_shell.c2
-rw-r--r--sway/desktop/output.c8
-rw-r--r--sway/desktop/transaction.c19
-rw-r--r--sway/desktop/xdg_shell.c18
-rw-r--r--sway/desktop/xdg_shell_v6.c20
-rw-r--r--sway/desktop/xwayland.c3
-rw-r--r--sway/tree/arrange.c63
-rw-r--r--sway/tree/container.c10
-rw-r--r--sway/tree/layout.c71
-rw-r--r--sway/tree/view.c49
-rw-r--r--sway/tree/workspace.c2
21 files changed, 186 insertions, 158 deletions
diff --git a/sway/commands/border.c b/sway/commands/border.c
index 0b059562..6db85395 100644
--- a/sway/commands/border.c
+++ b/sway/commands/border.c
@@ -3,6 +3,7 @@
3#include "sway/config.h" 3#include "sway/config.h"
4#include "sway/input/cursor.h" 4#include "sway/input/cursor.h"
5#include "sway/input/input-manager.h" 5#include "sway/input/input-manager.h"
6#include "sway/tree/arrange.h"
6#include "sway/tree/container.h" 7#include "sway/tree/container.h"
7#include "sway/tree/view.h" 8#include "sway/tree/view.h"
8 9
@@ -38,13 +39,11 @@ struct cmd_results *cmd_border(int argc, char **argv) {
38 } 39 }
39 40
40 if (container_is_floating(view->swayc)) { 41 if (container_is_floating(view->swayc)) {
41 container_damage_whole(view->swayc);
42 container_set_geometry_from_floating_view(view->swayc); 42 container_set_geometry_from_floating_view(view->swayc);
43 container_damage_whole(view->swayc);
44 } else {
45 view_autoconfigure(view);
46 } 43 }
47 44
45 arrange_and_commit(view->swayc);
46
48 struct sway_seat *seat = input_manager_current_seat(input_manager); 47 struct sway_seat *seat = input_manager_current_seat(input_manager);
49 if (seat->cursor) { 48 if (seat->cursor) {
50 cursor_send_pointer_motion(seat->cursor, 0, false); 49 cursor_send_pointer_motion(seat->cursor, 0, false);
diff --git a/sway/commands/floating.c b/sway/commands/floating.c
index 46b761da..e6003521 100644
--- a/sway/commands/floating.c
+++ b/sway/commands/floating.c
@@ -36,5 +36,8 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
36 36
37 container_set_floating(container, wants_floating); 37 container_set_floating(container, wants_floating);
38 38
39 struct sway_container *workspace = container_parent(container, C_WORKSPACE);
40 arrange_and_commit(workspace);
41
39 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 42 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
40} 43}
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c
index ec9ec276..1a4d8b41 100644
--- a/sway/commands/fullscreen.c
+++ b/sway/commands/fullscreen.c
@@ -1,6 +1,7 @@
1#include "log.h" 1#include "log.h"
2#include "sway/commands.h" 2#include "sway/commands.h"
3#include "sway/config.h" 3#include "sway/config.h"
4#include "sway/tree/arrange.h"
4#include "sway/tree/container.h" 5#include "sway/tree/container.h"
5#include "sway/tree/view.h" 6#include "sway/tree/view.h"
6#include "sway/tree/layout.h" 7#include "sway/tree/layout.h"
@@ -32,5 +33,8 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
32 33
33 view_set_fullscreen(view, wants_fullscreen); 34 view_set_fullscreen(view, wants_fullscreen);
34 35
36 struct sway_container *workspace = container_parent(container, C_WORKSPACE);
37 arrange_and_commit(workspace->parent);
38
35 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 39 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
36} 40}
diff --git a/sway/commands/layout.c b/sway/commands/layout.c
index a009e38f..9945fa5c 100644
--- a/sway/commands/layout.c
+++ b/sway/commands/layout.c
@@ -49,7 +49,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
49 } 49 }
50 50
51 container_notify_subtree_changed(parent); 51 container_notify_subtree_changed(parent);
52 arrange_children_of(parent); 52 arrange_and_commit(parent);
53 53
54 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 54 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
55} 55}
diff --git a/sway/commands/move.c b/sway/commands/move.c
index dc9a6f6f..2c9fb77a 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -5,8 +5,10 @@
5#include <wlr/types/wlr_output_layout.h> 5#include <wlr/types/wlr_output_layout.h>
6#include <wlr/util/log.h> 6#include <wlr/util/log.h>
7#include "sway/commands.h" 7#include "sway/commands.h"
8#include "sway/desktop/transaction.h"
8#include "sway/input/seat.h" 9#include "sway/input/seat.h"
9#include "sway/output.h" 10#include "sway/output.h"
11#include "sway/tree/arrange.h"
10#include "sway/tree/container.h" 12#include "sway/tree/container.h"
11#include "sway/tree/layout.h" 13#include "sway/tree/layout.h"
12#include "sway/tree/workspace.h" 14#include "sway/tree/workspace.h"
@@ -96,6 +98,12 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
96 seat_set_focus(config->handler_context.seat, focus); 98 seat_set_focus(config->handler_context.seat, focus);
97 container_reap_empty(old_parent); 99 container_reap_empty(old_parent);
98 container_reap_empty(destination->parent); 100 container_reap_empty(destination->parent);
101
102 struct sway_transaction *txn = transaction_create();
103 arrange_windows(old_parent, txn);
104 arrange_windows(destination->parent, txn);
105 transaction_commit(txn);
106
99 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 107 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
100 } else if (strcasecmp(argv[1], "to") == 0 108 } else if (strcasecmp(argv[1], "to") == 0
101 && strcasecmp(argv[2], "output") == 0) { 109 && strcasecmp(argv[2], "output") == 0) {
@@ -125,6 +133,12 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
125 seat_set_focus(config->handler_context.seat, old_parent); 133 seat_set_focus(config->handler_context.seat, old_parent);
126 container_reap_empty(old_parent); 134 container_reap_empty(old_parent);
127 container_reap_empty(focus->parent); 135 container_reap_empty(focus->parent);
136
137 struct sway_transaction *txn = transaction_create();
138 arrange_windows(old_parent, txn);
139 arrange_windows(focus->parent, txn);
140 transaction_commit(txn);
141
128 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 142 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
129 } 143 }
130 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 144 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
@@ -152,9 +166,28 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current,
152 current = container_parent(current, C_WORKSPACE); 166 current = container_parent(current, C_WORKSPACE);
153 } 167 }
154 container_move_to(current, destination); 168 container_move_to(current, destination);
169
170 struct sway_transaction *txn = transaction_create();
171 arrange_windows(source, txn);
172 arrange_windows(destination, txn);
173 transaction_commit(txn);
174
155 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 175 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
156} 176}
157 177
178static void move_in_direction(struct sway_container *container,
179 enum wlr_direction direction, int move_amt) {
180 struct sway_container *old_parent = container->parent;
181 container_move(container, direction, move_amt);
182
183 struct sway_transaction *txn = transaction_create();
184 arrange_windows(old_parent, txn);
185 if (container->parent != old_parent) {
186 arrange_windows(container->parent, txn);
187 }
188 transaction_commit(txn);
189}
190
158struct cmd_results *cmd_move(int argc, char **argv) { 191struct cmd_results *cmd_move(int argc, char **argv) {
159 struct cmd_results *error = NULL; 192 struct cmd_results *error = NULL;
160 int move_amt = 10; 193 int move_amt = 10;
@@ -173,13 +206,13 @@ struct cmd_results *cmd_move(int argc, char **argv) {
173 } 206 }
174 207
175 if (strcasecmp(argv[0], "left") == 0) { 208 if (strcasecmp(argv[0], "left") == 0) {
176 container_move(current, MOVE_LEFT, move_amt); 209 move_in_direction(current, MOVE_LEFT, move_amt);
177 } else if (strcasecmp(argv[0], "right") == 0) { 210 } else if (strcasecmp(argv[0], "right") == 0) {
178 container_move(current, MOVE_RIGHT, move_amt); 211 move_in_direction(current, MOVE_RIGHT, move_amt);
179 } else if (strcasecmp(argv[0], "up") == 0) { 212 } else if (strcasecmp(argv[0], "up") == 0) {
180 container_move(current, MOVE_UP, move_amt); 213 move_in_direction(current, MOVE_UP, move_amt);
181 } else if (strcasecmp(argv[0], "down") == 0) { 214 } else if (strcasecmp(argv[0], "down") == 0) {
182 container_move(current, MOVE_DOWN, move_amt); 215 move_in_direction(current, MOVE_DOWN, move_amt);
183 } else if (strcasecmp(argv[0], "container") == 0 216 } else if (strcasecmp(argv[0], "container") == 0
184 || strcasecmp(argv[0], "window") == 0) { 217 || strcasecmp(argv[0], "window") == 0) {
185 return cmd_move_container(current, argc, argv); 218 return cmd_move_container(current, argc, argv);
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 092dd46f..9fc213c4 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -12,6 +12,6 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
12 } 12 }
13 13
14 load_swaybars(); 14 load_swaybars();
15 arrange_root(); 15 arrange_and_commit(&root_container);
16 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 16 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
17} 17}
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index 29637953..6357343e 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -182,7 +182,7 @@ static void resize_tiled(int amount, enum resize_axis axis) {
182 } 182 }
183 } 183 }
184 184
185 arrange_children_of(parent->parent); 185 arrange_and_commit(parent->parent);
186} 186}
187 187
188static void resize(int amount, enum resize_axis axis, enum resize_unit unit) { 188static void resize(int amount, enum resize_axis axis, enum resize_unit unit) {
diff --git a/sway/commands/split.c b/sway/commands/split.c
index 57e42a5a..7ea14953 100644
--- a/sway/commands/split.c
+++ b/sway/commands/split.c
@@ -16,7 +16,7 @@ static struct cmd_results *do_split(int layout) {
16 } 16 }
17 struct sway_container *parent = container_split(con, layout); 17 struct sway_container *parent = container_split(con, layout);
18 container_create_notify(parent); 18 container_create_notify(parent);
19 arrange_children_of(parent); 19 arrange_and_commit(parent);
20 20
21 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 21 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
22} 22}
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index e8dfc57f..e052058f 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -1,6 +1,8 @@
1#include <strings.h> 1#include <strings.h>
2#include <wlr/util/log.h> 2#include <wlr/util/log.h>
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/desktop/transaction.h"
5#include "sway/tree/arrange.h"
4#include "sway/tree/layout.h" 6#include "sway/tree/layout.h"
5#include "sway/tree/view.h" 7#include "sway/tree/view.h"
6#include "stringop.h" 8#include "stringop.h"
@@ -76,5 +78,15 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
76 } 78 }
77 79
78 container_swap(current, other); 80 container_swap(current, other);
81
82 struct sway_transaction *txn = transaction_create();
83 arrange_windows(current->parent, txn);
84
85 if (other->parent != current->parent) {
86 arrange_windows(other->parent, txn);
87 }
88
89 transaction_commit(txn);
90
79 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 91 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
80} 92}
diff --git a/sway/config.c b/sway/config.c
index 949c5cd3..12a02163 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -531,7 +531,7 @@ static int detect_brace_on_following_line(FILE *file, char *line,
531 } while (peeked && strlen(peeked) == 0); 531 } while (peeked && strlen(peeked) == 0);
532 532
533 if (peeked && strlen(peeked) == 1 && peeked[0] == '{') { 533 if (peeked && strlen(peeked) == 1 && peeked[0] == '{') {
534 fseek(file, position, SEEK_SET); 534 fseek(file, position, SEEK_SET);
535 } else { 535 } else {
536 lines = 0; 536 lines = 0;
537 } 537 }
@@ -735,6 +735,6 @@ void config_update_font_height(bool recalculate) {
735 } 735 }
736 736
737 if (config->font_height != prev_max_height) { 737 if (config->font_height != prev_max_height) {
738 arrange_root(); 738 arrange_and_commit(&root_container);
739 } 739 }
740} 740}
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index 3accdefb..fe5fc316 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -176,7 +176,7 @@ void arrange_layers(struct sway_output *output) {
176 sizeof(struct wlr_box)) != 0) { 176 sizeof(struct wlr_box)) != 0) {
177 wlr_log(L_DEBUG, "Usable area changed, rearranging output"); 177 wlr_log(L_DEBUG, "Usable area changed, rearranging output");
178 memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); 178 memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box));
179 arrange_output(output->swayc); 179 arrange_and_commit(output->swayc);
180 } 180 }
181 181
182 // Arrange non-exlusive surfaces from top->bottom 182 // Arrange non-exlusive surfaces from top->bottom
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 8af05bc3..29efdd50 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -1238,13 +1238,13 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
1238static void handle_mode(struct wl_listener *listener, void *data) { 1238static void handle_mode(struct wl_listener *listener, void *data) {
1239 struct sway_output *output = wl_container_of(listener, output, mode); 1239 struct sway_output *output = wl_container_of(listener, output, mode);
1240 arrange_layers(output); 1240 arrange_layers(output);
1241 arrange_output(output->swayc); 1241 arrange_and_commit(output->swayc);
1242} 1242}
1243 1243
1244static void handle_transform(struct wl_listener *listener, void *data) { 1244static void handle_transform(struct wl_listener *listener, void *data) {
1245 struct sway_output *output = wl_container_of(listener, output, transform); 1245 struct sway_output *output = wl_container_of(listener, output, transform);
1246 arrange_layers(output); 1246 arrange_layers(output);
1247 arrange_output(output->swayc); 1247 arrange_and_commit(output->swayc);
1248} 1248}
1249 1249
1250static void handle_scale_iterator(struct sway_container *view, void *data) { 1250static void handle_scale_iterator(struct sway_container *view, void *data) {
@@ -1254,8 +1254,8 @@ static void handle_scale_iterator(struct sway_container *view, void *data) {
1254static void handle_scale(struct wl_listener *listener, void *data) { 1254static void handle_scale(struct wl_listener *listener, void *data) {
1255 struct sway_output *output = wl_container_of(listener, output, scale); 1255 struct sway_output *output = wl_container_of(listener, output, scale);
1256 arrange_layers(output); 1256 arrange_layers(output);
1257 arrange_output(output->swayc);
1258 container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL); 1257 container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL);
1258 arrange_and_commit(output->swayc);
1259} 1259}
1260 1260
1261void handle_new_output(struct wl_listener *listener, void *data) { 1261void handle_new_output(struct wl_listener *listener, void *data) {
@@ -1314,5 +1314,5 @@ void output_enable(struct sway_output *output) {
1314 output->damage_destroy.notify = damage_handle_destroy; 1314 output->damage_destroy.notify = damage_handle_destroy;
1315 1315
1316 arrange_layers(output); 1316 arrange_layers(output);
1317 arrange_root(); 1317 arrange_and_commit(&root_container);
1318} 1318}
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 313e707b..ee9883e2 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -17,6 +17,13 @@
17 */ 17 */
18#define TIMEOUT_MS 200 18#define TIMEOUT_MS 200
19 19
20struct sway_transaction {
21 struct wl_event_source *timer;
22 list_t *instructions; // struct sway_transaction_instruction *
23 list_t *damage; // struct wlr_box *
24 size_t num_waiting;
25};
26
20struct sway_transaction_instruction { 27struct sway_transaction_instruction {
21 struct sway_transaction *transaction; 28 struct sway_transaction *transaction;
22 struct sway_container *container; 29 struct sway_container *container;
@@ -162,16 +169,18 @@ void transaction_commit(struct sway_transaction *transaction) {
162 for (int i = 0; i < transaction->instructions->length; ++i) { 169 for (int i = 0; i < transaction->instructions->length; ++i) {
163 struct sway_transaction_instruction *instruction = 170 struct sway_transaction_instruction *instruction =
164 transaction->instructions->items[i]; 171 transaction->instructions->items[i];
165 if (instruction->container->type == C_VIEW) { 172 struct sway_container *con = instruction->container;
166 struct sway_view *view = instruction->container->sway_view; 173 if (con->type == C_VIEW &&
167 instruction->serial = view_configure(view, 174 (con->current.view_width != instruction->state.view_width ||
175 con->current.view_height != instruction->state.view_height)) {
176 instruction->serial = view_configure(con->sway_view,
168 instruction->state.view_x, 177 instruction->state.view_x,
169 instruction->state.view_y, 178 instruction->state.view_y,
170 instruction->state.view_width, 179 instruction->state.view_width,
171 instruction->state.view_height); 180 instruction->state.view_height);
172 if (instruction->serial) { 181 if (instruction->serial) {
173 save_view_texture(view); 182 save_view_texture(con->sway_view);
174 list_add(view->instructions, instruction); 183 list_add(con->sway_view->instructions, instruction);
175 ++transaction->num_waiting; 184 ++transaction->num_waiting;
176 } 185 }
177 } 186 }
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index f43a0a1b..d22c967c 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -5,10 +5,10 @@
5#include <wlr/types/wlr_xdg_shell.h> 5#include <wlr/types/wlr_xdg_shell.h>
6#include <wlr/util/edges.h> 6#include <wlr/util/edges.h>
7#include "log.h" 7#include "log.h"
8#include "sway/desktop/transaction.h"
9#include "sway/input/input-manager.h" 8#include "sway/input/input-manager.h"
10#include "sway/input/seat.h" 9#include "sway/input/seat.h"
11#include "sway/server.h" 10#include "sway/server.h"
11#include "sway/tree/arrange.h"
12#include "sway/tree/container.h" 12#include "sway/tree/container.h"
13#include "sway/tree/layout.h" 13#include "sway/tree/layout.h"
14#include "sway/tree/view.h" 14#include "sway/tree/view.h"
@@ -210,8 +210,14 @@ static void handle_map(struct wl_listener *listener, void *data) {
210 view->natural_width = view->wlr_xdg_surface->surface->current->width; 210 view->natural_width = view->wlr_xdg_surface->surface->current->width;
211 view->natural_height = view->wlr_xdg_surface->surface->current->height; 211 view->natural_height = view->wlr_xdg_surface->surface->current->height;
212 } 212 }
213
213 view_map(view, view->wlr_xdg_surface->surface); 214 view_map(view, view->wlr_xdg_surface->surface);
214 215
216 if (xdg_surface->toplevel->client_pending.fullscreen) {
217 view_set_fullscreen(view, true);
218 }
219 arrange_and_commit(view->swayc->parent);
220
215 xdg_shell_view->commit.notify = handle_commit; 221 xdg_shell_view->commit.notify = handle_commit;
216 wl_signal_add(&xdg_surface->surface->events.commit, 222 wl_signal_add(&xdg_surface->surface->events.commit,
217 &xdg_shell_view->commit); 223 &xdg_shell_view->commit);
@@ -219,10 +225,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
219 xdg_shell_view->new_popup.notify = handle_new_popup; 225 xdg_shell_view->new_popup.notify = handle_new_popup;
220 wl_signal_add(&xdg_surface->events.new_popup, 226 wl_signal_add(&xdg_surface->events.new_popup,
221 &xdg_shell_view->new_popup); 227 &xdg_shell_view->new_popup);
222
223 if (xdg_surface->toplevel->client_pending.fullscreen) {
224 view_set_fullscreen(view, true);
225 }
226} 228}
227 229
228static void handle_destroy(struct wl_listener *listener, void *data) { 230static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -237,6 +239,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
237 struct wlr_xdg_toplevel_set_fullscreen_event *e = data; 239 struct wlr_xdg_toplevel_set_fullscreen_event *e = data;
238 struct wlr_xdg_surface *xdg_surface = 240 struct wlr_xdg_surface *xdg_surface =
239 xdg_shell_view->view.wlr_xdg_surface; 241 xdg_shell_view->view.wlr_xdg_surface;
242 struct sway_view *view = &xdg_shell_view->view;
240 243
241 if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL, 244 if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL,
242 "xdg_shell requested fullscreen of surface with role %i", 245 "xdg_shell requested fullscreen of surface with role %i",
@@ -247,7 +250,10 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
247 return; 250 return;
248 } 251 }
249 252
250 view_set_fullscreen(&xdg_shell_view->view, e->fullscreen); 253 view_set_fullscreen(view, e->fullscreen);
254
255 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
256 arrange_and_commit(ws);
251} 257}
252 258
253void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { 259void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index bce59174..7ec9e6cb 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -3,10 +3,10 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <wayland-server.h> 4#include <wayland-server.h>
5#include <wlr/types/wlr_xdg_shell_v6.h> 5#include <wlr/types/wlr_xdg_shell_v6.h>
6#include "sway/desktop/transaction.h" 6#include "sway/server.h"
7#include "sway/tree/arrange.h"
7#include "sway/tree/container.h" 8#include "sway/tree/container.h"
8#include "sway/tree/layout.h" 9#include "sway/tree/layout.h"
9#include "sway/server.h"
10#include "sway/tree/view.h" 10#include "sway/tree/view.h"
11#include "sway/input/seat.h" 11#include "sway/input/seat.h"
12#include "sway/input/input-manager.h" 12#include "sway/input/input-manager.h"
@@ -210,8 +210,14 @@ static void handle_map(struct wl_listener *listener, void *data) {
210 view->natural_width = view->wlr_xdg_surface_v6->surface->current->width; 210 view->natural_width = view->wlr_xdg_surface_v6->surface->current->width;
211 view->natural_height = view->wlr_xdg_surface_v6->surface->current->height; 211 view->natural_height = view->wlr_xdg_surface_v6->surface->current->height;
212 } 212 }
213
213 view_map(view, view->wlr_xdg_surface_v6->surface); 214 view_map(view, view->wlr_xdg_surface_v6->surface);
214 215
216 if (xdg_surface->toplevel->client_pending.fullscreen) {
217 view_set_fullscreen(view, true);
218 }
219 arrange_and_commit(view->swayc->parent);
220
215 xdg_shell_v6_view->commit.notify = handle_commit; 221 xdg_shell_v6_view->commit.notify = handle_commit;
216 wl_signal_add(&xdg_surface->surface->events.commit, 222 wl_signal_add(&xdg_surface->surface->events.commit,
217 &xdg_shell_v6_view->commit); 223 &xdg_shell_v6_view->commit);
@@ -219,10 +225,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
219 xdg_shell_v6_view->new_popup.notify = handle_new_popup; 225 xdg_shell_v6_view->new_popup.notify = handle_new_popup;
220 wl_signal_add(&xdg_surface->events.new_popup, 226 wl_signal_add(&xdg_surface->events.new_popup,
221 &xdg_shell_v6_view->new_popup); 227 &xdg_shell_v6_view->new_popup);
222
223 if (xdg_surface->toplevel->client_pending.fullscreen) {
224 view_set_fullscreen(view, true);
225 }
226} 228}
227 229
228static void handle_destroy(struct wl_listener *listener, void *data) { 230static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -237,6 +239,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
237 struct wlr_xdg_toplevel_v6_set_fullscreen_event *e = data; 239 struct wlr_xdg_toplevel_v6_set_fullscreen_event *e = data;
238 struct wlr_xdg_surface_v6 *xdg_surface = 240 struct wlr_xdg_surface_v6 *xdg_surface =
239 xdg_shell_v6_view->view.wlr_xdg_surface_v6; 241 xdg_shell_v6_view->view.wlr_xdg_surface_v6;
242 struct sway_view *view = &xdg_shell_v6_view->view;
240 243
241 if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL, 244 if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL,
242 "xdg_shell_v6 requested fullscreen of surface with role %i", 245 "xdg_shell_v6 requested fullscreen of surface with role %i",
@@ -247,7 +250,10 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
247 return; 250 return;
248 } 251 }
249 252
250 view_set_fullscreen(&xdg_shell_v6_view->view, e->fullscreen); 253 view_set_fullscreen(view, e->fullscreen);
254
255 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
256 arrange_and_commit(ws);
251} 257}
252 258
253void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { 259void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index d8442530..70929d48 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -11,6 +11,7 @@
11#include "sway/input/seat.h" 11#include "sway/input/seat.h"
12#include "sway/output.h" 12#include "sway/output.h"
13#include "sway/server.h" 13#include "sway/server.h"
14#include "sway/tree/arrange.h"
14#include "sway/tree/container.h" 15#include "sway/tree/container.h"
15#include "sway/tree/layout.h" 16#include "sway/tree/layout.h"
16#include "sway/tree/view.h" 17#include "sway/tree/view.h"
@@ -292,6 +293,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
292 if (xsurface->fullscreen) { 293 if (xsurface->fullscreen) {
293 view_set_fullscreen(view, true); 294 view_set_fullscreen(view, true);
294 } 295 }
296 arrange_and_commit(view->swayc);
295} 297}
296 298
297static void handle_destroy(struct wl_listener *listener, void *data) { 299static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -325,6 +327,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
325 return; 327 return;
326 } 328 }
327 view_set_fullscreen(view, xsurface->fullscreen); 329 view_set_fullscreen(view, xsurface->fullscreen);
330 arrange_and_commit(view->swayc);
328} 331}
329 332
330static void handle_set_title(struct wl_listener *listener, void *data) { 333static void handle_set_title(struct wl_listener *listener, void *data) {
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index cf7ce61c..e138410d 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -138,7 +138,23 @@ static void apply_tabbed_or_stacked_layout(struct sway_container *parent) {
138 } 138 }
139} 139}
140 140
141static void _arrange_children_of(struct sway_container *parent, 141static void arrange_children_of(struct sway_container *parent,
142 struct sway_transaction *transaction);
143
144static void arrange_floating(struct sway_container *floating,
145 struct sway_transaction *transaction) {
146 for (int i = 0; i < floating->children->length; ++i) {
147 struct sway_container *floater = floating->children->items[i];
148 if (floater->type == C_VIEW) {
149 view_autoconfigure(floater->sway_view);
150 } else {
151 arrange_children_of(floater, transaction);
152 }
153 transaction_add_container(transaction, floater);
154 }
155}
156
157static void arrange_children_of(struct sway_container *parent,
142 struct sway_transaction *transaction) { 158 struct sway_transaction *transaction) {
143 if (config->reloading) { 159 if (config->reloading) {
144 return; 160 return;
@@ -162,7 +178,8 @@ static void _arrange_children_of(struct sway_container *parent,
162 apply_horiz_layout(parent); 178 apply_horiz_layout(parent);
163 break; 179 break;
164 case L_FLOATING: 180 case L_FLOATING:
165 sway_assert(false, "Didn't expect to see floating here"); 181 arrange_floating(parent, transaction);
182 break;
166 } 183 }
167 184
168 // Recurse into child containers 185 // Recurse into child containers
@@ -171,13 +188,13 @@ static void _arrange_children_of(struct sway_container *parent,
171 if (child->type == C_VIEW) { 188 if (child->type == C_VIEW) {
172 view_autoconfigure(child->sway_view); 189 view_autoconfigure(child->sway_view);
173 } else { 190 } else {
174 _arrange_children_of(child, transaction); 191 arrange_children_of(child, transaction);
175 } 192 }
176 transaction_add_container(transaction, child); 193 transaction_add_container(transaction, child);
177 } 194 }
178} 195}
179 196
180static void _arrange_workspace(struct sway_container *workspace, 197static void arrange_workspace(struct sway_container *workspace,
181 struct sway_transaction *transaction) { 198 struct sway_transaction *transaction) {
182 if (config->reloading) { 199 if (config->reloading) {
183 return; 200 return;
@@ -193,10 +210,11 @@ static void _arrange_workspace(struct sway_container *workspace,
193 transaction_add_container(transaction, workspace); 210 transaction_add_container(transaction, workspace);
194 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, 211 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
195 workspace->x, workspace->y); 212 workspace->x, workspace->y);
196 _arrange_children_of(workspace, transaction); 213 arrange_floating(workspace->sway_workspace->floating, transaction);
214 arrange_children_of(workspace, transaction);
197} 215}
198 216
199static void _arrange_output(struct sway_container *output, 217static void arrange_output(struct sway_container *output,
200 struct sway_transaction *transaction) { 218 struct sway_transaction *transaction) {
201 if (config->reloading) { 219 if (config->reloading) {
202 return; 220 return;
@@ -213,11 +231,11 @@ static void _arrange_output(struct sway_container *output,
213 output->name, output->x, output->y); 231 output->name, output->x, output->y);
214 for (int i = 0; i < output->children->length; ++i) { 232 for (int i = 0; i < output->children->length; ++i) {
215 struct sway_container *workspace = output->children->items[i]; 233 struct sway_container *workspace = output->children->items[i];
216 _arrange_workspace(workspace, transaction); 234 arrange_workspace(workspace, transaction);
217 } 235 }
218} 236}
219 237
220static void _arrange_root(struct sway_transaction *transaction) { 238static void arrange_root(struct sway_transaction *transaction) {
221 if (config->reloading) { 239 if (config->reloading) {
222 return; 240 return;
223 } 241 }
@@ -232,7 +250,7 @@ static void _arrange_root(struct sway_transaction *transaction) {
232 transaction_add_container(transaction, &root_container); 250 transaction_add_container(transaction, &root_container);
233 for (int i = 0; i < root_container.children->length; ++i) { 251 for (int i = 0; i < root_container.children->length; ++i) {
234 struct sway_container *output = root_container.children->items[i]; 252 struct sway_container *output = root_container.children->items[i];
235 _arrange_output(output, transaction); 253 arrange_output(output, transaction);
236 } 254 }
237} 255}
238 256
@@ -240,19 +258,21 @@ void arrange_windows(struct sway_container *container,
240 struct sway_transaction *transaction) { 258 struct sway_transaction *transaction) {
241 switch (container->type) { 259 switch (container->type) {
242 case C_ROOT: 260 case C_ROOT:
243 _arrange_root(transaction); 261 arrange_root(transaction);
244 break; 262 break;
245 case C_OUTPUT: 263 case C_OUTPUT:
246 _arrange_output(container, transaction); 264 arrange_output(container, transaction);
247 break; 265 break;
248 case C_WORKSPACE: 266 case C_WORKSPACE:
249 _arrange_workspace(container, transaction); 267 arrange_workspace(container, transaction);
250 break; 268 break;
251 case C_CONTAINER: 269 case C_CONTAINER:
252 _arrange_children_of(container, transaction); 270 arrange_children_of(container, transaction);
253 transaction_add_container(transaction, container); 271 transaction_add_container(transaction, container);
254 break; 272 break;
255 case C_VIEW: 273 case C_VIEW:
274 view_autoconfigure(container->sway_view);
275 transaction_add_container(transaction, container);
256 break; 276 break;
257 case C_TYPES: 277 case C_TYPES:
258 break; 278 break;
@@ -265,20 +285,3 @@ void arrange_and_commit(struct sway_container *container) {
265 arrange_windows(container, transaction); 285 arrange_windows(container, transaction);
266 transaction_commit(transaction); 286 transaction_commit(transaction);
267} 287}
268
269// These functions are only temporary
270void arrange_root() {
271 arrange_and_commit(&root_container);
272}
273
274void arrange_output(struct sway_container *container) {
275 arrange_and_commit(container);
276}
277
278void arrange_workspace(struct sway_container *container) {
279 arrange_and_commit(container);
280}
281
282void arrange_children_of(struct sway_container *container) {
283 arrange_and_commit(container);
284}
diff --git a/sway/tree/container.c b/sway/tree/container.c
index e6956f5c..d312eb60 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -204,6 +204,7 @@ static struct sway_container *container_workspace_destroy(
204 container_move_to(floating->children->items[i], 204 container_move_to(floating->children->items[i],
205 new_workspace->sway_workspace->floating); 205 new_workspace->sway_workspace->floating);
206 } 206 }
207 arrange_and_commit(new_workspace);
207 } 208 }
208 209
209 struct sway_workspace *sway_workspace = workspace->sway_workspace; 210 struct sway_workspace *sway_workspace = workspace->sway_workspace;
@@ -264,10 +265,10 @@ static struct sway_container *container_output_destroy(
264 } 265 }
265 266
266 container_sort_workspaces(new_output); 267 container_sort_workspaces(new_output);
267 arrange_output(new_output);
268 } 268 }
269 } 269 }
270 } 270 }
271 arrange_and_commit(&root_container);
271 272
272 wl_list_remove(&output->sway_output->mode.link); 273 wl_list_remove(&output->sway_output->mode.link);
273 wl_list_remove(&output->sway_output->transform.link); 274 wl_list_remove(&output->sway_output->transform.link);
@@ -924,13 +925,12 @@ void container_set_floating(struct sway_container *container, bool enable) {
924 925
925 struct sway_container *workspace = container_parent(container, C_WORKSPACE); 926 struct sway_container *workspace = container_parent(container, C_WORKSPACE);
926 struct sway_seat *seat = input_manager_current_seat(input_manager); 927 struct sway_seat *seat = input_manager_current_seat(input_manager);
927 container_damage_whole(container);
928 928
929 if (enable) { 929 if (enable) {
930 container_remove_child(container); 930 container_remove_child(container);
931 container_add_child(workspace->sway_workspace->floating, container); 931 container_add_child(workspace->sway_workspace->floating, container);
932 if (container->type == C_VIEW) { 932 if (container->type == C_VIEW) {
933 view_autoconfigure(container->sway_view); 933 view_init_floating(container->sway_view);
934 } 934 }
935 seat_set_focus(seat, seat_get_focus_inactive(seat, container)); 935 seat_set_focus(seat, seat_get_focus_inactive(seat, container));
936 container_reap_empty_recursive(workspace); 936 container_reap_empty_recursive(workspace);
@@ -943,8 +943,8 @@ void container_set_floating(struct sway_container *container, bool enable) {
943 container->is_sticky = false; 943 container->is_sticky = false;
944 container_reap_empty_recursive(workspace->sway_workspace->floating); 944 container_reap_empty_recursive(workspace->sway_workspace->floating);
945 } 945 }
946 arrange_workspace(workspace); 946
947 container_damage_whole(container); 947 ipc_event_window(container, "floating");
948} 948}
949 949
950void container_set_geometry_from_floating_view(struct sway_container *con) { 950void container_set_geometry_from_floating_view(struct sway_container *con) {
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 6d4cd088..65b61495 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -22,7 +22,7 @@ struct sway_container root_container;
22 22
23static void output_layout_handle_change(struct wl_listener *listener, 23static void output_layout_handle_change(struct wl_listener *listener,
24 void *data) { 24 void *data) {
25 arrange_root(); 25 arrange_and_commit(&root_container);
26} 26}
27 27
28void layout_init(void) { 28void layout_init(void) {
@@ -56,18 +56,17 @@ static int index_child(const struct sway_container *child) {
56 return -1; 56 return -1;
57} 57}
58 58
59static void container_handle_fullscreen_reparent(struct sway_container *viewcon, 59static void container_handle_fullscreen_reparent(struct sway_container *con,
60 struct sway_container *old_parent) { 60 struct sway_container *old_parent) {
61 if (viewcon->type != C_VIEW || !viewcon->sway_view->is_fullscreen) { 61 if (con->type != C_VIEW || !con->sway_view->is_fullscreen) {
62 return; 62 return;
63 } 63 }
64 struct sway_view *view = viewcon->sway_view; 64 struct sway_view *view = con->sway_view;
65 struct sway_container *old_workspace = old_parent; 65 struct sway_container *old_workspace = old_parent;
66 if (old_workspace && old_workspace->type != C_WORKSPACE) { 66 if (old_workspace && old_workspace->type != C_WORKSPACE) {
67 old_workspace = container_parent(old_workspace, C_WORKSPACE); 67 old_workspace = container_parent(old_workspace, C_WORKSPACE);
68 } 68 }
69 struct sway_container *new_workspace = container_parent(view->swayc, 69 struct sway_container *new_workspace = container_parent(con, C_WORKSPACE);
70 C_WORKSPACE);
71 if (old_workspace == new_workspace) { 70 if (old_workspace == new_workspace) {
72 return; 71 return;
73 } 72 }
@@ -78,15 +77,19 @@ static void container_handle_fullscreen_reparent(struct sway_container *viewcon,
78 77
79 // Mark the new workspace as fullscreen 78 // Mark the new workspace as fullscreen
80 if (new_workspace->sway_workspace->fullscreen) { 79 if (new_workspace->sway_workspace->fullscreen) {
81 view_set_fullscreen_raw( 80 view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false);
82 new_workspace->sway_workspace->fullscreen, false);
83 } 81 }
84 new_workspace->sway_workspace->fullscreen = view; 82 new_workspace->sway_workspace->fullscreen = view;
85 // Resize view to new output dimensions 83 // Resize view to new output dimensions
86 struct sway_container *output = new_workspace->parent; 84 struct sway_container *output = new_workspace->parent;
87 view_configure(view, 0, 0, output->width, output->height); 85 view->x = output->x;
88 view->swayc->width = output->width; 86 view->y = output->y;
89 view->swayc->height = output->height; 87 view->width = output->width;
88 view->height = output->height;
89 con->x = output->x;
90 con->y = output->y;
91 con->width = output->width;
92 con->height = output->height;
90} 93}
91 94
92void container_insert_child(struct sway_container *parent, 95void container_insert_child(struct sway_container *parent,
@@ -188,18 +191,7 @@ void container_move_to(struct sway_container *container,
188 } 191 }
189 container_notify_subtree_changed(old_parent); 192 container_notify_subtree_changed(old_parent);
190 container_notify_subtree_changed(new_parent); 193 container_notify_subtree_changed(new_parent);
191 if (old_parent) { 194
192 if (old_parent->type == C_OUTPUT) {
193 arrange_output(old_parent);
194 } else {
195 arrange_children_of(old_parent);
196 }
197 }
198 if (new_parent->type == C_OUTPUT) {
199 arrange_output(new_parent);
200 } else {
201 arrange_children_of(new_parent);
202 }
203 // If view was moved to a fullscreen workspace, refocus the fullscreen view 195 // If view was moved to a fullscreen workspace, refocus the fullscreen view
204 struct sway_container *new_workspace = container; 196 struct sway_container *new_workspace = container;
205 if (new_workspace->type != C_WORKSPACE) { 197 if (new_workspace->type != C_WORKSPACE) {
@@ -214,7 +206,8 @@ void container_move_to(struct sway_container *container,
214 if (focus_ws->type != C_WORKSPACE) { 206 if (focus_ws->type != C_WORKSPACE) {
215 focus_ws = container_parent(focus_ws, C_WORKSPACE); 207 focus_ws = container_parent(focus_ws, C_WORKSPACE);
216 } 208 }
217 seat_set_focus(seat, new_workspace->sway_workspace->fullscreen->swayc); 209 seat_set_focus(seat,
210 new_workspace->sway_workspace->fullscreen->swayc);
218 if (focus_ws != new_workspace) { 211 if (focus_ws != new_workspace) {
219 seat_set_focus(seat, focus); 212 seat_set_focus(seat, focus);
220 } 213 }
@@ -308,7 +301,6 @@ static void workspace_rejigger(struct sway_container *ws,
308 container_reap_empty_recursive(original_parent); 301 container_reap_empty_recursive(original_parent);
309 wl_signal_emit(&child->events.reparent, original_parent); 302 wl_signal_emit(&child->events.reparent, original_parent);
310 container_create_notify(new_parent); 303 container_create_notify(new_parent);
311 arrange_workspace(ws);
312} 304}
313 305
314static void move_out_of_tabs_stacks(struct sway_container *container, 306static void move_out_of_tabs_stacks(struct sway_container *container,
@@ -319,11 +311,6 @@ static void move_out_of_tabs_stacks(struct sway_container *container,
319 wlr_log(L_DEBUG, "Changing layout of %zd", current->parent->id); 311 wlr_log(L_DEBUG, "Changing layout of %zd", current->parent->id);
320 current->parent->layout = move_dir == 312 current->parent->layout = move_dir ==
321 MOVE_LEFT || move_dir == MOVE_RIGHT ? L_HORIZ : L_VERT; 313 MOVE_LEFT || move_dir == MOVE_RIGHT ? L_HORIZ : L_VERT;
322 if (current->parent->type == C_WORKSPACE) {
323 arrange_workspace(current->parent);
324 } else {
325 arrange_children_of(current->parent);
326 }
327 return; 314 return;
328 } 315 }
329 316
@@ -339,11 +326,6 @@ static void move_out_of_tabs_stacks(struct sway_container *container,
339 container_flatten(new_parent->parent); 326 container_flatten(new_parent->parent);
340 } 327 }
341 container_create_notify(new_parent); 328 container_create_notify(new_parent);
342 if (is_workspace) {
343 arrange_workspace(new_parent->parent);
344 } else {
345 arrange_children_of(new_parent);
346 }
347 container_notify_subtree_changed(new_parent); 329 container_notify_subtree_changed(new_parent);
348} 330}
349 331
@@ -367,10 +349,7 @@ void container_move(struct sway_container *container,
367 349
368 struct sway_container *new_parent = container_flatten(parent); 350 struct sway_container *new_parent = container_flatten(parent);
369 if (new_parent != parent) { 351 if (new_parent != parent) {
370 // Special case: we were the last one in this container, so flatten it 352 // Special case: we were the last one in this container, so leave
371 // and leave
372 arrange_children_of(new_parent);
373 update_debug_tree();
374 return; 353 return;
375 } 354 }
376 355
@@ -452,12 +431,9 @@ void container_move(struct sway_container *container,
452 wlr_log(L_DEBUG, "Hit limit, " 431 wlr_log(L_DEBUG, "Hit limit, "
453 "promoting descendant to sibling"); 432 "promoting descendant to sibling");
454 // Special case 433 // Special case
455 struct sway_container *old_parent = container->parent;
456 container_insert_child(current->parent, container, 434 container_insert_child(current->parent, container,
457 index + (offs < 0 ? 0 : 1)); 435 index + (offs < 0 ? 0 : 1));
458 container->width = container->height = 0; 436 container->width = container->height = 0;
459 arrange_children_of(current->parent);
460 arrange_children_of(old_parent);
461 return; 437 return;
462 } 438 }
463 } else { 439 } else {
@@ -491,14 +467,11 @@ void container_move(struct sway_container *container,
491 wlr_log(L_DEBUG, "Swapping siblings"); 467 wlr_log(L_DEBUG, "Swapping siblings");
492 sibling->parent->children->items[index + offs] = container; 468 sibling->parent->children->items[index + offs] = container;
493 sibling->parent->children->items[index] = sibling; 469 sibling->parent->children->items[index] = sibling;
494 arrange_children_of(sibling->parent);
495 } else { 470 } else {
496 wlr_log(L_DEBUG, "Promoting to sibling of cousin"); 471 wlr_log(L_DEBUG, "Promoting to sibling of cousin");
497 container_insert_child(sibling->parent, container, 472 container_insert_child(sibling->parent, container,
498 index_child(sibling) + (offs > 0 ? 0 : 1)); 473 index_child(sibling) + (offs > 0 ? 0 : 1));
499 container->width = container->height = 0; 474 container->width = container->height = 0;
500 arrange_children_of(sibling->parent);
501 arrange_children_of(old_parent);
502 } 475 }
503 sibling = NULL; 476 sibling = NULL;
504 break; 477 break;
@@ -512,8 +485,6 @@ void container_move(struct sway_container *container,
512 "(move dir: %d)", limit, move_dir); 485 "(move dir: %d)", limit, move_dir);
513 container_insert_child(sibling, container, limit); 486 container_insert_child(sibling, container, limit);
514 container->width = container->height = 0; 487 container->width = container->height = 0;
515 arrange_children_of(sibling);
516 arrange_children_of(old_parent);
517 sibling = NULL; 488 sibling = NULL;
518 } else { 489 } else {
519 wlr_log(L_DEBUG, "Reparenting container (perpendicular)"); 490 wlr_log(L_DEBUG, "Reparenting container (perpendicular)");
@@ -537,8 +508,6 @@ void container_move(struct sway_container *container,
537 container_add_child(sibling, container); 508 container_add_child(sibling, container);
538 } 509 }
539 container->width = container->height = 0; 510 container->width = container->height = 0;
540 arrange_children_of(sibling);
541 arrange_children_of(old_parent);
542 sibling = NULL; 511 sibling = NULL;
543 } 512 }
544 break; 513 break;
@@ -863,7 +832,6 @@ struct sway_container *container_split(struct sway_container *child,
863 // Special case: this just behaves like splitt 832 // Special case: this just behaves like splitt
864 child->prev_layout = child->layout; 833 child->prev_layout = child->layout;
865 child->layout = layout; 834 child->layout = layout;
866 arrange_children_of(child);
867 return child; 835 return child;
868 } 836 }
869 837
@@ -1044,9 +1012,6 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
1044 prev_workspace_name = stored_prev_name; 1012 prev_workspace_name = stored_prev_name;
1045 } 1013 }
1046 1014
1047 arrange_children_of(con1->parent);
1048 arrange_children_of(con2->parent);
1049
1050 if (fs1 && con2->type == C_VIEW) { 1015 if (fs1 && con2->type == C_VIEW) {
1051 view_set_fullscreen(con2->sway_view, true); 1016 view_set_fullscreen(con2->sway_view, true);
1052 } 1017 }
diff --git a/sway/tree/view.c b/sway/tree/view.c
index dbf803c6..658a94e8 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -135,22 +135,22 @@ uint32_t view_configure(struct sway_view *view, double lx, double ly, int width,
135 return 0; 135 return 0;
136} 136}
137 137
138static void view_autoconfigure_floating(struct sway_view *view) { 138void view_init_floating(struct sway_view *view) {
139 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); 139 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
140 int max_width = ws->width * 0.6666; 140 int max_width = ws->width * 0.6666;
141 int max_height = ws->height * 0.6666; 141 int max_height = ws->height * 0.6666;
142 int width = 142 view->width =
143 view->natural_width > max_width ? max_width : view->natural_width; 143 view->natural_width > max_width ? max_width : view->natural_width;
144 int height = 144 view->height =
145 view->natural_height > max_height ? max_height : view->natural_height; 145 view->natural_height > max_height ? max_height : view->natural_height;
146 int lx = ws->x + (ws->width - width) / 2; 146 view->x = ws->x + (ws->width - view->width) / 2;
147 int ly = ws->y + (ws->height - height) / 2; 147 view->y = ws->y + (ws->height - view->height) / 2;
148 148
149 // If the view's border is B_NONE then these properties are ignored. 149 // If the view's border is B_NONE then these properties are ignored.
150 view->border_top = view->border_bottom = true; 150 view->border_top = view->border_bottom = true;
151 view->border_left = view->border_right = true; 151 view->border_left = view->border_right = true;
152 152
153 view_configure(view, lx, ly, width, height); 153 container_set_geometry_from_floating_view(view->swayc);
154} 154}
155 155
156void view_autoconfigure(struct sway_view *view) { 156void view_autoconfigure(struct sway_view *view) {
@@ -162,12 +162,14 @@ void view_autoconfigure(struct sway_view *view) {
162 struct sway_container *output = container_parent(view->swayc, C_OUTPUT); 162 struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
163 163
164 if (view->is_fullscreen) { 164 if (view->is_fullscreen) {
165 view_configure(view, output->x, output->y, output->width, output->height); 165 view->x = output->x;
166 view->y = output->y;
167 view->width = output->width;
168 view->height = output->height;
166 return; 169 return;
167 } 170 }
168 171
169 if (container_is_floating(view->swayc)) { 172 if (container_is_floating(view->swayc)) {
170 view_autoconfigure_floating(view);
171 return; 173 return;
172 } 174 }
173 175
@@ -268,8 +270,7 @@ void view_set_activated(struct sway_view *view, bool activated) {
268 } 270 }
269} 271}
270 272
271// Set fullscreen, but without IPC events or arranging windows. 273void view_set_fullscreen(struct sway_view *view, bool fullscreen) {
272void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen) {
273 if (view->is_fullscreen == fullscreen) { 274 if (view->is_fullscreen == fullscreen) {
274 return; 275 return;
275 } 276 }
@@ -315,26 +316,17 @@ void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen) {
315 } else { 316 } else {
316 workspace->sway_workspace->fullscreen = NULL; 317 workspace->sway_workspace->fullscreen = NULL;
317 if (container_is_floating(view->swayc)) { 318 if (container_is_floating(view->swayc)) {
318 view_configure(view, view->saved_x, view->saved_y, 319 view->x = view->saved_x;
319 view->saved_width, view->saved_height); 320 view->y = view->saved_y;
321 view->width = view->saved_width;
322 view->height = view->saved_height;
323 container_set_geometry_from_floating_view(view->swayc);
320 } else { 324 } else {
321 view->swayc->width = view->swayc->saved_width; 325 view->swayc->width = view->swayc->saved_width;
322 view->swayc->height = view->swayc->saved_height; 326 view->swayc->height = view->swayc->saved_height;
323 } 327 }
324 } 328 }
325}
326
327void view_set_fullscreen(struct sway_view *view, bool fullscreen) {
328 if (view->is_fullscreen == fullscreen) {
329 return;
330 }
331 329
332 view_set_fullscreen_raw(view, fullscreen);
333
334 struct sway_container *workspace =
335 container_parent(view->swayc, C_WORKSPACE);
336 arrange_workspace(workspace);
337 output_damage_whole(workspace->parent->sway_output);
338 ipc_event_window(view->swayc, "fullscreen_mode"); 330 ipc_event_window(view->swayc, "fullscreen_mode");
339} 331}
340 332
@@ -517,8 +509,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
517 509
518 if (view->impl->wants_floating && view->impl->wants_floating(view)) { 510 if (view->impl->wants_floating && view->impl->wants_floating(view)) {
519 container_set_floating(view->swayc, true); 511 container_set_floating(view->swayc, true);
520 } else {
521 arrange_children_of(cont->parent);
522 } 512 }
523 513
524 input_manager_set_focus(input_manager, cont); 514 input_manager_set_focus(input_manager, cont);
@@ -530,7 +520,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
530 container_notify_subtree_changed(view->swayc->parent); 520 container_notify_subtree_changed(view->swayc->parent);
531 view_execute_criteria(view); 521 view_execute_criteria(view);
532 522
533 container_damage_whole(cont);
534 view_handle_container_reparent(&view->container_reparent, NULL); 523 view_handle_container_reparent(&view->container_reparent, NULL);
535} 524}
536 525
@@ -561,11 +550,7 @@ void view_unmap(struct sway_view *view) {
561 view->title_format = NULL; 550 view->title_format = NULL;
562 } 551 }
563 552
564 if (parent->type == C_OUTPUT) { 553 arrange_and_commit(parent);
565 arrange_output(parent);
566 } else {
567 arrange_children_of(parent);
568 }
569} 554}
570 555
571void view_update_position(struct sway_view *view, double lx, double ly) { 556void view_update_position(struct sway_view *view, double lx, double ly) {
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 9ba210fd..ead752ad 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -425,7 +425,7 @@ bool workspace_switch(struct sway_container *workspace) {
425 } 425 }
426 seat_set_focus(seat, next); 426 seat_set_focus(seat, next);
427 struct sway_container *output = container_parent(workspace, C_OUTPUT); 427 struct sway_container *output = container_parent(workspace, C_OUTPUT);
428 arrange_output(output); 428 arrange_and_commit(output);
429 return true; 429 return true;
430} 430}
431 431