diff options
-rw-r--r-- | include/sway/tree/container.h | 7 | ||||
-rw-r--r-- | sway/input/seat.c | 3 | ||||
-rw-r--r-- | sway/tree/container.c | 83 | ||||
-rw-r--r-- | sway/tree/view.c | 13 | ||||
-rw-r--r-- | sway/tree/workspace.c | 39 |
5 files changed, 83 insertions, 62 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 1286316a..278505ce 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -128,11 +128,12 @@ struct sway_container *container_view_create( | |||
128 | struct sway_container *sibling, struct sway_view *sway_view); | 128 | struct sway_container *sibling, struct sway_view *sway_view); |
129 | 129 | ||
130 | // TODO don't return the parent on destroy | 130 | // TODO don't return the parent on destroy |
131 | void container_destroy(struct sway_container *container); | 131 | struct sway_container *container_destroy(struct sway_container *container); |
132 | |||
133 | // TODO make me private | ||
134 | struct sway_container *container_finish(struct sway_container *cont); | ||
132 | 135 | ||
133 | struct sway_container *container_workspace_destroy(struct sway_container *container); | ||
134 | struct sway_container *container_output_destroy(struct sway_container *container); | 136 | struct sway_container *container_output_destroy(struct sway_container *container); |
135 | void container_view_destroy(struct sway_container *container); | ||
136 | 137 | ||
137 | struct sway_container *container_close(struct sway_container *container); | 138 | struct sway_container *container_close(struct sway_container *container); |
138 | 139 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index c41f7b2e..d752acb8 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -381,7 +381,8 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
381 | if (last_ws) { | 381 | if (last_ws) { |
382 | ipc_event_workspace(last_ws, container, "focus"); | 382 | ipc_event_workspace(last_ws, container, "focus"); |
383 | if (last_ws->children->length == 0) { | 383 | if (last_ws->children->length == 0) { |
384 | container_workspace_destroy(last_ws); | 384 | output_damage_whole(last_ws->parent->sway_output); |
385 | container_destroy(last_ws); | ||
385 | } | 386 | } |
386 | } | 387 | } |
387 | struct sway_container *last_output = last_focus; | 388 | struct sway_container *last_output = last_focus; |
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) { |
diff --git a/sway/tree/view.c b/sway/tree/view.c index eeadc5d8..c06924f5 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -27,8 +27,7 @@ void view_destroy(struct sway_view *view) { | |||
27 | view_unmap(view); | 27 | view_unmap(view); |
28 | } | 28 | } |
29 | 29 | ||
30 | container_view_destroy(view->swayc); | 30 | container_destroy(view->swayc); |
31 | free(view); | ||
32 | } | 31 | } |
33 | 32 | ||
34 | const char *view_get_title(struct sway_view *view) { | 33 | const char *view_get_title(struct sway_view *view) { |
@@ -78,14 +77,6 @@ void view_close(struct sway_view *view) { | |||
78 | } | 77 | } |
79 | } | 78 | } |
80 | 79 | ||
81 | void container_view_destroy(struct sway_container *view) { | ||
82 | if (!view) { | ||
83 | return; | ||
84 | } | ||
85 | wlr_log(L_DEBUG, "Destroying view '%s'", view->name); | ||
86 | container_destroy(view); | ||
87 | } | ||
88 | |||
89 | void view_damage_whole(struct sway_view *view) { | 80 | void view_damage_whole(struct sway_view *view) { |
90 | for (int i = 0; i < root_container.children->length; ++i) { | 81 | for (int i = 0; i < root_container.children->length; ++i) { |
91 | struct sway_container *cont = root_container.children->items[i]; | 82 | struct sway_container *cont = root_container.children->items[i]; |
@@ -158,7 +149,7 @@ void view_unmap(struct sway_view *view) { | |||
158 | 149 | ||
159 | view_damage_whole(view); | 150 | view_damage_whole(view); |
160 | 151 | ||
161 | container_view_destroy(view->swayc); | 152 | container_destroy(view->swayc); |
162 | 153 | ||
163 | view->swayc = NULL; | 154 | view->swayc = NULL; |
164 | view->surface = NULL; | 155 | view->surface = NULL; |
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 74330884..7d180009 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -208,45 +208,6 @@ struct sway_container *workspace_create(const char *name) { | |||
208 | return new_ws; | 208 | return new_ws; |
209 | } | 209 | } |
210 | 210 | ||
211 | struct sway_container *container_workspace_destroy( | ||
212 | struct sway_container *workspace) { | ||
213 | if (!sway_assert(workspace, "cannot destroy null workspace")) { | ||
214 | return NULL; | ||
215 | } | ||
216 | |||
217 | // Do not destroy this if it's the last workspace on this output | ||
218 | struct sway_container *output = container_parent(workspace, C_OUTPUT); | ||
219 | if (output && output->children->length == 1) { | ||
220 | return NULL; | ||
221 | } | ||
222 | |||
223 | struct sway_container *parent = workspace->parent; | ||
224 | if (workspace->children->length == 0) { | ||
225 | // destroy the WS if there are no children (TODO check for floating) | ||
226 | wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); | ||
227 | ipc_event_workspace(workspace, NULL, "empty"); | ||
228 | } else { | ||
229 | // Move children to a different workspace on this output | ||
230 | struct sway_container *new_workspace = NULL; | ||
231 | // TODO move floating | ||
232 | for (int i = 0; i < output->children->length; i++) { | ||
233 | if (output->children->items[i] != workspace) { | ||
234 | new_workspace = output->children->items[i]; | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", | ||
240 | workspace->name, new_workspace->name); | ||
241 | for (int i = 0; i < workspace->children->length; i++) { | ||
242 | container_move_to(workspace->children->items[i], new_workspace); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | container_destroy(workspace); | ||
247 | return parent; | ||
248 | } | ||
249 | |||
250 | /** | 211 | /** |
251 | * Get the previous or next workspace on the specified output. Wraps around at | 212 | * Get the previous or next workspace on the specified output. Wraps around at |
252 | * the end and beginning. If next is false, the previous workspace is returned, | 213 | * the end and beginning. If next is false, the previous workspace is returned, |