]> git.sur5r.net Git - i3/i3/commitdiff
Allow 'focus $dir' to move out of non-global fullscreen containers
authorDeiz <silverwraithii@gmail.com>
Mon, 8 Oct 2012 16:28:08 +0000 (12:28 -0400)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 9 Oct 2012 19:26:49 +0000 (21:26 +0200)
src/tree.c
testcases/t/156-fullscreen-focus.t

index f233fd691c5e93bca775b0f83498c19384208461..8681a3b906770d551e30adb2a2c02ac748211556 100644 (file)
@@ -463,12 +463,18 @@ void tree_render(void) {
  *
  */
 static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap) {
+    /* When dealing with fullscreen containers, it's necessary to go up to the
+     * workspace level, because 'focus $dir' will start at the con's real
+     * position in the tree, and it may not be possible to get to the edge
+     * normally due to fullscreen focusing restrictions. */
+    if (con->fullscreen_mode == CF_OUTPUT && con->type != CT_WORKSPACE)
+        con = con_get_workspace(con);
+
     /* Stop recursing at workspaces after attempting to switch to next
      * workspace if possible. */
     if (con->type == CT_WORKSPACE) {
-        if (con_get_fullscreen_con(con, CF_GLOBAL) ||
-            con_get_fullscreen_con(con, CF_OUTPUT)) {
-            DLOG("Cannot change workspace while in fullscreen mode.\n");
+        if (con_get_fullscreen_con(con, CF_GLOBAL)) {
+            DLOG("Cannot change workspace while in global fullscreen mode.\n");
             return false;
         }
         Output *current_output = get_output_containing(con->rect.x, con->rect.y);
@@ -505,6 +511,13 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap)
             return false;
 
         workspace_show(workspace);
+
+        /* If a workspace has an active fullscreen container, one of its
+         * children should always be focused. The above workspace_show()
+         * should be adequate for that, so return. */
+        if (con_get_fullscreen_con(workspace, CF_OUTPUT))
+            return true;
+
         Con *focus = con_descend_direction(workspace, direction);
         if (focus) {
             con_focus(focus);
index 23be014a8acc21dd998f25ed3968bf202f57569e..170c641d2e0b918c146738ce4f8965e52903c62d 100644 (file)
@@ -125,10 +125,18 @@ is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
 
 cmd 'fullscreen';
 
+# Focus screen 1
+$x->root->warp_pointer(1025, 0);
+sync_with_i3;
+
 $tmp = fresh_workspace;
 cmd "workspace $tmp";
 my $diff_ws = open_window;
 
+# Focus screen 0
+$x->root->warp_pointer(0, 0);
+sync_with_i3;
+
 $tmp2 = fresh_workspace;
 cmd "workspace $tmp2";
 cmd 'split h';
@@ -207,21 +215,24 @@ is($x->input_focus, $right1->id, 'allowed focus up');
 cmd 'focus down';
 is($x->input_focus, $right2->id, 'allowed focus down');
 
-cmd 'focus left';
-is($x->input_focus, $right2->id, 'prevented focus left');
-
-cmd 'focus right';
-is($x->input_focus, $right2->id, 'prevented focus right');
-
 cmd 'focus down';
 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';
+cmd 'focus left';
+is($x->input_focus, $right2->id, 'focus left wrapped (no-op)');
+
+cmd 'focus right';
 is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws');
 
+cmd 'focus left';
+is($x->input_focus, $right2->id, 'focused back into fullscreen container');
+
+cmd '[id="' . $diff_ws->id . '"] focus';
+is($x->input_focus, $diff_ws->id, 'allowed focus change to different ws by id');
+
 ################################################################################
 # More testing of the interaction between wrapping and the fullscreen focus
 # restrictions.