gaps: change workspace rendering to fix sizes with large outer gaps (#5252)

Currently, containers only consider their neighbors and screen edges.

If >2 containers are in a line, the outer containers adjust from outer gaps, but
the middle containers know nothing of this and only consider the inner gaps.

When the outer gaps differ substantially from the inner gaps, the left-most and
right-most containers are smaller as only they adjust for the larger outer gaps.

This commit changes the rendering: containers are now always inset by their
inner gap settings, and workspace containers is now inset by the outer gap
settings.

The result is that many tiled containers have the same size, and the gaps
overall work as the user might expect them to previous combinations of
outer/inner gap settings still produce the same result, albeit with fixed
outer-most sizes.

fixes https://github.com/Airblader/i3/issues/22

related to https://github.com/i3/i3/issues/3724

Co-authored-by: Cameron Leger <contact@cameronleger.com>
This commit is contained in:
Michael Stapelberg 2022-11-06 21:22:21 +01:00 committed by GitHub
parent 69e13d7821
commit e6a28b9475
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 11 deletions

View File

@ -27,7 +27,7 @@ gaps_t calculate_effective_gaps(Con *con) {
return (gaps_t){0, 0, 0, 0, 0};
gaps_t gaps = {
.inner = (workspace->gaps.inner + config.gaps.inner) / 2,
.inner = (workspace->gaps.inner + config.gaps.inner),
.top = 0,
.right = 0,
.bottom = 0,
@ -40,12 +40,6 @@ gaps_t calculate_effective_gaps(Con *con) {
gaps.left = workspace->gaps.left + config.gaps.left;
}
/* Outer gaps are added on top of inner gaps. */
gaps.top += 2 * gaps.inner;
gaps.right += 2 * gaps.inner;
gaps.bottom += 2 * gaps.inner;
gaps.left += 2 * gaps.inner;
return gaps;
}

View File

@ -49,13 +49,28 @@ void render_con(Con *con) {
DLOG("Rendering node %p / %s / layout %d / children %d\n", con, con->name,
con->layout, params.children);
if (con->type == CT_WORKSPACE) {
gaps_t gaps = calculate_effective_gaps(con);
Rect inset = (Rect){
gaps.left,
gaps.top,
-(gaps.left + gaps.right),
-(gaps.top + gaps.bottom),
};
con->rect = rect_add(con->rect, inset);
params.rect = rect_add(params.rect, inset);
params.x += gaps.left;
params.y += gaps.top;
}
if (gaps_should_inset_con(con, params.children)) {
gaps_t gaps = calculate_effective_gaps(con);
Rect inset = (Rect){
gaps_has_adjacent_container(con, D_LEFT) ? gaps.inner : gaps.left,
gaps_has_adjacent_container(con, D_UP) ? gaps.inner : gaps.top,
gaps_has_adjacent_container(con, D_RIGHT) ? -gaps.inner : -gaps.right,
gaps_has_adjacent_container(con, D_DOWN) ? -gaps.inner : -gaps.bottom};
gaps_has_adjacent_container(con, D_LEFT) ? gaps.inner / 2 : gaps.inner,
gaps_has_adjacent_container(con, D_UP) ? gaps.inner / 2 : gaps.inner,
gaps_has_adjacent_container(con, D_RIGHT) ? -(gaps.inner / 2) : -gaps.inner,
gaps_has_adjacent_container(con, D_DOWN) ? -(gaps.inner / 2) : -gaps.inner,
};
inset.width -= inset.x;
inset.height -= inset.y;