]> git.sur5r.net Git - i3/i3/commitdiff
resizing: traverse containers up properly (+test) (Thanks oblique)
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 22 Jul 2012 19:37:26 +0000 (21:37 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 22 Jul 2012 19:37:26 +0000 (21:37 +0200)
In certain situations (when you have a h-split within a h-split) you
couldn’t properly resize previously. This commit makes the resize
command properly traverse up the containers.

fixes #754

src/commands.c
testcases/t/191-resize-levels.t [new file with mode: 0644]

index 3066a809a5b145ccab5874a1dbe899fbba0c046b..7b6d55a7aac7a4ef42492b42db5fd99a60df6dea 100644 (file)
@@ -519,6 +519,8 @@ static bool cmd_resize_tiling_direction(I3_CMD, char *way, char *direction, int
     LOG("tiling resize\n");
     /* get the appropriate current container (skip stacked/tabbed cons) */
     Con *current = focused;
+    Con *other = NULL;
+    double percentage = 0;
     while (current->parent->layout == L_STACKED ||
            current->parent->layout == L_TABBED)
         current = current->parent;
@@ -527,40 +529,50 @@ static bool cmd_resize_tiling_direction(I3_CMD, char *way, char *direction, int
     orientation_t search_orientation =
         (strcmp(direction, "left") == 0 || strcmp(direction, "right") == 0 ? HORIZ : VERT);
 
-    while (current->type != CT_WORKSPACE &&
-           current->type != CT_FLOATING_CON &&
-           current->parent->orientation != search_orientation)
-        current = current->parent;
+    do {
+        if (current->parent->orientation != search_orientation) {
+            current = current->parent;
+            continue;
+        }
 
-    /* get the default percentage */
-    int children = con_num_children(current->parent);
-    Con *other;
-    LOG("ins. %d children\n", children);
-    double percentage = 1.0 / children;
-    LOG("default percentage = %f\n", percentage);
+        /* get the default percentage */
+        int children = con_num_children(current->parent);
+        LOG("ins. %d children\n", children);
+        percentage = 1.0 / children;
+        LOG("default percentage = %f\n", percentage);
 
-    orientation_t orientation = current->parent->orientation;
+        orientation_t orientation = current->parent->orientation;
 
-    if ((orientation == HORIZ &&
-         (strcmp(direction, "up") == 0 || strcmp(direction, "down") == 0)) ||
-        (orientation == VERT &&
-         (strcmp(direction, "left") == 0 || strcmp(direction, "right") == 0))) {
-        LOG("You cannot resize in that direction. Your focus is in a %s split container currently.\n",
-            (orientation == HORIZ ? "horizontal" : "vertical"));
-        ysuccess(false);
-        return false;
-    }
+        if ((orientation == HORIZ &&
+             (strcmp(direction, "up") == 0 || strcmp(direction, "down") == 0)) ||
+            (orientation == VERT &&
+             (strcmp(direction, "left") == 0 || strcmp(direction, "right") == 0))) {
+            LOG("You cannot resize in that direction. Your focus is in a %s split container currently.\n",
+                (orientation == HORIZ ? "horizontal" : "vertical"));
+            ysuccess(false);
+            return false;
+        }
 
-    if (strcmp(direction, "up") == 0 || strcmp(direction, "left") == 0) {
-        other = TAILQ_PREV(current, nodes_head, nodes);
-    } else {
-        other = TAILQ_NEXT(current, nodes);
-    }
-    if (other == TAILQ_END(workspaces)) {
-        LOG("No other container in this direction found, cannot resize.\n");
+        if (strcmp(direction, "up") == 0 || strcmp(direction, "left") == 0) {
+            other = TAILQ_PREV(current, nodes_head, nodes);
+        } else {
+            other = TAILQ_NEXT(current, nodes);
+        }
+        if (other == TAILQ_END(workspaces)) {
+            LOG("No other container in this direction found, trying to look further up in the tree...\n");
+            current = current->parent;
+            continue;
+        }
+        break;
+    } while (current->type != CT_WORKSPACE &&
+             current->type != CT_FLOATING_CON);
+
+    if (other == NULL) {
+        LOG("No other container in this direction found, trying to look further up in the tree...\n");
         ysuccess(false);
         return false;
     }
+
     LOG("other->percent = %f\n", other->percent);
     LOG("current->percent before = %f\n", current->percent);
     if (current->percent == 0.0)
diff --git a/testcases/t/191-resize-levels.t b/testcases/t/191-resize-levels.t
new file mode 100644 (file)
index 0000000..230a491
--- /dev/null
@@ -0,0 +1,29 @@
+#!perl
+# vim:ts=4:sw=4:expandtab
+# Verifies that you can resize across different levels of containers even when
+# they are all of the same orientation.
+# (Ticket #754)
+use i3test;
+
+my $tmp = fresh_workspace;
+
+open_window;
+open_window;
+cmd 'split v';
+my $middle = open_window;
+open_window;
+cmd 'focus parent';
+cmd 'split h';
+open_window;
+
+cmd '[id="' . $middle->id . '"] focus';
+is($x->input_focus, $middle->id, 'middle window focused');
+
+cmd 'resize grow left 10px or 25ppt';
+
+my ($nodes, $focus) = get_ws_content($tmp);
+
+ok(cmp_float($nodes->[0]->{percent}, 0.25), 'left container got only 25%');
+ok(cmp_float($nodes->[1]->{percent}, 0.75), 'right container got 75%');
+
+done_testing;