aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/container.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 11:58:17 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-30 13:49:34 -0400
commit49379dd0fc0758f89d7f4fa4fb5b08c7f4c26ae6 (patch)
treeb67a66382125811fde75e5c3dff37d7081860c78 /sway/tree/container.c
parentMerge pull request #1664 from swaywm/xwayland-add-to-focused (diff)
downloadsway-49379dd0fc0758f89d7f4fa4fb5b08c7f4c26ae6.tar.gz
sway-49379dd0fc0758f89d7f4fa4fb5b08c7f4c26ae6.tar.zst
sway-49379dd0fc0758f89d7f4fa4fb5b08c7f4c26ae6.zip
Fix workspace deletion edge cases
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c101
1 files changed, 7 insertions, 94 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index ed39a154..778108b4 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -10,12 +10,12 @@
10#include "sway/tree/container.h" 10#include "sway/tree/container.h"
11#include "sway/input/input-manager.h" 11#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 12#include "sway/input/seat.h"
13#include "sway/tree/layout.h" 13#include "sway/ipc-server.h"
14#include "sway/output.h" 14#include "sway/output.h"
15#include "sway/server.h" 15#include "sway/server.h"
16#include "sway/tree/layout.h"
16#include "sway/tree/view.h" 17#include "sway/tree/view.h"
17#include "sway/tree/workspace.h" 18#include "sway/tree/workspace.h"
18#include "sway/ipc-server.h"
19#include "log.h" 19#include "log.h"
20 20
21static list_t *bfs_queue; 21static list_t *bfs_queue;
@@ -58,13 +58,14 @@ static struct sway_container *container_create(enum sway_container_type type) {
58 return c; 58 return c;
59} 59}
60 60
61void container_destroy(struct sway_container *cont) { 61struct sway_container *container_destroy(struct sway_container *cont) {
62 if (cont == NULL) { 62 if (cont == NULL) {
63 return; 63 return NULL;
64 } 64 }
65 65
66 wl_signal_emit(&cont->events.destroy, cont); 66 wl_signal_emit(&cont->events.destroy, cont);
67 67
68 struct sway_container *parent = cont->parent;
68 if (cont->children) { 69 if (cont->children) {
69 // remove children until there are no more, container_destroy calls 70 // remove children until there are no more, container_destroy calls
70 // container_remove_child, which removes child from this container 71 // container_remove_child, which removes child from this container
@@ -77,13 +78,14 @@ void container_destroy(struct sway_container *cont) {
77 list_foreach(cont->marks, free); 78 list_foreach(cont->marks, free);
78 list_free(cont->marks); 79 list_free(cont->marks);
79 } 80 }
80 if (cont->parent) { 81 if (parent) {
81 container_remove_child(cont); 82 container_remove_child(cont);
82 } 83 }
83 if (cont->name) { 84 if (cont->name) {
84 free(cont->name); 85 free(cont->name);
85 } 86 }
86 free(cont); 87 free(cont);
88 return parent;
87} 89}
88 90
89struct sway_container *container_output_create( 91struct sway_container *container_output_create(
@@ -202,95 +204,6 @@ struct sway_container *container_view_create(struct sway_container *sibling,
202 return swayc; 204 return swayc;
203} 205}
204 206
205struct sway_container *container_output_destroy(struct sway_container *output) {
206 if (!sway_assert(output, "cannot destroy null output")) {
207 return NULL;
208 }
209
210 if (output->children->length > 0) {
211 // TODO save workspaces when there are no outputs.
212 // TODO also check if there will ever be no outputs except for exiting
213 // program
214 if (root_container.children->length > 1) {
215 int p = root_container.children->items[0] == output;
216 // Move workspace from this output to another output
217 while (output->children->length) {
218 struct sway_container *child = output->children->items[0];
219 container_remove_child(child);
220 container_add_child(root_container.children->items[p], child);
221 }
222 container_sort_workspaces(root_container.children->items[p]);
223 arrange_windows(root_container.children->items[p],
224 -1, -1);
225 }
226 }
227
228 wl_list_remove(&output->sway_output->frame.link);
229 wl_list_remove(&output->sway_output->destroy.link);
230 wl_list_remove(&output->sway_output->mode.link);
231
232 wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name);
233 container_destroy(output);
234
235 return &root_container;
236}
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
277struct sway_container *container_view_destroy(struct sway_container *view) {
278 if (!view) {
279 return NULL;
280 }
281 wlr_log(L_DEBUG, "Destroying view '%s'", view->name);
282 struct sway_container *parent = view->parent;
283 container_destroy(view);
284
285 // TODO WLR: Destroy empty containers
286 /*
287 if (parent && parent->type == C_CONTAINER) {
288 return destroy_container(parent);
289 }
290 */
291 return parent;
292}
293
294struct sway_container *container_set_layout(struct sway_container *container, 207struct sway_container *container_set_layout(struct sway_container *container,
295 enum sway_container_layout layout) { 208 enum sway_container_layout layout) {
296 if (container->type == C_WORKSPACE) { 209 if (container->type == C_WORKSPACE) {