diff options
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r-- | sway/tree/layout.c | 101 |
1 files changed, 86 insertions, 15 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index a8941a40..83e4fe37 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> |
@@ -100,10 +101,12 @@ void container_add_child(struct sway_container *parent, | |||
100 | parent, parent->type, parent->width, parent->height); | 101 | parent, parent->type, parent->width, parent->height); |
101 | list_add(parent->children, child); | 102 | list_add(parent->children, child); |
102 | child->parent = parent; | 103 | child->parent = parent; |
104 | // TODO: set focus for this container? | ||
105 | sway_input_manager_set_focus(input_manager, child); | ||
103 | } | 106 | } |
104 | 107 | ||
105 | struct sway_container *container_reap_empty(struct sway_container *container) { | 108 | struct sway_container *container_reap_empty(struct sway_container *container) { |
106 | if (!sway_assert(container, "reaping null container")) { | 109 | if (container == NULL) { |
107 | return NULL; | 110 | return NULL; |
108 | } | 111 | } |
109 | wlr_log(L_DEBUG, "Reaping %p %s '%s'", container, | 112 | wlr_log(L_DEBUG, "Reaping %p %s '%s'", container, |
@@ -137,7 +140,7 @@ struct sway_container *container_remove_child(struct sway_container *child) { | |||
137 | } | 140 | } |
138 | } | 141 | } |
139 | child->parent = NULL; | 142 | child->parent = NULL; |
140 | return container_reap_empty(parent); | 143 | return parent; |
141 | } | 144 | } |
142 | 145 | ||
143 | void container_move_to(struct sway_container *container, | 146 | void container_move_to(struct sway_container *container, |
@@ -348,7 +351,12 @@ static void apply_horiz_layout(struct sway_container *container, | |||
348 | wlr_log(L_DEBUG, | 351 | wlr_log(L_DEBUG, |
349 | "Calculating arrangement for %p:%d (will scale %f by %f)", | 352 | "Calculating arrangement for %p:%d (will scale %f by %f)", |
350 | child, child->type, width, scale); | 353 | child, child->type, width, scale); |
351 | view_set_position(child->sway_view, child_x, y); | 354 | if (child->type == C_VIEW) { |
355 | view_set_position(child->sway_view, child_x, y); | ||
356 | } else { | ||
357 | child->x = child_x; | ||
358 | child->y = y; | ||
359 | } | ||
352 | 360 | ||
353 | if (i == end - 1) { | 361 | if (i == end - 1) { |
354 | double remaining_width = x + width - child_x; | 362 | double remaining_width = x + width - child_x; |
@@ -531,9 +539,9 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) { | |||
531 | return NULL; | 539 | return NULL; |
532 | } | 540 | } |
533 | 541 | ||
534 | static struct sway_container *get_swayc_in_direction_under( | 542 | struct sway_container *container_get_in_direction( |
535 | struct sway_container *container, enum movement_direction dir, | 543 | struct sway_container *container, struct sway_seat *seat, |
536 | struct sway_seat *seat, struct sway_container *limit) { | 544 | enum movement_direction dir) { |
537 | if (dir == MOVE_CHILD) { | 545 | if (dir == MOVE_CHILD) { |
538 | return sway_seat_get_focus_inactive(seat, container); | 546 | return sway_seat_get_focus_inactive(seat, container); |
539 | } | 547 | } |
@@ -565,7 +573,6 @@ static struct sway_container *get_swayc_in_direction_under( | |||
565 | 573 | ||
566 | struct sway_container *wrap_candidate = NULL; | 574 | struct sway_container *wrap_candidate = NULL; |
567 | while (true) { | 575 | while (true) { |
568 | // Test if we can even make a difference here | ||
569 | bool can_move = false; | 576 | bool can_move = false; |
570 | int desired; | 577 | int desired; |
571 | int idx = index_child(container); | 578 | int idx = index_child(container); |
@@ -595,7 +602,7 @@ static struct sway_container *get_swayc_in_direction_under( | |||
595 | } | 602 | } |
596 | if (next->children && next->children->length) { | 603 | if (next->children && next->children->length) { |
597 | // TODO consider floating children as well | 604 | // TODO consider floating children as well |
598 | return sway_seat_get_focus_inactive(seat, next); | 605 | return sway_seat_get_focus_by_type(seat, next, C_VIEW); |
599 | } else { | 606 | } else { |
600 | return next; | 607 | return next; |
601 | } | 608 | } |
@@ -625,21 +632,22 @@ static struct sway_container *get_swayc_in_direction_under( | |||
625 | wrap_candidate = parent->children->items[0]; | 632 | wrap_candidate = parent->children->items[0]; |
626 | } | 633 | } |
627 | if (config->force_focus_wrapping) { | 634 | if (config->force_focus_wrapping) { |
628 | return wrap_candidate; | 635 | return sway_seat_get_focus_by_type(seat, wrap_candidate, C_VIEW); |
629 | } | 636 | } |
630 | } | 637 | } |
631 | } else { | 638 | } else { |
632 | wlr_log(L_DEBUG, | 639 | wlr_log(L_DEBUG, |
633 | "cont %d-%p dir %i sibling %d: %p", idx, | 640 | "cont %d-%p dir %i sibling %d: %p", idx, |
634 | container, dir, desired, parent->children->items[desired]); | 641 | container, dir, desired, parent->children->items[desired]); |
635 | return parent->children->items[desired]; | 642 | return sway_seat_get_focus_by_type(seat, |
643 | parent->children->items[desired], C_VIEW); | ||
636 | } | 644 | } |
637 | } | 645 | } |
638 | 646 | ||
639 | if (!can_move) { | 647 | if (!can_move) { |
640 | container = parent; | 648 | container = parent; |
641 | parent = parent->parent; | 649 | parent = parent->parent; |
642 | if (!parent || container == limit) { | 650 | if (!parent) { |
643 | // wrapping is the last chance | 651 | // wrapping is the last chance |
644 | return wrap_candidate; | 652 | return wrap_candidate; |
645 | } | 653 | } |
@@ -647,8 +655,71 @@ static struct sway_container *get_swayc_in_direction_under( | |||
647 | } | 655 | } |
648 | } | 656 | } |
649 | 657 | ||
650 | struct sway_container *container_get_in_direction( | 658 | struct sway_container *container_replace_child(struct sway_container *child, |
651 | struct sway_container *container, struct sway_seat *seat, | 659 | struct sway_container *new_child) { |
652 | enum movement_direction dir) { | 660 | struct sway_container *parent = child->parent; |
653 | return get_swayc_in_direction_under(container, dir, seat, NULL); | 661 | if (parent == NULL) { |
662 | return NULL; | ||
663 | } | ||
664 | int i = index_child(child); | ||
665 | |||
666 | // TODO floating | ||
667 | parent->children->items[i] = new_child; | ||
668 | new_child->parent = parent; | ||
669 | child->parent = NULL; | ||
670 | |||
671 | // Set geometry for new child | ||
672 | new_child->x = child->x; | ||
673 | new_child->y = child->y; | ||
674 | new_child->width = child->width; | ||
675 | new_child->height = child->height; | ||
676 | |||
677 | // reset geometry for child | ||
678 | child->width = 0; | ||
679 | child->height = 0; | ||
680 | |||
681 | return parent; | ||
682 | } | ||
683 | |||
684 | struct sway_container *container_split(struct sway_container *child, | ||
685 | enum sway_container_layout layout) { | ||
686 | // TODO floating: cannot split a floating container | ||
687 | if (!sway_assert(child, "child cannot be null")) { | ||
688 | return NULL; | ||
689 | } | ||
690 | struct sway_container *cont = container_create(C_CONTAINER); | ||
691 | |||
692 | wlr_log(L_DEBUG, "creating container %p around %p", cont, child); | ||
693 | |||
694 | cont->prev_layout = L_NONE; | ||
695 | cont->layout = layout; | ||
696 | cont->width = child->width; | ||
697 | cont->height = child->height; | ||
698 | cont->x = child->x; | ||
699 | cont->y = child->y; | ||
700 | |||
701 | /* Container inherits all of workspaces children, layout and whatnot */ | ||
702 | if (child->type == C_WORKSPACE) { | ||
703 | struct sway_container *workspace = child; | ||
704 | // reorder focus | ||
705 | int i; | ||
706 | for (i = 0; i < workspace->children->length; ++i) { | ||
707 | ((struct sway_container *)workspace->children->items[i])->parent = | ||
708 | cont; | ||
709 | } | ||
710 | |||
711 | // Swap children | ||
712 | list_t *tmp_list = workspace->children; | ||
713 | workspace->children = cont->children; | ||
714 | cont->children = tmp_list; | ||
715 | // add container to workspace chidren | ||
716 | container_add_child(workspace, cont); | ||
717 | // give them proper layouts | ||
718 | cont->layout = workspace->workspace_layout; | ||
719 | cont->prev_layout = workspace->prev_layout; | ||
720 | } else { // Or is built around container | ||
721 | container_replace_child(child, cont); | ||
722 | container_add_child(cont, child); | ||
723 | } | ||
724 | return cont; | ||
654 | } | 725 | } |