summaryrefslogtreecommitdiffstats
path: root/sway/container.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/container.c')
-rw-r--r--sway/container.c140
1 files changed, 105 insertions, 35 deletions
diff --git a/sway/container.c b/sway/container.c
index 7ccc2e09..62ff1c4a 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -26,14 +26,11 @@ static void free_swayc(swayc_t *cont) {
26 if (!ASSERT_NONNULL(cont)) { 26 if (!ASSERT_NONNULL(cont)) {
27 return; 27 return;
28 } 28 }
29 // TODO does not properly handle containers with children,
30 // TODO but functions that call this usually check for that
31 if (cont->children) { 29 if (cont->children) {
32 if (cont->children->length) { 30 // remove children until there are no more, free_swayc calls
33 int i; 31 // remove_child, which removes child from this container
34 for (i = 0; i < cont->children->length; ++i) { 32 while (cont->children->length) {
35 free_swayc(cont->children->items[i]); 33 free_swayc(cont->children->items[0]);
36 }
37 } 34 }
38 list_free(cont->children); 35 list_free(cont->children);
39 } 36 }
@@ -57,10 +54,6 @@ static void free_swayc(swayc_t *cont) {
57 54
58// New containers 55// New containers
59 56
60static bool workspace_test(swayc_t *view, void *name) {
61 return strcasecmp(view->name, (char *)name) == 0;
62}
63
64swayc_t *new_output(wlc_handle handle) { 57swayc_t *new_output(wlc_handle handle) {
65 const struct wlc_size* size = wlc_output_get_resolution(handle); 58 const struct wlc_size* size = wlc_output_get_resolution(handle);
66 const char *name = wlc_output_get_name(handle); 59 const char *name = wlc_output_get_name(handle);
@@ -84,7 +77,7 @@ swayc_t *new_output(wlc_handle handle) {
84 if (strcasecmp(wso->output, name) == 0) { 77 if (strcasecmp(wso->output, name) == 0) {
85 sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output); 78 sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output);
86 // Check if any other workspaces are using this name 79 // Check if any other workspaces are using this name
87 if (find_container(&root_container, workspace_test, wso->workspace)) { 80 if (workspace_by_name(wso->workspace)) {
88 sway_log(L_DEBUG, "But it's already taken"); 81 sway_log(L_DEBUG, "But it's already taken");
89 break; 82 break;
90 } 83 }
@@ -128,7 +121,8 @@ swayc_t *new_workspace(swayc_t *output, const char *name) {
128} 121}
129 122
130swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) { 123swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
131 if (!ASSERT_NONNULL(child)) { 124 if (!ASSERT_NONNULL(child)
125 && !sway_assert(!child->is_floating, "cannot create container around floating window")) {
132 return NULL; 126 return NULL;
133 } 127 }
134 swayc_t *cont = new_swayc(C_CONTAINER); 128 swayc_t *cont = new_swayc(C_CONTAINER);
@@ -207,6 +201,9 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
207} 201}
208 202
209swayc_t *new_floating_view(wlc_handle handle) { 203swayc_t *new_floating_view(wlc_handle handle) {
204 if (swayc_active_workspace() == NULL) {
205 return NULL;
206 }
210 const char *title = wlc_view_get_title(handle); 207 const char *title = wlc_view_get_title(handle);
211 swayc_t *view = new_swayc(C_VIEW); 208 swayc_t *view = new_swayc(C_VIEW);
212 sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view", 209 sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view",
@@ -220,8 +217,8 @@ swayc_t *new_floating_view(wlc_handle handle) {
220 const struct wlc_geometry* geometry = wlc_view_get_geometry(handle); 217 const struct wlc_geometry* geometry = wlc_view_get_geometry(handle);
221 218
222 // give it requested geometry, but place in center 219 // give it requested geometry, but place in center
223 view->x = (active_workspace->width - geometry->size.w) / 2; 220 view->x = (swayc_active_workspace()->width - geometry->size.w) / 2;
224 view->y = (active_workspace->height- geometry->size.h) / 2; 221 view->y = (swayc_active_workspace()->height- geometry->size.h) / 2;
225 view->width = geometry->size.w; 222 view->width = geometry->size.w;
226 view->height = geometry->size.h; 223 view->height = geometry->size.h;
227 224
@@ -231,10 +228,10 @@ swayc_t *new_floating_view(wlc_handle handle) {
231 view->is_floating = true; 228 view->is_floating = true;
232 229
233 // Case of focused workspace, just create as child of it 230 // Case of focused workspace, just create as child of it
234 list_add(active_workspace->floating, view); 231 list_add(swayc_active_workspace()->floating, view);
235 view->parent = active_workspace; 232 view->parent = swayc_active_workspace();
236 if (active_workspace->focused == NULL) { 233 if (swayc_active_workspace()->focused == NULL) {
237 set_focused_container_for(active_workspace, view); 234 set_focused_container_for(swayc_active_workspace(), view);
238 } 235 }
239 return view; 236 return view;
240} 237}
@@ -306,6 +303,35 @@ swayc_t *destroy_view(swayc_t *view) {
306 303
307// Container lookup 304// Container lookup
308 305
306
307swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
308 if (!container->children) {
309 return NULL;
310 }
311 // Special case for checking floating stuff
312 int i;
313 if (container->type == C_WORKSPACE) {
314 for (i = 0; i < container->floating->length; ++i) {
315 swayc_t *child = container->floating->items[i];
316 if (test(child, data)) {
317 return child;
318 }
319 }
320 }
321 for (i = 0; i < container->children->length; ++i) {
322 swayc_t *child = container->children->items[i];
323 if (test(child, data)) {
324 return child;
325 } else {
326 swayc_t *res = swayc_by_test(child, test, data);
327 if (res) {
328 return res;
329 }
330 }
331 }
332 return NULL;
333}
334
309swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { 335swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
310 if (!ASSERT_NONNULL(container)) { 336 if (!ASSERT_NONNULL(container)) {
311 return NULL; 337 return NULL;
@@ -315,7 +341,7 @@ swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
315 } 341 }
316 do { 342 do {
317 container = container->parent; 343 container = container->parent;
318 } while(container && container->type != type); 344 } while (container && container->type != type);
319 return container; 345 return container;
320} 346}
321 347
@@ -332,27 +358,30 @@ swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) {
332 return container; 358 return container;
333} 359}
334 360
335swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { 361static swayc_t *_swayc_by_handle_helper(wlc_handle handle, swayc_t *parent) {
336 if (!container->children) { 362 if (!parent || !parent->children) {
337 return NULL; 363 return NULL;
338 } 364 }
339 // Special case for checking floating stuff 365 int i, len;
340 int i; 366 swayc_t **child;
341 if (container->type == C_WORKSPACE) { 367 if (parent->type == C_WORKSPACE) {
342 for (i = 0; i < container->floating->length; ++i) { 368 len = parent->floating->length;
343 swayc_t *child = container->floating->items[i]; 369 child = (swayc_t **)parent->floating->items;
344 if (test(child, data)) { 370 for (i = 0; i < len; ++i, ++child) {
345 return child; 371 if ((*child)->handle == handle) {
372 return *child;
346 } 373 }
347 } 374 }
348 } 375 }
349 for (i = 0; i < container->children->length; ++i) { 376
350 swayc_t *child = container->children->items[i]; 377 len = parent->children->length;
351 if (test(child, data)) { 378 child = (swayc_t**)parent->children->items;
352 return child; 379 for (i = 0; i < len; ++i, ++child) {
380 if ((*child)->handle == handle) {
381 return *child;
353 } else { 382 } else {
354 swayc_t *res = find_container(child, test, data); 383 swayc_t *res;
355 if (res) { 384 if ((res = _swayc_by_handle_helper(handle, *child))) {
356 return res; 385 return res;
357 } 386 }
358 } 387 }
@@ -360,6 +389,47 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da
360 return NULL; 389 return NULL;
361} 390}
362 391
392swayc_t *swayc_by_handle(wlc_handle handle) {
393 return _swayc_by_handle_helper(handle, &root_container);
394}
395
396swayc_t *swayc_active_output(void) {
397 return root_container.focused;
398}
399
400swayc_t *swayc_active_workspace(void) {
401 return root_container.focused ? root_container.focused->focused : NULL;
402}
403
404swayc_t *swayc_active_workspace_for(swayc_t *cont) {
405 if (!cont) {
406 return NULL;
407 }
408 switch (cont->type) {
409 case C_ROOT:
410 cont = cont->focused;
411 /* Fallthrough */
412
413 case C_OUTPUT:
414 cont = cont->focused;
415 /* Fallthrough */
416
417 case C_WORKSPACE:
418 return cont;
419
420 default:
421 return swayc_parent_by_type(cont, C_WORKSPACE);
422 }
423}
424
425// Container information
426
427bool swayc_is_fullscreen(swayc_t *view) {
428 return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN);
429}
430
431// Mapping
432
363void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 433void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
364 if (container && container->children && container->children->length) { 434 if (container && container->children && container->children->length) {
365 int i; 435 int i;