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