]> git.sur5r.net Git - i3/i3/blobdiff - src/tree.c
Only warp pointer once during x_push_changes()
[i3/i3] / src / tree.c
index 272276f467bd3a84b4fc8baa829e6eddc22dc2e3..240c22a6551957b2c0fe2ccf162bfe80429d3342 100644 (file)
@@ -376,9 +376,50 @@ void tree_render() {
  *
  */
 static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap) {
-    /* Stop recursing at workspaces */
-    if (con->type == CT_WORKSPACE)
-        return false;
+    /* Stop recursing at workspaces after attempting to switch to next
+     * workspace if possible. */
+    if (con->type == CT_WORKSPACE) {
+        Output *current_output = get_output_containing(con->rect.x, con->rect.y);
+        Output *next_output;
+
+        if (!current_output)
+            return false;
+        DLOG("Current output is %s\n", current_output->name);
+
+        /* Try to find next output */
+        direction_t direction;
+        if (way == 'n' && orientation == HORIZ)
+            direction = D_RIGHT;
+        else if (way == 'p' && orientation == HORIZ)
+            direction = D_LEFT;
+        else if (way == 'n' && orientation == VERT)
+            direction = D_DOWN;
+        else if (way == 'p' && orientation == VERT)
+            direction = D_UP;
+        else
+            return false;
+
+        next_output = get_output_next(direction, current_output);
+        if (!next_output)
+            return false;
+        DLOG("Next output is %s\n", next_output->name);
+
+        /* Find visible workspace on next output */
+        Con *workspace = NULL;
+        GREP_FIRST(workspace, output_get_content(next_output->con), workspace_is_visible(child));
+
+        /* Show next workspace and focus appropriate container if possible. */
+        if (!workspace)
+            return false;
+
+        workspace_show(workspace->name);
+        Con *focus = con_descend_direction(workspace, direction);
+        if (focus) {
+            con_focus(focus);
+            x_set_warp_to(&(focus->rect));
+        }
+        return true;
+    }
 
     if (con->type == CT_FLOATING_CON) {
         /* TODO: implement focus for floating windows */