]> git.sur5r.net Git - i3/i3/blobdiff - src/commands.c
Merge pull request #2998 from orestisf1993/issue-2990
[i3/i3] / src / commands.c
index df2b236b10d23423074d3bbd0608b3b429a1b927..afb624bea5208c4691c7c10ebc832598651b917f 100644 (file)
@@ -511,7 +511,7 @@ static bool cmd_resize_tiling_direction(I3_CMD, Con *current, const char *way, c
     else
         search_direction = D_DOWN;
 
-    bool res = resize_find_tiling_participants(&first, &second, search_direction);
+    bool res = resize_find_tiling_participants(&first, &second, search_direction, false);
     if (!res) {
         LOG("No second container in this direction found.\n");
         ysuccess(false);
@@ -552,19 +552,15 @@ static bool cmd_resize_tiling_direction(I3_CMD, Con *current, const char *way, c
 
 static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *way, const char *direction, int ppt) {
     LOG("width/height resize\n");
-    /* get the appropriate current container (skip stacked/tabbed cons) */
-    while (current->parent->layout == L_STACKED ||
-           current->parent->layout == L_TABBED)
-        current = current->parent;
-
-    /* Then further go up until we find one with the matching orientation. */
-    orientation_t search_orientation =
-        (strcmp(direction, "width") == 0 ? HORIZ : VERT);
 
-    while (current->type != CT_WORKSPACE &&
-           current->type != CT_FLOATING_CON &&
-           (con_orientation(current->parent) != search_orientation || con_num_children(current->parent) == 1))
-        current = current->parent;
+    /* get the appropriate current container (skip stacked/tabbed cons) */
+    Con *dummy = NULL;
+    direction_t search_direction = (strcmp(direction, "width") == 0 ? D_LEFT : D_DOWN);
+    bool search_result = resize_find_tiling_participants(&current, &dummy, search_direction, true);
+    if (search_result == false) {
+        ysuccess(false);
+        return false;
+    }
 
     /* get the default percentage */
     int children = con_num_children(current->parent);
@@ -572,24 +568,6 @@ static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *way
     double percentage = 1.0 / children;
     LOG("default percentage = %f\n", percentage);
 
-    orientation_t orientation = con_orientation(current->parent);
-
-    if ((orientation == HORIZ &&
-         strcmp(direction, "height") == 0) ||
-        (orientation == VERT &&
-         strcmp(direction, "width") == 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 (children == 1) {
-        LOG("This is the only container, cannot resize.\n");
-        ysuccess(false);
-        return false;
-    }
-
     /* Ensure all the other children have a percentage set. */
     Con *child;
     TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
@@ -681,7 +659,7 @@ void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px,
  */
 void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height) {
     DLOG("resizing to %ld %s x %ld %s\n", cwidth, mode_width, cheight, mode_height);
-    if (cwidth <= 0 || cheight <= 0) {
+    if (cwidth < 0 || cheight < 0) {
         ELOG("Resize failed: dimensions cannot be negative (was %ld %s x %ld %s)\n", cwidth, mode_width, cheight, mode_height);
         return;
     }
@@ -689,25 +667,84 @@ void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, c
     HANDLE_EMPTY_MATCH;
 
     owindow *current;
+    bool success = true;
     TAILQ_FOREACH(current, &owindows, owindows) {
         Con *floating_con;
         if ((floating_con = con_inside_floating(current->con))) {
             Con *output = con_get_output(floating_con);
-            if (mode_width && strcmp(mode_width, "ppt") == 0) {
+            if (cwidth == 0) {
+                cwidth = output->rect.width;
+            } else if (mode_width && strcmp(mode_width, "ppt") == 0) {
                 cwidth = output->rect.width * ((double)cwidth / 100.0);
             }
-            if (mode_height && strcmp(mode_height, "ppt") == 0) {
+            if (cheight == 0) {
+                cheight = output->rect.height;
+            } else if (mode_height && strcmp(mode_height, "ppt") == 0) {
                 cheight = output->rect.height * ((double)cheight / 100.0);
             }
             floating_resize(floating_con, cwidth, cheight);
         } else {
-            ELOG("Resize failed: %p not a floating container\n", current->con);
+            if (current->con->window && current->con->window->dock) {
+                DLOG("This is a dock window. Not resizing (con = %p)\n)", current->con);
+                continue;
+            }
+
+            if (cwidth > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
+                /* get the appropriate current container (skip stacked/tabbed cons) */
+                Con *target = current->con;
+                Con *dummy;
+                resize_find_tiling_participants(&target, &dummy, D_LEFT, true);
+
+                /* Calculate new size for the target container */
+                double current_percent = target->percent;
+                char *action_string;
+                long adjustment;
+
+                if (current_percent > cwidth) {
+                    action_string = "shrink";
+                    adjustment = (int)(current_percent * 100) - cwidth;
+                } else {
+                    action_string = "grow";
+                    adjustment = cwidth - (int)(current_percent * 100);
+                }
+
+                /* perform resizing and report failure if not possible */
+                if (!cmd_resize_tiling_width_height(current_match, cmd_output,
+                                                    target, action_string, "width", adjustment)) {
+                    success = false;
+                }
+            }
+
+            if (cheight > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
+                /* get the appropriate current container (skip stacked/tabbed cons) */
+                Con *target = current->con;
+                Con *dummy;
+                resize_find_tiling_participants(&target, &dummy, D_DOWN, true);
+
+                /* Calculate new size for the target container */
+                double current_percent = target->percent;
+                char *action_string;
+                long adjustment;
+
+                if (current_percent > cheight) {
+                    action_string = "shrink";
+                    adjustment = (int)(current_percent * 100) - cheight;
+                } else {
+                    action_string = "grow";
+                    adjustment = cheight - (int)(current_percent * 100);
+                }
+
+                /* perform resizing and report failure if not possible */
+                if (!cmd_resize_tiling_width_height(current_match, cmd_output,
+                                                    target, action_string, "height", adjustment)) {
+                    success = false;
+                }
+            }
         }
     }
 
     cmd_output->needs_tree_render = true;
-    // XXX: default reply for now, make this a better reply
-    ysuccess(true);
+    ysuccess(success);
 }
 
 /*
@@ -767,6 +804,7 @@ void cmd_nop(I3_CMD, const char *comment) {
     LOG("-------------------------------------------------\n");
     LOG("  NOP: %s\n", comment);
     LOG("-------------------------------------------------\n");
+    ysuccess(true);
 }
 
 /*