diff --git a/src/con.c b/src/con.c index 609a0d36..ad5025a9 100644 --- a/src/con.c +++ b/src/con.c @@ -1005,6 +1005,7 @@ Con *con_descend_tiling_focused(Con *con) { */ Con *con_descend_direction(Con *con, direction_t direction) { Con *most = NULL; + Con *current; int orientation = con_orientation(con); DLOG("con_descend_direction(%p, orientation %d, direction %d)\n", con, orientation, direction); if (direction == D_LEFT || direction == D_RIGHT) { @@ -1018,7 +1019,12 @@ Con *con_descend_direction(Con *con, direction_t direction) { /* Wrong orientation. We use the last focused con. Within that con, * we recurse to chose the left/right con or at least the last * focused one. */ - most = TAILQ_FIRST(&(con->focus_head)); + TAILQ_FOREACH(current, &(con->focus_head), focused) { + if (current->type != CT_FLOATING_CON) { + most = current; + break; + } + } } else { /* If the con has no orientation set, it’s not a split container * but a container with a client window, so stop recursing */ @@ -1037,7 +1043,12 @@ Con *con_descend_direction(Con *con, direction_t direction) { /* Wrong orientation. We use the last focused con. Within that con, * we recurse to chose the top/bottom con or at least the last * focused one. */ - most = TAILQ_FIRST(&(con->focus_head)); + TAILQ_FOREACH(current, &(con->focus_head), focused) { + if (current->type != CT_FLOATING_CON) { + most = current; + break; + } + } } else { /* If the con has no orientation set, it’s not a split container * but a container with a client window, so stop recursing */ diff --git a/testcases/t/510-focus-across-outputs.t b/testcases/t/510-focus-across-outputs.t new file mode 100644 index 00000000..7f68a2d5 --- /dev/null +++ b/testcases/t/510-focus-across-outputs.t @@ -0,0 +1,146 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests that switching workspaces via 'focus $dir' never leaves a floating +# window focused. +# +use i3test i3_autostart => 0; + +# Ensure the pointer is at (0, 0) so that we really start on the first +# (the left) workspace. +$x->root->warp_pointer(0, 0); + +my $config = <root->warp_pointer(1025, 0); +my $s1_ws = fresh_workspace; +sync_with_i3; + +my $fourth = open_window; + +# Focus screen 2 +$x->root->warp_pointer(0, 769); +my $s2_ws = fresh_workspace; +sync_with_i3; + +my $fifth = open_window; + +# Focus screen 3 +$x->root->warp_pointer(1025, 769); +my $s3_ws = fresh_workspace; +sync_with_i3; + +my $sixth = open_window; +my $seventh = open_window; +my $eighth = open_window; +cmd 'floating toggle'; + +# Layout should look like this (windows 3 and 8 are floating): +# S0 S1 +# ┌───┬───┬───────┐ +# │ ┌─┴─┐ │ │ +# │1│ 3 │2│ 4 │ +# │ └─┬─┘ │ │ +# ├───┴───┼───┬───┤ +# │ │ ┌─┴─┐ │ +# │ 5 │6│ 8 │7│ +# │ │ └─┬─┘ │ +# └───────┴───┴───┘ +# S2 S3 +# +################################################################### +# Test that focus (left|down|right|up) doesn't focus floating +# windows when moving into horizontally-split workspaces. +################################################################### + +sub reset_focus { + my $ws = shift; + cmd "workspace $ws; focus floating"; +} + +cmd "workspace $s1_ws"; +cmd 'focus left'; +is($x->input_focus, $second->id, 'second window focused'); +reset_focus $s0_ws; + +cmd "workspace $s1_ws"; +cmd 'focus down'; +is($x->input_focus, $seventh->id, 'seventh window focused'); +reset_focus $s3_ws; + +cmd "workspace $s2_ws"; +cmd 'focus right'; +is($x->input_focus, $sixth->id, 'sixth window focused'); +reset_focus $s3_ws; + +cmd "workspace $s2_ws"; +cmd 'focus up'; +is($x->input_focus, $second->id, 'second window focused'); +reset_focus $s0_ws; + +################################################################### +# Put the workspaces on screens 0 and 3 into vertical split mode +# and test focus (left|down|right|up) again. +################################################################### + +cmd "workspace $s0_ws"; +is($x->input_focus, $third->id, 'third window focused'); +cmd 'focus parent'; +cmd 'focus parent'; +cmd 'split v'; +reset_focus $s0_ws; + +cmd "workspace $s3_ws"; +is($x->input_focus, $eighth->id, 'eighth window focused'); +cmd 'focus parent'; +cmd 'focus parent'; +cmd 'split v'; +reset_focus $s3_ws; + +cmd "workspace $s1_ws"; +cmd 'focus left'; +is($x->input_focus, $second->id, 'second window focused'); +reset_focus $s0_ws; + +cmd "workspace $s1_ws"; +cmd 'focus down'; +is($x->input_focus, $sixth->id, 'sixth window focused'); +reset_focus $s3_ws; + +cmd "workspace $s2_ws"; +cmd 'focus right'; +is($x->input_focus, $sixth->id, 'sixth window focused'); + +cmd "workspace $s2_ws"; +cmd 'focus up'; +is($x->input_focus, $second->id, 'second window focused'); + +exit_gracefully($pid); + +done_testing;