For resizing, convert pixel diff to percentage, based on parent.

Previously, it first calculated one of the containers' next percentage, and then subtracted the previous percentage to find the actual change.

Now it directly calculates the change, and subtracts and adds the change to the two affected containers.

Added util function con_rect_size_in_orientation.

Removed px_resize_to_percent; inlined, using con_rect_size_in_orientation.

Also, prematurely return when pixel diff is 0, as no action is necessary.

This is related to [this issue on i3-gaps](https://github.com/Airblader/i3/issues/247).
This commit is contained in:
aksel 2018-11-07 22:49:04 +01:00
parent 44e8fddc28
commit bbfa140c0f
6 changed files with 33 additions and 29 deletions

View File

@ -533,3 +533,10 @@ i3String *con_parse_title_format(Con *con);
*
*/
bool con_swap(Con *first, Con *second);
/**
* Returns given container's rect size depending on its orientation.
* i.e. its width when horizontal, its height when vertical.
*
*/
uint32_t con_rect_size_in_orientation(Con *con);

View File

@ -31,9 +31,3 @@ bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt);
*
*/
double percent_for_1px(Con *con);
/**
* Calculate the given container's new percent given a change in pixels.
*
*/
double px_resize_to_percent(Con *con, int px_diff);

View File

@ -537,8 +537,9 @@ static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *dir
if (ppt != 0.0) {
new_current_percent = current->percent + ppt;
} else {
new_current_percent = px_resize_to_percent(current, px);
ppt = new_current_percent - current->percent;
/* Convert px change to change in percentages */
ppt = (double)px / (double)con_rect_size_in_orientation(current->parent);
new_current_percent = current->percent + ppt;
}
subtract_percent = ppt / (children - 1);
if (ppt < 0.0 && new_current_percent < percent_for_1px(current)) {

View File

@ -2430,3 +2430,12 @@ bool con_swap(Con *first, Con *second) {
return true;
}
/*
* Returns container's rect size depending on its orientation.
* i.e. its width when horizontal, its height when vertical.
*
*/
uint32_t con_rect_size_in_orientation(Con *con) {
return (con_orientation(con) == HORIZ ? con->rect.width : con->rect.height);
}

View File

@ -192,7 +192,7 @@ static int *precalculate_sizes(Con *con, render_params *p) {
Con *child;
int i = 0, assigned = 0;
int total = con_orientation(con) == HORIZ ? p->rect.width : p->rect.height;
int total = con_rect_size_in_orientation(con);
TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
double percentage = child->percent > 0.0 ? child->percent : 1.0 / p->children;
assigned += sizes[i++] = lround(percentage * total);

View File

@ -101,30 +101,16 @@ bool resize_find_tiling_participants(Con **current, Con **other, direction_t dir
return true;
}
/*
* Calculate the given container's new percent given a change in pixels.
*
*/
double px_resize_to_percent(Con *con, int px_diff) {
Con *parent = con->parent;
const orientation_t o = con_orientation(parent);
const int total = (o == HORIZ ? parent->rect.width : parent->rect.height);
/* deco_rect.height is subtracted from each child in render_con_split */
const int target = px_diff + (o == HORIZ ? con->rect.width : con->rect.height + con->deco_rect.height);
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);
const int parent_size = con_rect_size_in_orientation(con->parent);
/* deco_rect.height is subtracted from each child in render_con_split */
const int min_size = (con_orientation(con->parent) == HORIZ ? 1 : 1 + con->deco_rect.height);
return ((double)min_size / (double)parent_size);
}
/*
@ -145,8 +131,10 @@ bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt) {
new_first_percent = first->percent + ((double)ppt / 100.0);
new_second_percent = second->percent - ((double)ppt / 100.0);
} else {
new_first_percent = px_resize_to_percent(first, px);
new_second_percent = second->percent + first->percent - new_first_percent;
/* Convert px change to change in percentages */
const double pct = (double)px / (double)con_rect_size_in_orientation(first->parent);
new_first_percent = first->percent + pct;
new_second_percent = second->percent - pct;
}
/* Ensure that no container will be less than 1 pixel in the resizing
* direction. */
@ -234,6 +222,11 @@ void resize_graphical_handler(Con *first, Con *second, orientation_t orientation
int pixels = (new_position - initial_position);
DLOG("Done, pixels = %d\n", pixels);
/* No change; no action needed. */
if (pixels == 0) {
return;
}
/* if we got thus far, the containers must have valid percentages. */
assert(first->percent > 0.0);
assert(second->percent > 0.0);