From 23c1c13d3479098aabf768cf83be4b6b70cfd7f0 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Thu, 6 Sep 2018 04:56:31 +0300 Subject: [PATCH] Ensure containers have a size of at least 1px after resize Fixes #2226. Fixes #2776. Fixes #3241. Related to #3194. --- include/resize.h | 7 +++++++ src/commands.c | 25 +++++++++++++------------ src/resize.c | 17 ++++++++++++++--- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/resize.h b/include/resize.h index 758cb4a1..72dffc0f 100644 --- a/include/resize.h +++ b/include/resize.h @@ -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. * diff --git a/src/commands.c b/src/commands.c index 0343f9dc..ab41ec97 100644 --- a/src/commands.c +++ b/src/commands.c @@ -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); diff --git a/src/resize.c b/src/resize.c index 38591b45..d746ea22 100644 --- a/src/resize.c +++ b/src/resize.c @@ -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; } -- 2.39.2