]> git.sur5r.net Git - i3/i3/commitdiff
Allow focus child/parent when in fullscreen.
authorFernando Tarlá Cardoso Lemos <fernandotcl@gmail.com>
Sat, 26 May 2012 21:36:25 +0000 (18:36 -0300)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 3 Jun 2012 14:24:53 +0000 (16:24 +0200)
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
include/tree.h
src/commands.c
src/con.c
src/tree.c
testcases/t/156-fullscreen-focus.t
testcases/t/157-regress-fullscreen-level-up.t [deleted file]

index b9159e3b5b134851ae759ebb0935aadcdcd47230..8816b19a640a55d0fa84300bdd59295c56c24943 100644 (file)
@@ -39,16 +39,16 @@ Con *tree_open_con(Con *con, i3Window *window);
 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
index b3c955e56d926e3b2fe8eab3e795f7c0d534356e..cf8187b70542ea9ab588ec7d22b08b2de1ad3a30 100644 (file)
@@ -1213,23 +1213,26 @@ void cmd_focus_window_mode(I3_CMD, char *window_mode) {
  *
  */
 void cmd_focus_level(I3_CMD, char *level) {
-    if (focused &&
-        focused->type != CT_WORKSPACE &&
-        focused->fullscreen_mode != CF_NONE) {
-        LOG("Cannot change focus while in fullscreen mode.\n");
-        ysuccess(false);
-        return;
-    }
-
     DLOG("level = %s\n", level);
+    bool success = false;
+
+    /* Focusing the parent can only be allowed if the newly
+     * focused container won't escape the fullscreen container. */
+    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");
+        }
+    }
 
-    if (strcmp(level, "parent") == 0)
-        level_up();
-    else level_down();
+    /* Focusing a child should always be allowed. */
+    else success = level_down();
 
-    cmd_output->needs_tree_render = true;
+    cmd_output->needs_tree_render = success;
     // XXX: default reply for now, make this a better reply
-    ysuccess(true);
+    ysuccess(success);
 }
 
 /*
index f969d0569c791f211d35523a7271188c838b6494..a7ae642b3e496e2232725fc5e672d0b0bed0c7fb 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -1170,6 +1170,10 @@ bool con_fullscreen_permits_focusing(Con *con) {
     if (fs->type == CT_WORKSPACE)
         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
      * sufficient to guarantee that change won't leave fullscreen in bad shape. */
     if (fs->fullscreen_mode == CF_OUTPUT &&
index f29369c607eba2d0e64b64d630a0d6ffe78753c2..cb3d044ab91c7f8966cf2716a33b985639c4c1a0 100644 (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) {
-    /* 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;
-    }
+bool level_up(void) {
     /* We can focus up to the workspace, but not any higher in the tree */
     if ((focused->parent->type != CT_CON &&
         focused->parent->type != CT_WORKSPACE) ||
         focused->type == CT_WORKSPACE) {
         LOG("Cannot go up any further\n");
-        return;
+        return false;
     }
     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 */
     Con *next = TAILQ_FIRST(&(focused->focus_head));
     if (next == TAILQ_END(&(focused->focus_head))) {
         printf("cannot go down\n");
-        return;
+        return false;
     }
     con_focus(next);
+    return true;
 }
 
 static void mark_unmapped(Con *con) {
index 3a27c9ffa28ea36d50dd35f4f467937f0e6143c6..65d23815706e504993870fbcf7e423f5a1d16686 100644 (file)
@@ -122,6 +122,12 @@ is($x->input_focus, $right1->id, 'upper right window focused');
 cmd '[id="' . $right2->id . '"] focus';
 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';
 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');
 
 ################################################################################
-# Same tests when we're in non-global fullscreen mode. We toggle fullscreen on
-# and off to avoid testing whether focus level works in fullscreen for now. It
-# should now be possible to focus a container in a different workspace.
+# Same tests when we're in non-global fullscreen mode. It should now be possible
+# to focus a container in a different workspace.
 ################################################################################
 
-cmd 'fullscreen global';
-cmd 'fullscreen global';
-
-cmd '[id="' . $right1->id . '"] focus';
-is($x->input_focus, $right1->id, 'upper right window focused');
-
 cmd 'focus parent';
+cmd 'fullscreen global';
 cmd 'fullscreen';
 
 cmd '[id="' . $right1->id . '"] focus';
-is($x->input_focus, $right1->id, 'upper right window still focused');
+is($x->input_focus, $right1->id, 'upper right window focused');
 
 cmd '[id="' . $right2->id . '"] focus';
 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';
 is($x->input_focus, $right2->id, 'prevented focus change to left window');
 
diff --git a/testcases/t/157-regress-fullscreen-level-up.t b/testcases/t/157-regress-fullscreen-level-up.t
deleted file mode 100644 (file)
index 316dbca..0000000
+++ /dev/null
@@ -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 it’s 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;