diff options
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r-- | sway/tree/container.c | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index d9fc61e7..c1ebf4f1 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -77,7 +77,7 @@ struct sway_container *container_create(enum sway_container_type type) { | |||
77 | return c; | 77 | return c; |
78 | } | 78 | } |
79 | 79 | ||
80 | static struct sway_container *container_finish(struct sway_container *cont) { | 80 | struct sway_container *container_finish(struct sway_container *cont) { |
81 | if (cont == NULL) { | 81 | if (cont == NULL) { |
82 | return NULL; | 82 | return NULL; |
83 | } | 83 | } |
@@ -91,7 +91,7 @@ static struct sway_container *container_finish(struct sway_container *cont) { | |||
91 | while (cont->children != NULL && cont->children->length != 0) { | 91 | while (cont->children != NULL && cont->children->length != 0) { |
92 | struct sway_container *child = cont->children->items[0]; | 92 | struct sway_container *child = cont->children->items[0]; |
93 | container_remove_child(child); | 93 | container_remove_child(child); |
94 | container_destroy(child); | 94 | container_finish(child); |
95 | } | 95 | } |
96 | } | 96 | } |
97 | if (cont->marks) { | 97 | if (cont->marks) { |
@@ -109,6 +109,45 @@ static struct sway_container *container_finish(struct sway_container *cont) { | |||
109 | free(cont); | 109 | free(cont); |
110 | return parent; | 110 | return parent; |
111 | } | 111 | } |
112 | static struct sway_container *container_workspace_destroy( | ||
113 | struct sway_container *workspace) { | ||
114 | if (!sway_assert(workspace, "cannot destroy null workspace")) { | ||
115 | return NULL; | ||
116 | } | ||
117 | |||
118 | // Do not destroy this if it's the last workspace on this output | ||
119 | struct sway_container *output = container_parent(workspace, C_OUTPUT); | ||
120 | if (output && output->children->length == 1) { | ||
121 | return NULL; | ||
122 | } | ||
123 | |||
124 | struct sway_container *parent = workspace->parent; | ||
125 | if (workspace->children->length == 0) { | ||
126 | // destroy the WS if there are no children (TODO check for floating) | ||
127 | wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); | ||
128 | ipc_event_workspace(workspace, NULL, "empty"); | ||
129 | } else { | ||
130 | // Move children to a different workspace on this output | ||
131 | struct sway_container *new_workspace = NULL; | ||
132 | // TODO move floating | ||
133 | for (int i = 0; i < output->children->length; i++) { | ||
134 | if (output->children->items[i] != workspace) { | ||
135 | new_workspace = output->children->items[i]; | ||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", | ||
141 | workspace->name, new_workspace->name); | ||
142 | for (int i = 0; i < workspace->children->length; i++) { | ||
143 | container_move_to(workspace->children->items[i], new_workspace); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | container_finish(workspace); | ||
148 | return parent; | ||
149 | } | ||
150 | |||
112 | 151 | ||
113 | static void reap_empty_func(struct sway_container *con, void *data) { | 152 | static void reap_empty_func(struct sway_container *con, void *data) { |
114 | switch (con->type) { | 153 | switch (con->type) { |
@@ -146,18 +185,46 @@ struct sway_container *container_reap_empty(struct sway_container *container) { | |||
146 | return parent; | 185 | return parent; |
147 | } | 186 | } |
148 | 187 | ||
188 | static void container_root_finish(struct sway_container *con) { | ||
189 | wlr_log(L_ERROR, "TODO: destroy the root container"); | ||
190 | } | ||
149 | 191 | ||
150 | void container_destroy(struct sway_container *cont) { | 192 | struct sway_container *container_destroy(struct sway_container *con) { |
151 | if (cont == NULL) { | 193 | if (con == NULL) { |
152 | return; | 194 | return NULL; |
153 | } | 195 | } |
154 | 196 | ||
155 | if (cont->children != NULL && cont->children->length) { | 197 | struct sway_container *anscestor = NULL; |
156 | assert(false && "dont destroy containers with children"); | 198 | |
199 | switch (con->type) { | ||
200 | case C_ROOT: | ||
201 | container_root_finish(con); | ||
202 | break; | ||
203 | case C_OUTPUT: | ||
204 | anscestor = container_output_destroy(con); | ||
205 | break; | ||
206 | case C_WORKSPACE: | ||
207 | anscestor = container_workspace_destroy(con); | ||
208 | break; | ||
209 | case C_CONTAINER: | ||
210 | if (con->children != NULL && con->children->length) { | ||
211 | assert(false && "dont destroy container containers with children"); | ||
212 | } | ||
213 | container_finish(con); | ||
214 | // TODO return parent to arrange maybe? | ||
215 | break; | ||
216 | case C_VIEW: | ||
217 | container_finish(con); | ||
218 | // TODO return parent to arrange maybe? | ||
219 | break; | ||
220 | case C_TYPES: | ||
221 | wlr_log(L_ERROR, "tried to destroy an invalid container"); | ||
222 | break; | ||
157 | } | 223 | } |
158 | 224 | ||
159 | container_finish(cont); | ||
160 | container_reap_empty(&root_container); | 225 | container_reap_empty(&root_container); |
226 | |||
227 | return anscestor; | ||
161 | } | 228 | } |
162 | 229 | ||
163 | static void container_close_func(struct sway_container *container, void *data) { | 230 | static void container_close_func(struct sway_container *container, void *data) { |