mirror of
https://github.com/swaywm/sway.git
synced 2025-03-31 09:27:46 +03:00
Avoid crashing on too many containers
If far too many containers are created, they can become so small that their size calculations come out negative, leading to crashes on asserts. Instead, set a lower bound for sizes and disable the container entirely if it goes below it, giving whatever space it used to the last container. The splits are not recalculated, so currently the effect is that if all containers have the same width fraction, they keep getting narrower until at some point they all round to zero and the last container will be given all the available space. A better behavior would have been if the additional container did not contribute to size and fraction calculations at all, but it's an extreme edge-case, anything is better than crashing, and this is easier to implement.
This commit is contained in:
parent
4b185a0fe0
commit
c2d6aff64c
2 changed files with 33 additions and 12 deletions
|
@ -312,9 +312,9 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
wlr_scene_node_set_position(&child->scene_tree->node, 0, title_bar_height);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
|
||||
if (activated) {
|
||||
arrange_container(child, width, height - title_bar_height,
|
||||
title_bar_height == 0, 0);
|
||||
height -= title_bar_height;
|
||||
if (activated && width > 0 && height > 0) {
|
||||
arrange_container(child, width, height, title_bar_height == 0, 0);
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
|
@ -341,9 +341,9 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
wlr_scene_node_set_position(&child->scene_tree->node, 0, title_height);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
|
||||
if (activated) {
|
||||
arrange_container(child, width, height - title_height,
|
||||
title_bar_height == 0, 0);
|
||||
height -= title_bar_height;
|
||||
if (activated && width > 0 && height > 0) {
|
||||
arrange_container(child, width, height, title_bar_height == 0, 0);
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
|
@ -359,8 +359,12 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
wlr_scene_node_set_enabled(&child->border.tree->node, true);
|
||||
wlr_scene_node_set_position(&child->scene_tree->node, 0, off);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
arrange_container(child, width, cheight, true, gaps);
|
||||
off += cheight + gaps;
|
||||
if (width > 0 && cheight > 0) {
|
||||
arrange_container(child, width, cheight, true, gaps);
|
||||
off += cheight + gaps;
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
}
|
||||
} else if (layout == L_HORIZ) {
|
||||
int off = 0;
|
||||
|
@ -372,7 +376,12 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
wlr_scene_node_set_position(&child->scene_tree->node, off, 0);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
arrange_container(child, cwidth, height, true, gaps);
|
||||
off += cwidth + gaps;
|
||||
if (cwidth > 0 && height > 0) {
|
||||
arrange_container(child, cwidth, height, true, gaps);
|
||||
off += cwidth + gaps;
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sway_assert(false, "unreachable");
|
||||
|
|
|
@ -29,7 +29,7 @@ static void apply_horiz_layout(list_t *children, struct wlr_box *parent) {
|
|||
}
|
||||
}
|
||||
|
||||
// Calculate each height fraction
|
||||
// Calculate each width fraction
|
||||
double total_width_fraction = 0;
|
||||
for (int i = 0; i < children->length; ++i) {
|
||||
struct sway_container *child = children->items[i];
|
||||
|
@ -82,12 +82,18 @@ static void apply_horiz_layout(list_t *children, struct wlr_box *parent) {
|
|||
child->pending.y = parent->y;
|
||||
child->pending.width = round(child->width_fraction * child_total_width);
|
||||
child->pending.height = parent->height;
|
||||
child_x += child->pending.width + inner_gap;
|
||||
|
||||
// Make last child use remaining width of parent
|
||||
if (i == children->length - 1) {
|
||||
child->pending.width = parent->x + parent->width - child->pending.x;
|
||||
}
|
||||
|
||||
// Arbitrary lower bound for window size
|
||||
if (child->pending.width < 10 || child->pending.height < 10) {
|
||||
child->pending.width = 0;
|
||||
child->pending.height = 0;
|
||||
}
|
||||
child_x += child->pending.width + inner_gap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,12 +167,18 @@ static void apply_vert_layout(list_t *children, struct wlr_box *parent) {
|
|||
child->pending.y = child_y;
|
||||
child->pending.width = parent->width;
|
||||
child->pending.height = round(child->height_fraction * child_total_height);
|
||||
child_y += child->pending.height + inner_gap;
|
||||
|
||||
// Make last child use remaining height of parent
|
||||
if (i == children->length - 1) {
|
||||
child->pending.height = parent->y + parent->height - child->pending.y;
|
||||
}
|
||||
|
||||
// Arbitrary lower bound for window size
|
||||
if (child->pending.width < 10 || child->pending.height < 10) {
|
||||
child->pending.width = 0;
|
||||
child->pending.height = 0;
|
||||
}
|
||||
child_y += child->pending.height + inner_gap;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue