aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r--sway/tree/layout.c111
1 files changed, 93 insertions, 18 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 3333f9f1..95a84d12 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -1,4 +1,5 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h>
2#include <ctype.h> 3#include <ctype.h>
3#include <math.h> 4#include <math.h>
4#include <stdbool.h> 5#include <stdbool.h>
@@ -103,7 +104,7 @@ void container_add_child(struct sway_container *parent,
103} 104}
104 105
105struct sway_container *container_reap_empty(struct sway_container *container) { 106struct sway_container *container_reap_empty(struct sway_container *container) {
106 if (!sway_assert(container, "reaping null container")) { 107 if (container == NULL) {
107 return NULL; 108 return NULL;
108 } 109 }
109 wlr_log(L_DEBUG, "Reaping %p %s '%s'", container, 110 wlr_log(L_DEBUG, "Reaping %p %s '%s'", container,
@@ -137,7 +138,7 @@ struct sway_container *container_remove_child(struct sway_container *child) {
137 } 138 }
138 } 139 }
139 child->parent = NULL; 140 child->parent = NULL;
140 return container_reap_empty(parent); 141 return parent;
141} 142}
142 143
143void container_move_to(struct sway_container *container, 144void container_move_to(struct sway_container *container,
@@ -348,8 +349,14 @@ static void apply_horiz_layout(struct sway_container *container,
348 wlr_log(L_DEBUG, 349 wlr_log(L_DEBUG,
349 "Calculating arrangement for %p:%d (will scale %f by %f)", 350 "Calculating arrangement for %p:%d (will scale %f by %f)",
350 child, child->type, width, scale); 351 child, child->type, width, scale);
351 view_configure(child->sway_view, child_x, y, child->width, 352
352 child->height); 353 if (child->type == C_VIEW) {
354 view_configure(child->sway_view, child_x, y, child->width,
355 child->height);
356 } else {
357 child->x = child_x;
358 child->y = y;
359 }
353 360
354 if (i == end - 1) { 361 if (i == end - 1) {
355 double remaining_width = x + width - child_x; 362 double remaining_width = x + width - child_x;
@@ -400,8 +407,13 @@ void apply_vert_layout(struct sway_container *container,
400 wlr_log(L_DEBUG, 407 wlr_log(L_DEBUG,
401 "Calculating arrangement for %p:%d (will scale %f by %f)", 408 "Calculating arrangement for %p:%d (will scale %f by %f)",
402 child, child->type, height, scale); 409 child, child->type, height, scale);
403 view_configure(child->sway_view, x, child_y, child->width, 410 if (child->type == C_VIEW) {
404 child->height); 411 view_configure(child->sway_view, x, child_y, child->width,
412 child->height);
413 } else {
414 child->x = x;
415 child->y = child_y;
416 }
405 417
406 if (i == end - 1) { 418 if (i == end - 1) {
407 double remaining_height = y + height - child_y; 419 double remaining_height = y + height - child_y;
@@ -533,9 +545,9 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {
533 return NULL; 545 return NULL;
534} 546}
535 547
536static struct sway_container *get_swayc_in_direction_under( 548struct sway_container *container_get_in_direction(
537 struct sway_container *container, enum movement_direction dir, 549 struct sway_container *container, struct sway_seat *seat,
538 struct sway_seat *seat, struct sway_container *limit) { 550 enum movement_direction dir) {
539 if (dir == MOVE_CHILD) { 551 if (dir == MOVE_CHILD) {
540 return seat_get_focus_inactive(seat, container); 552 return seat_get_focus_inactive(seat, container);
541 } 553 }
@@ -567,7 +579,6 @@ static struct sway_container *get_swayc_in_direction_under(
567 579
568 struct sway_container *wrap_candidate = NULL; 580 struct sway_container *wrap_candidate = NULL;
569 while (true) { 581 while (true) {
570 // Test if we can even make a difference here
571 bool can_move = false; 582 bool can_move = false;
572 int desired; 583 int desired;
573 int idx = index_child(container); 584 int idx = index_child(container);
@@ -597,7 +608,7 @@ static struct sway_container *get_swayc_in_direction_under(
597 } 608 }
598 if (next->children && next->children->length) { 609 if (next->children && next->children->length) {
599 // TODO consider floating children as well 610 // TODO consider floating children as well
600 return seat_get_focus_inactive(seat, next); 611 return seat_get_focus_by_type(seat, next, C_VIEW);
601 } else { 612 } else {
602 return next; 613 return next;
603 } 614 }
@@ -627,21 +638,23 @@ static struct sway_container *get_swayc_in_direction_under(
627 wrap_candidate = parent->children->items[0]; 638 wrap_candidate = parent->children->items[0];
628 } 639 }
629 if (config->force_focus_wrapping) { 640 if (config->force_focus_wrapping) {
630 return wrap_candidate; 641 return seat_get_focus_by_type(seat,
642 wrap_candidate, C_VIEW);
631 } 643 }
632 } 644 }
633 } else { 645 } else {
634 wlr_log(L_DEBUG, 646 wlr_log(L_DEBUG,
635 "cont %d-%p dir %i sibling %d: %p", idx, 647 "cont %d-%p dir %i sibling %d: %p", idx,
636 container, dir, desired, parent->children->items[desired]); 648 container, dir, desired, parent->children->items[desired]);
637 return parent->children->items[desired]; 649 return seat_get_focus_by_type(seat,
650 parent->children->items[desired], C_VIEW);
638 } 651 }
639 } 652 }
640 653
641 if (!can_move) { 654 if (!can_move) {
642 container = parent; 655 container = parent;
643 parent = parent->parent; 656 parent = parent->parent;
644 if (!parent || container == limit) { 657 if (!parent) {
645 // wrapping is the last chance 658 // wrapping is the last chance
646 return wrap_candidate; 659 return wrap_candidate;
647 } 660 }
@@ -649,8 +662,70 @@ static struct sway_container *get_swayc_in_direction_under(
649 } 662 }
650} 663}
651 664
652struct sway_container *container_get_in_direction( 665struct sway_container *container_replace_child(struct sway_container *child,
653 struct sway_container *container, struct sway_seat *seat, 666 struct sway_container *new_child) {
654 enum movement_direction dir) { 667 struct sway_container *parent = child->parent;
655 return get_swayc_in_direction_under(container, dir, seat, NULL); 668 if (parent == NULL) {
669 return NULL;
670 }
671 int i = index_child(child);
672
673 // TODO floating
674 parent->children->items[i] = new_child;
675 new_child->parent = parent;
676 child->parent = NULL;
677
678 // Set geometry for new child
679 new_child->x = child->x;
680 new_child->y = child->y;
681 new_child->width = child->width;
682 new_child->height = child->height;
683
684 // reset geometry for child
685 child->width = 0;
686 child->height = 0;
687
688 return parent;
689}
690
691struct sway_container *container_split(struct sway_container *child,
692 enum sway_container_layout layout) {
693 // TODO floating: cannot split a floating container
694 if (!sway_assert(child, "child cannot be null")) {
695 return NULL;
696 }
697 struct sway_container *cont = container_create(C_CONTAINER);
698
699 wlr_log(L_DEBUG, "creating container %p around %p", cont, child);
700
701 cont->prev_layout = L_NONE;
702 cont->width = child->width;
703 cont->height = child->height;
704 cont->x = child->x;
705 cont->y = child->y;
706
707 if (child->type == C_WORKSPACE) {
708 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
709 struct sway_container *workspace = child;
710 bool set_focus = (seat_get_focus(seat) == workspace);
711
712 while (workspace->children->length) {
713 struct sway_container *ws_child = workspace->children->items[0];
714 container_remove_child(ws_child);
715 container_add_child(cont, ws_child);
716 }
717
718 container_add_child(workspace, cont);
719 container_set_layout(workspace, layout);
720
721 if (set_focus) {
722 seat_set_focus(seat, cont);
723 }
724 } else {
725 cont->layout = layout;
726 container_replace_child(child, cont);
727 container_add_child(cont, child);
728 }
729
730 return cont;
656} 731}