diff options
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r-- | sway/tree/layout.c | 111 |
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 | ||
105 | struct sway_container *container_reap_empty(struct sway_container *container) { | 106 | struct 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 | ||
143 | void container_move_to(struct sway_container *container, | 144 | void 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 | ||
536 | static struct sway_container *get_swayc_in_direction_under( | 548 | struct 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 | ||
652 | struct sway_container *container_get_in_direction( | 665 | struct 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 | |||
691 | struct 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 | } |