Ensure containers have a size of at least 1px after resize

Fixes #2226.
Fixes #2776.
Fixes #3241.
Related to #3194.
This commit is contained in:
Orestis Floros 2018-09-06 04:56:31 +03:00
parent 09683d21a9
commit 23c1c13d34
No known key found for this signature in database
GPG Key ID: E9AD9F32E401E38F
3 changed files with 34 additions and 15 deletions

View 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.
*

View File

@ -551,23 +551,24 @@ 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. */
if (subtract_percent >= 0.0) {
TAILQ_FOREACH(child, &(current->parent->nodes_head), nodes) {
if (child == current)
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);
}
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;

View 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;
}