diff options
author | 2018-03-30 00:00:23 -0400 | |
---|---|---|
committer | 2018-03-30 00:00:23 -0400 | |
commit | 7162b9bea4d66d61376ad3605e23e2d83bb95201 (patch) | |
tree | 6f7a3121f15503a923c1ce53bf2bee368c6149a6 /sway/tree/container.c | |
parent | Merge pull request #1653 from swaywm/revert-1647-refactor-tree (diff) | |
parent | Fix oversights from previous pull request (diff) | |
download | sway-7162b9bea4d66d61376ad3605e23e2d83bb95201.tar.gz sway-7162b9bea4d66d61376ad3605e23e2d83bb95201.tar.zst sway-7162b9bea4d66d61376ad3605e23e2d83bb95201.zip |
Merge pull request #1654 from acrisci/refactor-2-electric-boogaloo
Revert "Merge pull request #1653 from swaywm/revert-1647-refactor-tree"
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r-- | sway/tree/container.c | 220 |
1 files changed, 111 insertions, 109 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index bbafe9ec..6a6861f3 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -7,14 +7,14 @@ | |||
7 | #include <wlr/types/wlr_output_layout.h> | 7 | #include <wlr/types/wlr_output_layout.h> |
8 | #include <wlr/types/wlr_wl_shell.h> | 8 | #include <wlr/types/wlr_wl_shell.h> |
9 | #include "sway/config.h" | 9 | #include "sway/config.h" |
10 | #include "sway/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/layout.h" | 13 | #include "sway/tree/layout.h" |
14 | #include "sway/output.h" | 14 | #include "sway/output.h" |
15 | #include "sway/server.h" | 15 | #include "sway/server.h" |
16 | #include "sway/view.h" | 16 | #include "sway/tree/view.h" |
17 | #include "sway/workspace.h" | 17 | #include "sway/tree/workspace.h" |
18 | #include "sway/ipc-server.h" | 18 | #include "sway/ipc-server.h" |
19 | #include "log.h" | 19 | #include "log.h" |
20 | 20 | ||
@@ -33,48 +33,15 @@ static list_t *get_bfs_queue() { | |||
33 | return bfs_queue; | 33 | return bfs_queue; |
34 | } | 34 | } |
35 | 35 | ||
36 | static void notify_new_container(swayc_t *container) { | 36 | static void notify_new_container(struct sway_container *container) { |
37 | wl_signal_emit(&root_container.sway_root->events.new_container, container); | 37 | wl_signal_emit(&root_container.sway_root->events.new_container, container); |
38 | ipc_event_window(container, "new"); | 38 | ipc_event_window(container, "new"); |
39 | } | 39 | } |
40 | 40 | ||
41 | swayc_t *swayc_by_test(swayc_t *container, | 41 | static struct sway_container *container_create(enum sway_container_type type) { |
42 | bool (*test)(swayc_t *view, void *data), void *data) { | ||
43 | if (!container->children) { | ||
44 | return NULL; | ||
45 | } | ||
46 | // TODO: floating windows | ||
47 | for (int i = 0; i < container->children->length; ++i) { | ||
48 | swayc_t *child = container->children->items[i]; | ||
49 | if (test(child, data)) { | ||
50 | return child; | ||
51 | } else { | ||
52 | swayc_t *res = swayc_by_test(child, test, data); | ||
53 | if (res) { | ||
54 | return res; | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | return NULL; | ||
59 | } | ||
60 | |||
61 | void swayc_descendants_of_type(swayc_t *root, enum swayc_types type, | ||
62 | void (*func)(swayc_t *item, void *data), void *data) { | ||
63 | for (int i = 0; i < root->children->length; ++i) { | ||
64 | swayc_t *item = root->children->items[i]; | ||
65 | if (item->type == type) { | ||
66 | func(item, data); | ||
67 | } | ||
68 | if (item->children && item->children->length) { | ||
69 | swayc_descendants_of_type(item, type, func, data); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static swayc_t *new_swayc(enum swayc_types type) { | ||
75 | // next id starts at 1 because 0 is assigned to root_container in layout.c | 42 | // next id starts at 1 because 0 is assigned to root_container in layout.c |
76 | static size_t next_id = 1; | 43 | static size_t next_id = 1; |
77 | swayc_t *c = calloc(1, sizeof(swayc_t)); | 44 | struct sway_container *c = calloc(1, sizeof(struct sway_container)); |
78 | if (!c) { | 45 | if (!c) { |
79 | return NULL; | 46 | return NULL; |
80 | } | 47 | } |
@@ -82,8 +49,6 @@ static swayc_t *new_swayc(enum swayc_types type) { | |||
82 | c->layout = L_NONE; | 49 | c->layout = L_NONE; |
83 | c->workspace_layout = L_NONE; | 50 | c->workspace_layout = L_NONE; |
84 | c->type = type; | 51 | c->type = type; |
85 | c->nb_master = 1; | ||
86 | c->nb_slave_groups = 1; | ||
87 | if (type != C_VIEW) { | 52 | if (type != C_VIEW) { |
88 | c->children = create_list(); | 53 | c->children = create_list(); |
89 | } | 54 | } |
@@ -93,18 +58,18 @@ static swayc_t *new_swayc(enum swayc_types type) { | |||
93 | return c; | 58 | return c; |
94 | } | 59 | } |
95 | 60 | ||
96 | static void free_swayc(swayc_t *cont) { | 61 | static void container_destroy(struct sway_container *cont) { |
97 | if (!sway_assert(cont, "free_swayc passed NULL")) { | 62 | if (cont == NULL) { |
98 | return; | 63 | return; |
99 | } | 64 | } |
100 | 65 | ||
101 | wl_signal_emit(&cont->events.destroy, cont); | 66 | wl_signal_emit(&cont->events.destroy, cont); |
102 | 67 | ||
103 | if (cont->children) { | 68 | if (cont->children) { |
104 | // remove children until there are no more, free_swayc calls | 69 | // remove children until there are no more, container_destroy calls |
105 | // remove_child, which removes child from this container | 70 | // container_remove_child, which removes child from this container |
106 | while (cont->children->length) { | 71 | while (cont->children->length) { |
107 | free_swayc(cont->children->items[0]); | 72 | container_destroy(cont->children->items[0]); |
108 | } | 73 | } |
109 | list_free(cont->children); | 74 | list_free(cont->children); |
110 | } | 75 | } |
@@ -113,7 +78,7 @@ static void free_swayc(swayc_t *cont) { | |||
113 | list_free(cont->marks); | 78 | list_free(cont->marks); |
114 | } | 79 | } |
115 | if (cont->parent) { | 80 | if (cont->parent) { |
116 | remove_child(cont); | 81 | container_remove_child(cont); |
117 | } | 82 | } |
118 | if (cont->name) { | 83 | if (cont->name) { |
119 | free(cont->name); | 84 | free(cont->name); |
@@ -121,7 +86,8 @@ static void free_swayc(swayc_t *cont) { | |||
121 | free(cont); | 86 | free(cont); |
122 | } | 87 | } |
123 | 88 | ||
124 | swayc_t *new_output(struct sway_output *sway_output) { | 89 | struct sway_container *container_output_create( |
90 | struct sway_output *sway_output) { | ||
125 | struct wlr_box size; | 91 | struct wlr_box size; |
126 | wlr_output_effective_resolution(sway_output->wlr_output, &size.width, | 92 | wlr_output_effective_resolution(sway_output->wlr_output, &size.width, |
127 | &size.height); | 93 | &size.height); |
@@ -156,22 +122,22 @@ swayc_t *new_output(struct sway_output *sway_output) { | |||
156 | return NULL; | 122 | return NULL; |
157 | } | 123 | } |
158 | 124 | ||
159 | swayc_t *output = new_swayc(C_OUTPUT); | 125 | struct sway_container *output = container_create(C_OUTPUT); |
160 | output->sway_output = sway_output; | 126 | output->sway_output = sway_output; |
161 | output->name = strdup(name); | 127 | output->name = strdup(name); |
162 | if (output->name == NULL) { | 128 | if (output->name == NULL) { |
163 | free_swayc(output); | 129 | container_destroy(output); |
164 | return NULL; | 130 | return NULL; |
165 | } | 131 | } |
166 | 132 | ||
167 | apply_output_config(oc, output); | 133 | apply_output_config(oc, output); |
168 | 134 | ||
169 | add_child(&root_container, output); | 135 | container_add_child(&root_container, output); |
170 | 136 | ||
171 | // Create workspace | 137 | // Create workspace |
172 | char *ws_name = workspace_next_name(output->name); | 138 | char *ws_name = workspace_next_name(output->name); |
173 | wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); | 139 | wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); |
174 | swayc_t *ws = new_workspace(output, ws_name); | 140 | struct sway_container *ws = container_workspace_create(output, ws_name); |
175 | // Set each seat's focus if not already set | 141 | // Set each seat's focus if not already set |
176 | struct sway_seat *seat = NULL; | 142 | struct sway_seat *seat = NULL; |
177 | wl_list_for_each(seat, &input_manager->seats, link) { | 143 | wl_list_for_each(seat, &input_manager->seats, link) { |
@@ -185,12 +151,14 @@ swayc_t *new_output(struct sway_output *sway_output) { | |||
185 | return output; | 151 | return output; |
186 | } | 152 | } |
187 | 153 | ||
188 | swayc_t *new_workspace(swayc_t *output, const char *name) { | 154 | struct sway_container *container_workspace_create( |
189 | if (!sway_assert(output, "new_workspace called with null output")) { | 155 | struct sway_container *output, const char *name) { |
156 | if (!sway_assert(output, | ||
157 | "container_workspace_create called with null output")) { | ||
190 | return NULL; | 158 | return NULL; |
191 | } | 159 | } |
192 | wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); | 160 | wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); |
193 | swayc_t *workspace = new_swayc(C_WORKSPACE); | 161 | struct sway_container *workspace = container_create(C_WORKSPACE); |
194 | 162 | ||
195 | workspace->x = output->x; | 163 | workspace->x = output->x; |
196 | workspace->y = output->y; | 164 | workspace->y = output->y; |
@@ -198,21 +166,23 @@ swayc_t *new_workspace(swayc_t *output, const char *name) { | |||
198 | workspace->height = output->height; | 166 | workspace->height = output->height; |
199 | workspace->name = !name ? NULL : strdup(name); | 167 | workspace->name = !name ? NULL : strdup(name); |
200 | workspace->prev_layout = L_NONE; | 168 | workspace->prev_layout = L_NONE; |
201 | workspace->layout = default_layout(output); | 169 | workspace->layout = container_get_default_layout(output); |
202 | workspace->workspace_layout = default_layout(output); | 170 | workspace->workspace_layout = container_get_default_layout(output); |
203 | 171 | ||
204 | add_child(output, workspace); | 172 | container_add_child(output, workspace); |
205 | sort_workspaces(output); | 173 | container_sort_workspaces(output); |
206 | notify_new_container(workspace); | 174 | notify_new_container(workspace); |
207 | return workspace; | 175 | return workspace; |
208 | } | 176 | } |
209 | 177 | ||
210 | swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) { | 178 | struct sway_container *container_view_create(struct sway_container *sibling, |
211 | if (!sway_assert(sibling, "new_view called with NULL sibling/parent")) { | 179 | struct sway_view *sway_view) { |
180 | if (!sway_assert(sibling, | ||
181 | "container_view_create called with NULL sibling/parent")) { | ||
212 | return NULL; | 182 | return NULL; |
213 | } | 183 | } |
214 | const char *title = view_get_title(sway_view); | 184 | const char *title = view_get_title(sway_view); |
215 | swayc_t *swayc = new_swayc(C_VIEW); | 185 | struct sway_container *swayc = container_create(C_VIEW); |
216 | wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s", | 186 | wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s", |
217 | swayc, title, sibling, sibling ? sibling->type : 0, sibling->name); | 187 | swayc, title, sibling, sibling ? sibling->type : 0, sibling->name); |
218 | // Setup values | 188 | // Setup values |
@@ -223,17 +193,18 @@ swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) { | |||
223 | 193 | ||
224 | if (sibling->type == C_WORKSPACE) { | 194 | if (sibling->type == C_WORKSPACE) { |
225 | // Case of focused workspace, just create as child of it | 195 | // Case of focused workspace, just create as child of it |
226 | add_child(sibling, swayc); | 196 | container_add_child(sibling, swayc); |
227 | } else { | 197 | } else { |
228 | // Regular case, create as sibling of current container | 198 | // Regular case, create as sibling of current container |
229 | add_sibling(sibling, swayc); | 199 | container_add_sibling(sibling, swayc); |
230 | } | 200 | } |
231 | notify_new_container(swayc); | 201 | notify_new_container(swayc); |
232 | return swayc; | 202 | return swayc; |
233 | } | 203 | } |
234 | 204 | ||
235 | swayc_t *destroy_output(swayc_t *output) { | 205 | struct sway_container *container_output_destroy(struct sway_container *output) { |
236 | if (!sway_assert(output, "null output passed to destroy_output")) { | 206 | if (!sway_assert(output, |
207 | "null output passed to container_output_destroy")) { | ||
237 | return NULL; | 208 | return NULL; |
238 | } | 209 | } |
239 | 210 | ||
@@ -245,12 +216,13 @@ swayc_t *destroy_output(swayc_t *output) { | |||
245 | int p = root_container.children->items[0] == output; | 216 | int p = root_container.children->items[0] == output; |
246 | // Move workspace from this output to another output | 217 | // Move workspace from this output to another output |
247 | while (output->children->length) { | 218 | while (output->children->length) { |
248 | swayc_t *child = output->children->items[0]; | 219 | struct sway_container *child = output->children->items[0]; |
249 | remove_child(child); | 220 | container_remove_child(child); |
250 | add_child(root_container.children->items[p], child); | 221 | container_add_child(root_container.children->items[p], child); |
251 | } | 222 | } |
252 | sort_workspaces(root_container.children->items[p]); | 223 | container_sort_workspaces(root_container.children->items[p]); |
253 | arrange_windows(root_container.children->items[p], -1, -1); | 224 | arrange_windows(root_container.children->items[p], |
225 | -1, -1); | ||
254 | } | 226 | } |
255 | } | 227 | } |
256 | 228 | ||
@@ -259,18 +231,18 @@ swayc_t *destroy_output(swayc_t *output) { | |||
259 | wl_list_remove(&output->sway_output->mode.link); | 231 | wl_list_remove(&output->sway_output->mode.link); |
260 | 232 | ||
261 | wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); | 233 | wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); |
262 | free_swayc(output); | 234 | container_destroy(output); |
263 | 235 | ||
264 | return &root_container; | 236 | return &root_container; |
265 | } | 237 | } |
266 | 238 | ||
267 | swayc_t *destroy_view(swayc_t *view) { | 239 | struct sway_container *container_view_destroy(struct sway_container *view) { |
268 | if (!view) { | 240 | if (!view) { |
269 | return NULL; | 241 | return NULL; |
270 | } | 242 | } |
271 | wlr_log(L_DEBUG, "Destroying view '%s'", view->name); | 243 | wlr_log(L_DEBUG, "Destroying view '%s'", view->name); |
272 | swayc_t *parent = view->parent; | 244 | struct sway_container *parent = view->parent; |
273 | free_swayc(view); | 245 | container_destroy(view); |
274 | 246 | ||
275 | // TODO WLR: Destroy empty containers | 247 | // TODO WLR: Destroy empty containers |
276 | /* | 248 | /* |
@@ -281,7 +253,55 @@ swayc_t *destroy_view(swayc_t *view) { | |||
281 | return parent; | 253 | return parent; |
282 | } | 254 | } |
283 | 255 | ||
284 | swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { | 256 | struct sway_container *container_set_layout(struct sway_container *container, |
257 | enum sway_container_layout layout) { | ||
258 | if (container->type == C_WORKSPACE) { | ||
259 | container->workspace_layout = layout; | ||
260 | if (layout == L_HORIZ || layout == L_VERT) { | ||
261 | container->layout = layout; | ||
262 | } | ||
263 | } else { | ||
264 | container->layout = layout; | ||
265 | } | ||
266 | return container; | ||
267 | } | ||
268 | |||
269 | void container_descendants(struct sway_container *root, | ||
270 | enum sway_container_type type, | ||
271 | void (*func)(struct sway_container *item, void *data), void *data) { | ||
272 | for (int i = 0; i < root->children->length; ++i) { | ||
273 | struct sway_container *item = root->children->items[i]; | ||
274 | if (item->type == type) { | ||
275 | func(item, data); | ||
276 | } | ||
277 | if (item->children && item->children->length) { | ||
278 | container_descendants(item, type, func, data); | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | struct sway_container *container_find(struct sway_container *container, | ||
284 | bool (*test)(struct sway_container *view, void *data), void *data) { | ||
285 | if (!container->children) { | ||
286 | return NULL; | ||
287 | } | ||
288 | // TODO: floating windows | ||
289 | for (int i = 0; i < container->children->length; ++i) { | ||
290 | struct sway_container *child = container->children->items[i]; | ||
291 | if (test(child, data)) { | ||
292 | return child; | ||
293 | } else { | ||
294 | struct sway_container *res = container_find(child, test, data); | ||
295 | if (res) { | ||
296 | return res; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | return NULL; | ||
301 | } | ||
302 | |||
303 | struct sway_container *container_parent(struct sway_container *container, | ||
304 | enum sway_container_type type) { | ||
285 | if (!sway_assert(container, "container is NULL")) { | 305 | if (!sway_assert(container, "container is NULL")) { |
286 | return NULL; | 306 | return NULL; |
287 | } | 307 | } |
@@ -294,7 +314,8 @@ swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { | |||
294 | return container; | 314 | return container; |
295 | } | 315 | } |
296 | 316 | ||
297 | swayc_t *swayc_at(swayc_t *parent, double lx, double ly, | 317 | struct sway_container *container_at(struct sway_container *parent, |
318 | double lx, double ly, | ||
298 | struct wlr_surface **surface, double *sx, double *sy) { | 319 | struct wlr_surface **surface, double *sx, double *sy) { |
299 | list_t *queue = get_bfs_queue(); | 320 | list_t *queue = get_bfs_queue(); |
300 | if (!queue) { | 321 | if (!queue) { |
@@ -303,13 +324,13 @@ swayc_t *swayc_at(swayc_t *parent, double lx, double ly, | |||
303 | 324 | ||
304 | list_add(queue, parent); | 325 | list_add(queue, parent); |
305 | 326 | ||
306 | swayc_t *swayc = NULL; | 327 | struct sway_container *swayc = NULL; |
307 | while (queue->length) { | 328 | while (queue->length) { |
308 | swayc = queue->items[0]; | 329 | swayc = queue->items[0]; |
309 | list_del(queue, 0); | 330 | list_del(queue, 0); |
310 | if (swayc->type == C_VIEW) { | 331 | if (swayc->type == C_VIEW) { |
311 | struct sway_view *sview = swayc->sway_view; | 332 | struct sway_view *sview = swayc->sway_view; |
312 | swayc_t *soutput = swayc_parent_by_type(swayc, C_OUTPUT); | 333 | struct sway_container *soutput = container_parent(swayc, C_OUTPUT); |
313 | struct wlr_box *output_box = | 334 | struct wlr_box *output_box = |
314 | wlr_output_layout_get_box( | 335 | wlr_output_layout_get_box( |
315 | root_container.sway_root->output_layout, | 336 | root_container.sway_root->output_layout, |
@@ -379,30 +400,23 @@ swayc_t *swayc_at(swayc_t *parent, double lx, double ly, | |||
379 | return NULL; | 400 | return NULL; |
380 | } | 401 | } |
381 | 402 | ||
382 | void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { | 403 | void container_for_each_descendant_dfs(struct sway_container *container, |
404 | void (*f)(struct sway_container *container, void *data), | ||
405 | void *data) { | ||
383 | if (container) { | 406 | if (container) { |
384 | int i; | ||
385 | if (container->children) { | 407 | if (container->children) { |
386 | for (i = 0; i < container->children->length; ++i) { | 408 | for (int i = 0; i < container->children->length; ++i) { |
387 | swayc_t *child = container->children->items[i]; | 409 | struct sway_container *child = |
388 | container_map(child, f, data); | 410 | container->children->items[i]; |
411 | container_for_each_descendant_dfs(child, f, data); | ||
389 | } | 412 | } |
390 | } | 413 | } |
391 | // TODO | ||
392 | /* | ||
393 | if (container->floating) { | ||
394 | for (i = 0; i < container->floating->length; ++i) { | ||
395 | swayc_t *child = container->floating->items[i]; | ||
396 | container_map(child, f, data); | ||
397 | } | ||
398 | } | ||
399 | */ | ||
400 | f(container, data); | 414 | f(container, data); |
401 | } | 415 | } |
402 | } | 416 | } |
403 | 417 | ||
404 | void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data), | 418 | void container_for_each_descendant_bfs(struct sway_container *con, |
405 | void *data) { | 419 | void (*f)(struct sway_container *con, void *data), void *data) { |
406 | list_t *queue = get_bfs_queue(); | 420 | list_t *queue = get_bfs_queue(); |
407 | if (!queue) { | 421 | if (!queue) { |
408 | return; | 422 | return; |
@@ -415,7 +429,7 @@ void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data), | |||
415 | 429 | ||
416 | list_add(queue, con); | 430 | list_add(queue, con); |
417 | 431 | ||
418 | swayc_t *current = NULL; | 432 | struct sway_container *current = NULL; |
419 | while (queue->length) { | 433 | while (queue->length) { |
420 | current = queue->items[0]; | 434 | current = queue->items[0]; |
421 | list_del(queue, 0); | 435 | list_del(queue, 0); |
@@ -424,15 +438,3 @@ void container_for_each_bfs(swayc_t *con, void (*f)(swayc_t *con, void *data), | |||
424 | list_cat(queue, current->children); | 438 | list_cat(queue, current->children); |
425 | } | 439 | } |
426 | } | 440 | } |
427 | |||
428 | swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) { | ||
429 | if (container->type == C_WORKSPACE) { | ||
430 | container->workspace_layout = layout; | ||
431 | if (layout == L_HORIZ || layout == L_VERT) { | ||
432 | container->layout = layout; | ||
433 | } | ||
434 | } else { | ||
435 | container->layout = layout; | ||
436 | } | ||
437 | return container; | ||
438 | } | ||