]> git.sur5r.net Git - i3/i3/commitdiff
Ensure containers have a size of at least 1px after resize 3389/head
authorOrestis Floros <orestisf1993@gmail.com>
Thu, 6 Sep 2018 01:56:31 +0000 (04:56 +0300)
committerOrestis Floros <orestisf1993@gmail.com>
Thu, 6 Sep 2018 01:56:31 +0000 (04:56 +0300)
Fixes #2226.
Fixes #2776.
Fixes #3241.
Related to #3194.

include/resize.h
src/commands.c
src/resize.c

index 758cb4a1a28376f5e4bdd4d9d8c1ccc305fc5742..72dffc0f55a5d66c68d376938945832dea936d9e 100644 (file)
@@ -25,6 +25,13 @@ void resize_graphical_handler(Con *first, Con *second, orientation_t orientation
  */
 bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt);
 
+/**
+ * Calculate the minimum percent needed for the given container to be at least 1
+ * pixel.
+ *
+ */
+double percent_for_1px(Con *con);
+
 /**
  * Calculate the given container's new percent given a change in pixels.
  *
index 0343f9dc3525f9a68366f1b0839fde9a764a48f5..ab41ec97f4ac70d27023b618fda1c76f2b3b4830 100644 (file)
@@ -551,24 +551,25 @@ static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *dir
         ppt = new_current_percent - current->percent;
     }
     subtract_percent = ppt / (children - 1);
+    if (ppt < 0.0 && new_current_percent < percent_for_1px(current)) {
+        yerror("Not resizing, container would end with less than 1px\n");
+        return false;
+    }
 
     LOG("new_current_percent = %f\n", new_current_percent);
     LOG("subtract_percent = %f\n", subtract_percent);
     /* Ensure that the new percentages are positive. */
-    TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
-        if (child == current)
-            continue;
-        if (child->percent - subtract_percent <= 0.0) {
-            LOG("Not resizing, already at minimum size (child %p would end up with a size of %.f\n", child, child->percent - subtract_percent);
-            ysuccess(false);
-            return false;
+    if (subtract_percent >= 0.0) {
+        TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
+            if (child == current) {
+                continue;
+            }
+            if (child->percent - subtract_percent < percent_for_1px(child)) {
+                yerror("Not resizing, already at minimum size (child %p would end up with a size of %.f\n", child, child->percent - subtract_percent);
+                return false;
+            }
         }
     }
-    if (new_current_percent <= 0.0) {
-        LOG("Not resizing, already at minimum size\n");
-        ysuccess(false);
-        return false;
-    }
 
     current->percent = new_current_percent;
     LOG("current->percent after = %f\n", current->percent);
index 38591b457030ed9674fa513f58d5f3861335f3b3..d746ea227f9bb55b608d658586177a263fec776c 100644 (file)
@@ -114,6 +114,19 @@ double px_resize_to_percent(Con *con, int px_diff) {
     return ((double)target / (double)total);
 }
 
+/*
+ * Calculate the minimum percent needed for the given container to be at least 1
+ * pixel.
+ *
+ */
+double percent_for_1px(Con *con) {
+    Con *parent = con->parent;
+    const orientation_t o = con_orientation(parent);
+    const int total = (o == HORIZ ? parent->rect.width : parent->rect.height);
+    const int target = (o == HORIZ ? 1 : 1 + con->deco_rect.height);
+    return ((double)target / (double)total);
+}
+
 /*
  * Resize the two given containers using the given amount of pixels or
  * percentage points. One of the two needs to be 0. A positive amount means
@@ -126,8 +139,6 @@ bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt) {
     assert(px * ppt == 0);
 
     Con *parent = first->parent;
-    orientation_t orientation = con_orientation(parent);
-    const int total = (orientation == HORIZ ? parent->rect.width : parent->rect.height);
     double new_first_percent;
     double new_second_percent;
     if (ppt) {
@@ -139,7 +150,7 @@ bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt) {
     }
     /* Ensure that no container will be less than 1 pixel in the resizing
      * direction. */
-    if (lround(new_first_percent * total) <= 0 || lround(new_second_percent * total) <= 0) {
+    if (new_first_percent < percent_for_1px(first) || new_second_percent < percent_for_1px(second)) {
         return false;
     }