aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 10:31:21 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 10:47:19 -0400
commit01af34391267e91461a4ab7a1234dd58f45d2c93 (patch)
treeae5197dabda270035b383d45b5c113afab2ebfbd /sway
parentFix crash when override redirect views close (diff)
downloadsway-01af34391267e91461a4ab7a1234dd58f45d2c93.tar.gz
sway-01af34391267e91461a4ab7a1234dd58f45d2c93.tar.zst
sway-01af34391267e91461a4ab7a1234dd58f45d2c93.zip
Destroy empty workspaces when moving away
Diffstat (limited to 'sway')
-rw-r--r--sway/input/seat.c4
-rw-r--r--sway/tree/container.c55
-rw-r--r--sway/tree/layout.c37
3 files changed, 93 insertions, 3 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 7cf0dd08..ae536264 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -8,6 +8,7 @@
8#include "sway/input/keyboard.h" 8#include "sway/input/keyboard.h"
9#include "sway/ipc-server.h" 9#include "sway/ipc-server.h"
10#include "sway/output.h" 10#include "sway/output.h"
11#include "sway/tree/container.h"
11#include "sway/tree/view.h" 12#include "sway/tree/view.h"
12#include "log.h" 13#include "log.h"
13 14
@@ -331,6 +332,9 @@ void sway_seat_set_focus(struct sway_seat *seat, struct sway_container *containe
331 if (last_ws) { 332 if (last_ws) {
332 wlr_log(L_DEBUG, "sending workspace event"); 333 wlr_log(L_DEBUG, "sending workspace event");
333 ipc_event_workspace(last_ws, container, "focus"); 334 ipc_event_workspace(last_ws, container, "focus");
335 if (last_ws->children->length == 0) {
336 container_workspace_destroy(last_ws);
337 }
334 } 338 }
335 } 339 }
336 340
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 2eac812e..ed39a154 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -58,7 +58,7 @@ static struct sway_container *container_create(enum sway_container_type type) {
58 return c; 58 return c;
59} 59}
60 60
61static void container_destroy(struct sway_container *cont) { 61void container_destroy(struct sway_container *cont) {
62 if (cont == NULL) { 62 if (cont == NULL) {
63 return; 63 return;
64 } 64 }
@@ -203,8 +203,7 @@ struct sway_container *container_view_create(struct sway_container *sibling,
203} 203}
204 204
205struct sway_container *container_output_destroy(struct sway_container *output) { 205struct sway_container *container_output_destroy(struct sway_container *output) {
206 if (!sway_assert(output, 206 if (!sway_assert(output, "cannot destroy null output")) {
207 "null output passed to container_output_destroy")) {
208 return NULL; 207 return NULL;
209 } 208 }
210 209
@@ -236,6 +235,45 @@ struct sway_container *container_output_destroy(struct sway_container *output) {
236 return &root_container; 235 return &root_container;
237} 236}
238 237
238struct sway_container *container_workspace_destroy(
239 struct sway_container *workspace) {
240 if (!sway_assert(workspace, "cannot destroy null workspace")) {
241 return NULL;
242 }
243
244 // Do not destroy this if it's the last workspace on this output
245 struct sway_container *output = container_parent(workspace, C_OUTPUT);
246 if (output && output->children->length == 1) {
247 return NULL;
248 }
249
250 struct sway_container *parent = workspace->parent;
251 if (workspace->children->length == 0) {
252 // destroy the WS if there are no children (TODO check for floating)
253 wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
254 ipc_event_workspace(workspace, NULL, "empty");
255 } else {
256 // Move children to a different workspace on this output
257 struct sway_container *new_workspace = NULL;
258 // TODO move floating
259 for (int i = 0; i < output->children->length; i++) {
260 if (output->children->items[i] != workspace) {
261 new_workspace = output->children->items[i];
262 break;
263 }
264 }
265
266 wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'",
267 workspace->name, new_workspace->name);
268 for (int i = 0; i < workspace->children->length; i++) {
269 container_move_to(workspace->children->items[i], new_workspace);
270 }
271 }
272
273 container_destroy(workspace);
274 return parent;
275}
276
239struct sway_container *container_view_destroy(struct sway_container *view) { 277struct sway_container *container_view_destroy(struct sway_container *view) {
240 if (!view) { 278 if (!view) {
241 return NULL; 279 return NULL;
@@ -438,3 +476,14 @@ void container_for_each_descendant_bfs(struct sway_container *con,
438 list_cat(queue, current->children); 476 list_cat(queue, current->children);
439 } 477 }
440} 478}
479
480bool container_has_anscestor(struct sway_container *descendant,
481 struct sway_container *anscestor) {
482 while (descendant->type != C_ROOT) {
483 descendant = descendant->parent;
484 if (descendant == anscestor) {
485 return true;
486 }
487 }
488 return false;
489}
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index dc0ee5b4..97007888 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -11,6 +11,7 @@
11#include "sway/output.h" 11#include "sway/output.h"
12#include "sway/tree/view.h" 12#include "sway/tree/view.h"
13#include "sway/input/seat.h" 13#include "sway/input/seat.h"
14#include "sway/ipc-server.h"
14#include "list.h" 15#include "list.h"
15#include "log.h" 16#include "log.h"
16 17
@@ -121,6 +122,42 @@ struct sway_container *container_remove_child(struct sway_container *child) {
121 return parent; 122 return parent;
122} 123}
123 124
125struct sway_container *container_reap_empty(struct sway_container *container) {
126 if (!sway_assert(container, "reaping null container")) {
127 return NULL;
128 }
129 while (container->children->length == 0 && container->type == C_CONTAINER) {
130 wlr_log(L_DEBUG, "Container: Destroying container '%p'", container);
131 struct sway_container *parent = container->parent;
132 container_destroy(container);
133 container = parent;
134 }
135 return container;
136}
137
138void container_move_to(struct sway_container* container,
139 struct sway_container* destination) {
140 if (container == destination
141 || container_has_anscestor(container, destination)) {
142 return;
143 }
144 struct sway_container *old_parent = container_remove_child(container);
145 container->width = container->height = 0;
146 struct sway_container *new_parent =
147 container_add_sibling(destination, container);
148 if (destination->type == C_WORKSPACE) {
149 // If the workspace only has one child after adding one, it
150 // means that the workspace was just initialized.
151 // TODO: Consider floating views in this test
152 if (destination->children->length == 1) {
153 ipc_event_workspace(NULL, destination, "init");
154 }
155 }
156 old_parent = container_reap_empty(old_parent);
157 arrange_windows(old_parent, -1, -1);
158 arrange_windows(new_parent, -1, -1);
159}
160
124enum sway_container_layout container_get_default_layout( 161enum sway_container_layout container_get_default_layout(
125 struct sway_container *output) { 162 struct sway_container *output) {
126 /* TODO WLR 163 /* TODO WLR