Allow focus child/parent when in fullscreen.

This is now restricted according to the already defined fullscreen
focus constraints. Test case 157 was removed, as we don't prevent
level up/down in fullscreen anymore. Those commands are properly
tested in fullscreen by test case 156.

Fixes: #612
This commit is contained in:
Fernando Tarlá Cardoso Lemos 2012-05-26 18:36:25 -03:00 committed by Michael Stapelberg
parent da1e232757
commit 250c260eaa
6 changed files with 48 additions and 80 deletions

View File

@ -39,16 +39,16 @@ Con *tree_open_con(Con *con, i3Window *window);
void tree_split(Con *con, orientation_t orientation); void tree_split(Con *con, orientation_t orientation);
/** /**
* Moves focus one level up. * Moves focus one level up. Returns true if focus changed.
* *
*/ */
void level_up(void); bool level_up(void);
/** /**
* Moves focus one level down. * Moves focus one level down. Returns true if focus changed.
* *
*/ */
void level_down(void); bool level_down(void);
/** /**
* Renders the tree, that is rendering all outputs using render_con() and * Renders the tree, that is rendering all outputs using render_con() and

View File

@ -1213,23 +1213,26 @@ void cmd_focus_window_mode(I3_CMD, char *window_mode) {
* *
*/ */
void cmd_focus_level(I3_CMD, char *level) { void cmd_focus_level(I3_CMD, char *level) {
if (focused && DLOG("level = %s\n", level);
focused->type != CT_WORKSPACE && bool success = false;
focused->fullscreen_mode != CF_NONE) {
LOG("Cannot change focus while in fullscreen mode.\n"); /* Focusing the parent can only be allowed if the newly
ysuccess(false); * focused container won't escape the fullscreen container. */
return; if (strcmp(level, "parent") == 0) {
if (focused && focused->parent) {
if (con_fullscreen_permits_focusing(focused->parent))
success = level_up();
else
LOG("Currently in fullscreen, not going up\n");
}
} }
DLOG("level = %s\n", level); /* Focusing a child should always be allowed. */
else success = level_down();
if (strcmp(level, "parent") == 0) cmd_output->needs_tree_render = success;
level_up();
else level_down();
cmd_output->needs_tree_render = true;
// XXX: default reply for now, make this a better reply // XXX: default reply for now, make this a better reply
ysuccess(true); ysuccess(success);
} }
/* /*

View File

@ -1170,6 +1170,10 @@ bool con_fullscreen_permits_focusing(Con *con) {
if (fs->type == CT_WORKSPACE) if (fs->type == CT_WORKSPACE)
return true; return true;
/* Allow it if the container itself is the fullscreen container. */
if (con == fs)
return true;
/* If fullscreen is per-output, the focus being in a different workspace is /* If fullscreen is per-output, the focus being in a different workspace is
* sufficient to guarantee that change won't leave fullscreen in bad shape. */ * sufficient to guarantee that change won't leave fullscreen in bad shape. */
if (fs->fullscreen_mode == CF_OUTPUT && if (fs->fullscreen_mode == CF_OUTPUT &&

View File

@ -375,38 +375,34 @@ void tree_split(Con *con, orientation_t orientation) {
} }
/* /*
* Moves focus one level up. * Moves focus one level up. Returns true if focus changed.
* *
*/ */
void level_up(void) { bool level_up(void) {
/* We cannot go up when we are in fullscreen mode at the moment, that would
* be totally not intuitive */
if (focused->fullscreen_mode != CF_NONE) {
LOG("Currently in fullscreen, not going up\n");
return;
}
/* We can focus up to the workspace, but not any higher in the tree */ /* We can focus up to the workspace, but not any higher in the tree */
if ((focused->parent->type != CT_CON && if ((focused->parent->type != CT_CON &&
focused->parent->type != CT_WORKSPACE) || focused->parent->type != CT_WORKSPACE) ||
focused->type == CT_WORKSPACE) { focused->type == CT_WORKSPACE) {
LOG("Cannot go up any further\n"); LOG("Cannot go up any further\n");
return; return false;
} }
con_focus(focused->parent); con_focus(focused->parent);
return true;
} }
/* /*
* Moves focus one level down. * Moves focus one level down. Returns true if focus changed.
* *
*/ */
void level_down(void) { bool level_down(void) {
/* Go down the focus stack of the current node */ /* Go down the focus stack of the current node */
Con *next = TAILQ_FIRST(&(focused->focus_head)); Con *next = TAILQ_FIRST(&(focused->focus_head));
if (next == TAILQ_END(&(focused->focus_head))) { if (next == TAILQ_END(&(focused->focus_head))) {
printf("cannot go down\n"); printf("cannot go down\n");
return; return false;
} }
con_focus(next); con_focus(next);
return true;
} }
static void mark_unmapped(Con *con) { static void mark_unmapped(Con *con) {

View File

@ -122,6 +122,12 @@ is($x->input_focus, $right1->id, 'upper right window focused');
cmd '[id="' . $right2->id . '"] focus'; cmd '[id="' . $right2->id . '"] focus';
is($x->input_focus, $right2->id, 'bottom right window focused'); is($x->input_focus, $right2->id, 'bottom right window focused');
cmd 'focus parent';
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'; cmd '[id="' . $left->id . '"] focus';
is($x->input_focus, $right2->id, 'prevented focus change to left window'); is($x->input_focus, $right2->id, 'prevented focus change to left window');
@ -129,26 +135,26 @@ cmd '[id="' . $diff_ws->id . '"] focus';
is($x->input_focus, $right2->id, 'prevented focus change to different ws'); is($x->input_focus, $right2->id, 'prevented focus change to different ws');
################################################################################ ################################################################################
# Same tests when we're in non-global fullscreen mode. We toggle fullscreen on # Same tests when we're in non-global fullscreen mode. It should now be possible
# and off to avoid testing whether focus level works in fullscreen for now. It # to focus a container in a different workspace.
# should now be possible to focus a container in a different workspace.
################################################################################ ################################################################################
cmd 'focus parent';
cmd 'fullscreen global'; cmd 'fullscreen global';
cmd 'fullscreen global'; cmd 'fullscreen';
cmd '[id="' . $right1->id . '"] focus'; cmd '[id="' . $right1->id . '"] focus';
is($x->input_focus, $right1->id, 'upper right window focused'); is($x->input_focus, $right1->id, 'upper right window focused');
cmd 'focus parent';
cmd 'fullscreen';
cmd '[id="' . $right1->id . '"] focus';
is($x->input_focus, $right1->id, 'upper right window still focused');
cmd '[id="' . $right2->id . '"] focus'; cmd '[id="' . $right2->id . '"] focus';
is($x->input_focus, $right2->id, 'bottom right window focused'); is($x->input_focus, $right2->id, 'bottom right window focused');
cmd 'focus parent';
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'; cmd '[id="' . $left->id . '"] focus';
is($x->input_focus, $right2->id, 'prevented focus change to left window'); is($x->input_focus, $right2->id, 'prevented focus change to left window');

View File

@ -1,41 +0,0 @@
#!perl
# vim:ts=4:sw=4:expandtab
#
# Regression test: level up should be a noop during fullscreen mode
#
use i3test;
my $tmp = fresh_workspace;
#####################################################################
# open a window, verify its not in fullscreen mode
#####################################################################
my $win = open_window;
my $nodes = get_ws_content $tmp;
is(@$nodes, 1, 'exactly one client');
is($nodes->[0]->{fullscreen_mode}, 0, 'client not fullscreen');
#####################################################################
# make it fullscreen
#####################################################################
cmd 'nop making fullscreen';
cmd 'fullscreen';
$nodes = get_ws_content $tmp;
is($nodes->[0]->{fullscreen_mode}, 1, 'client fullscreen now');
#####################################################################
# send level up, try to un-fullscreen
#####################################################################
cmd 'focus parent';
cmd 'fullscreen';
$nodes = get_ws_content $tmp;
is($nodes->[0]->{fullscreen_mode}, 0, 'client not fullscreen any longer');
does_i3_live;
done_testing;