summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-02-28 18:20:18 +0100
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-02-28 18:20:18 +0100
commit6088c6cdf0a72a430a22a6c7ac4e75c14e98a949 (patch)
treebfa2fd2360f72ae4e4d036e58821fbe49e5c3eb3
parentMerge pull request #492 from mikkeloscar/swaybar-multi-output (diff)
downloadsway-6088c6cdf0a72a430a22a6c7ac4e75c14e98a949.tar.gz
sway-6088c6cdf0a72a430a22a6c7ac4e75c14e98a949.tar.zst
sway-6088c6cdf0a72a430a22a6c7ac4e75c14e98a949.zip
Correctly move focus from one output to a new one.
This patch aims to correctly handle moving focus <left|right|up|down> between outputs. For instance, if moving from one output to a new output at the left of the current one, it should focus the right-most view/container on the new output, and the opposite if moving from right to left. This should happen regardless of the previously stored focus of the new output. This also handles moving to a new output above or below the current one.
-rw-r--r--sway/layout.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/sway/layout.c b/sway/layout.c
index d5fdbf0b..dca4e47f 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -617,6 +617,50 @@ void arrange_windows(swayc_t *container, double width, double height) {
617 layout_log(&root_container, 0); 617 layout_log(&root_container, 0);
618} 618}
619 619
620/**
621 * Get swayc in the direction of newly entered output.
622 */
623static swayc_t *get_swayc_in_output_direction(swayc_t *output, enum movement_direction dir) {
624 if (!output) {
625 return NULL;
626 }
627
628 swayc_t *ws = swayc_focus_by_type(output, C_WORKSPACE);
629 if (ws && ws->children->length > 0) {
630 switch (dir) {
631 case MOVE_LEFT:
632 // get most right child of new output
633 return ws->children->items[ws->children->length-1];
634 case MOVE_RIGHT:
635 // get most left child of new output
636 return ws->children->items[0];
637 case MOVE_UP:
638 case MOVE_DOWN:
639 {
640 swayc_t *focused_view = swayc_focus_by_type(ws, C_VIEW);
641 if (focused_view && focused_view->parent) {
642 swayc_t *parent = focused_view->parent;
643 if (parent->layout == L_VERT) {
644 if (dir == MOVE_UP) {
645 // get child furthest down on new output
646 return parent->children->items[parent->children->length-1];
647 } else if (dir == MOVE_DOWN) {
648 // get child furthest up on new output
649 return parent->children->items[0];
650 }
651 }
652 return focused_view;
653 }
654 break;
655 }
656 default:
657 break;
658 }
659 }
660
661 return output;
662}
663
620swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_direction dir, swayc_t *limit) { 664swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_direction dir, swayc_t *limit) {
621 swayc_t *parent = container->parent; 665 swayc_t *parent = container->parent;
622 if (dir == MOVE_PARENT) { 666 if (dir == MOVE_PARENT) {
@@ -635,7 +679,8 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio
635 sway_log(L_DEBUG, "Moving from fullscreen view, skipping to output"); 679 sway_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
636 container = swayc_parent_by_type(container, C_OUTPUT); 680 container = swayc_parent_by_type(container, C_OUTPUT);
637 get_absolute_center_position(container, &abs_pos); 681 get_absolute_center_position(container, &abs_pos);
638 return swayc_adjacent_output(container, dir, &abs_pos, true); 682 swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
683 return get_swayc_in_output_direction(output, dir);
639 } 684 }
640 685
641 if (container->type == C_WORKSPACE && container->fullscreen) { 686 if (container->type == C_WORKSPACE && container->fullscreen) {
@@ -649,7 +694,8 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio
649 int diff = 0; 694 int diff = 0;
650 if (parent->type == C_ROOT) { 695 if (parent->type == C_ROOT) {
651 sway_log(L_DEBUG, "Moving between outputs"); 696 sway_log(L_DEBUG, "Moving between outputs");
652 return swayc_adjacent_output(container, dir, &abs_pos, true); 697 swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
698 return get_swayc_in_output_direction(output, dir);
653 } else { 699 } else {
654 if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { 700 if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
655 if (parent->layout == L_HORIZ) { 701 if (parent->layout == L_HORIZ) {