aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/container.h8
-rw-r--r--include/sway/tree/layout.h3
-rw-r--r--sway/input/seat.c4
-rw-r--r--sway/tree/container.c55
-rw-r--r--sway/tree/layout.c37
5 files changed, 104 insertions, 3 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 3bb497db..24e8468e 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -99,8 +99,13 @@ struct sway_container *container_view_create(
99 99
100struct sway_container *container_output_destroy(struct sway_container *output); 100struct sway_container *container_output_destroy(struct sway_container *output);
101 101
102struct sway_container *container_workspace_destroy(
103 struct sway_container *workspace);
104
102struct sway_container *container_view_destroy(struct sway_container *view); 105struct sway_container *container_view_destroy(struct sway_container *view);
103 106
107void container_destroy(struct sway_container *cont);
108
104struct sway_container *container_set_layout(struct sway_container *container, 109struct sway_container *container_set_layout(struct sway_container *container,
105 enum sway_container_layout layout); 110 enum sway_container_layout layout);
106 111
@@ -140,4 +145,7 @@ void container_for_each_descendant_bfs(struct sway_container *container,
140void container_for_each_descendant_dfs(struct sway_container *container, 145void container_for_each_descendant_dfs(struct sway_container *container,
141 void (*f)(struct sway_container *container, void *data), void *data); 146 void (*f)(struct sway_container *container, void *data), void *data);
142 147
148bool container_has_anscestor(struct sway_container *descendant,
149 struct sway_container *anscestor);
150
143#endif 151#endif
diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h
index ad52bdb0..8239366b 100644
--- a/include/sway/tree/layout.h
+++ b/include/sway/tree/layout.h
@@ -39,6 +39,9 @@ struct sway_container *container_add_sibling(struct sway_container *parent,
39 39
40struct sway_container *container_remove_child(struct sway_container *child); 40struct sway_container *container_remove_child(struct sway_container *child);
41 41
42void container_move_to(struct sway_container* container,
43 struct sway_container* destination);
44
42enum sway_container_layout container_get_default_layout(struct sway_container *output); 45enum sway_container_layout container_get_default_layout(struct sway_container *output);
43 46
44void container_sort_workspaces(struct sway_container *output); 47void container_sort_workspaces(struct sway_container *output);
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