Make 'focus' disable blocking fullscreen windows

The problem here is that con_fullscreen_permits_focusing() does not
check if there is a blocking fullscreen container in the workspace that
the container to be focused belongs. This makes it possible to focus a
container behind a fullscreen window if it's in an unfocused workspace.

This commit introduces a change in the 'focus' command behaviour. When
focusing a container blocked by a fullscreen container, either CF_OUTPUT
or CF_GLOBAL, the blocking container loses its fullscreen mode and the
target container is focused like normal.

This should not affect directional focus commands: left, right, up,
down, parent, child.

Fixes issue #1819.
This commit is contained in:
Orestis Floros
2017-09-17 02:20:48 +03:00
parent 994a479558
commit 2403c43f7b
2 changed files with 116 additions and 19 deletions

View File

@ -157,9 +157,6 @@ isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
cmd 'focus child';
is($x->input_focus, $right2->id, 'bottom right window focused again');
cmd '[id="' . $left->id . '"] focus';
is($x->input_focus, $right2->id, 'prevented focus change to left window');
cmd 'focus up';
is($x->input_focus, $right1->id, 'allowed focus up');
@ -178,9 +175,6 @@ is($x->input_focus, $right1->id, 'allowed focus wrap (down)');
cmd 'focus up';
is($x->input_focus, $right2->id, 'allowed focus wrap (up)');
cmd '[id="' . $diff_ws->id . '"] focus';
is($x->input_focus, $right2->id, 'prevented focus change to different ws');
################################################################################
# Same tests when we're in non-global fullscreen mode. It should now be possible
# to focus a container in a different workspace.
@ -202,9 +196,6 @@ isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
cmd 'focus child';
is($x->input_focus, $right2->id, 'bottom right window focused again');
cmd '[id="' . $left->id . '"] focus';
is($x->input_focus, $right2->id, 'prevented focus change to left window');
cmd 'focus up';
is($x->input_focus, $right1->id, 'allowed focus up');
@ -323,6 +314,105 @@ verify_move(2, 'prevented move to workspace by name');
cmd "move to workspace prev";
verify_move(2, 'prevented move to workspace by position');
# TODO: Tests for "move to output" and "move workspace to output".
################################################################################
# Ensure it's possible to focus a window using the focus command despite
# fullscreen window blocking it. Fullscreen window should lose its fullscreen
# mode.
################################################################################
# first & second tiling, focus using id
kill_all_windows;
$tmp = fresh_workspace;
my $first = open_window;
my $second = open_window;
cmd 'fullscreen';
is($x->input_focus, $second->id, 'fullscreen window focused');
is_num_fullscreen($tmp, 1, '1 fullscreen window');
cmd '[id="'. $first->id .'"] focus';
sync_with_i3;
is($x->input_focus, $first->id, 'correctly focused using id');
is_num_fullscreen($tmp, 0, 'no fullscreen windows');
# first floating, second tiling, focus using 'focus floating'
kill_all_windows;
$tmp = fresh_workspace;
my $first = open_floating_window;
my $second = open_window;
cmd 'fullscreen';
is($x->input_focus, $second->id, 'fullscreen window focused');
is_num_fullscreen($tmp, 1, '1 fullscreen window');
cmd 'focus floating';
sync_with_i3;
is($x->input_focus, $first->id, 'correctly focused using focus floating');
is_num_fullscreen($tmp, 0, 'no fullscreen windows');
# first tiling, second floating, focus using 'focus tiling'
kill_all_windows;
$tmp = fresh_workspace;
my $first = open_window;
my $second = open_floating_window;
cmd 'fullscreen';
is($x->input_focus, $second->id, 'fullscreen window focused');
is_num_fullscreen($tmp, 1, '1 fullscreen window');
cmd 'focus tiling';
sync_with_i3;
is($x->input_focus, $first->id, 'correctly focused using focus tiling');
is_num_fullscreen($tmp, 0, 'no fullscreen windows');
################################################################################
# When the fullscreen window is in an other workspace it should maintain its
# fullscreen mode since it's not blocking the window to be focused.
################################################################################
kill_all_windows;
$tmp = fresh_workspace;
my $first = open_window;
$tmp2 = fresh_workspace;
my $second = open_window;
cmd 'fullscreen';
is($x->input_focus, $second->id, 'fullscreen window focused');
is_num_fullscreen($tmp2, 1, '1 fullscreen window');
cmd '[id="'. $first->id .'"] focus';
sync_with_i3;
is($x->input_focus, $first->id, 'correctly focused using focus id');
is_num_fullscreen($tmp, 0, 'no fullscreen windows on first workspace');
is_num_fullscreen($tmp2, 1, 'still one fullscreen window on second workspace');
################################################################################
# But a global window in another workspace is blocking the window to be focused.
# Ensure that it loses its fullscreen mode.
################################################################################
kill_all_windows;
$tmp = fresh_workspace;
$first = open_window;
$tmp2 = fresh_workspace;
$second = open_window;
cmd 'fullscreen global';
is($x->input_focus, $second->id, 'global window focused');
is_num_fullscreen($tmp2, 1, '1 fullscreen window');
cmd '[id="'. $first->id .'"] focus';
sync_with_i3;
is($x->input_focus, $first->id, 'correctly focused using focus id');
is_num_fullscreen($tmp2, 0, 'no fullscreen windows');
# TODO: Tests for "move to output" and "move workspace to output".
done_testing;