mirror of
https://github.com/swaywm/sway.git
synced 2026-04-16 08:21:30 -04:00
Fix negative dimensions in scene rect sizing
During cross-output tiling drags, computed box dimensions can become negative due to coordinate transforms and thickness subtractions. This triggers the assertion in wlr_scene_rect_set_size() which requires width >= 0 && height >= 0, crashing the compositor. Clamp dimensions to zero in three locations: - resize_box() in seatop_move_tiling.c for the WLR_EDGE_NONE case - update_indicator() in seatop_move_tiling.c as a safety net - arrange_container() in transaction.c for border width (matching the existing vert_border_height clamping from62fd8c4d) - update_rect_list() in container.c for pixman region boxes This is the same class of bug fixed by62fd8c4d(height clamping) and partially addressed byc2d6aff6(too-many-containers guards).
This commit is contained in:
parent
6d25b100a2
commit
da901a2102
3 changed files with 25 additions and 4 deletions
|
|
@ -435,9 +435,10 @@ static void arrange_container(struct sway_container *con,
|
||||||
int border_left = con->current.border_left ? border_width : 0;
|
int border_left = con->current.border_left ? border_width : 0;
|
||||||
int border_right = con->current.border_right ? border_width : 0;
|
int border_right = con->current.border_right ? border_width : 0;
|
||||||
int vert_border_height = MAX(0, height - border_top - border_bottom);
|
int vert_border_height = MAX(0, height - border_top - border_bottom);
|
||||||
|
int horiz_border_width = MAX(0, width);
|
||||||
|
|
||||||
wlr_scene_rect_set_size(con->border.top, width, border_top);
|
wlr_scene_rect_set_size(con->border.top, horiz_border_width, border_top);
|
||||||
wlr_scene_rect_set_size(con->border.bottom, width, border_bottom);
|
wlr_scene_rect_set_size(con->border.bottom, horiz_border_width, border_bottom);
|
||||||
wlr_scene_rect_set_size(con->border.left,
|
wlr_scene_rect_set_size(con->border.left,
|
||||||
border_left, vert_border_height);
|
border_left, vert_border_height);
|
||||||
wlr_scene_rect_set_size(con->border.right,
|
wlr_scene_rect_set_size(con->border.right,
|
||||||
|
|
@ -449,7 +450,7 @@ static void arrange_container(struct sway_container *con,
|
||||||
wlr_scene_node_set_position(&con->border.left->node,
|
wlr_scene_node_set_position(&con->border.left->node,
|
||||||
0, border_top);
|
0, border_top);
|
||||||
wlr_scene_node_set_position(&con->border.right->node,
|
wlr_scene_node_set_position(&con->border.right->node,
|
||||||
width - border_right, border_top);
|
horiz_border_width - border_right, border_top);
|
||||||
|
|
||||||
// make sure to reparent, it's possible that the client just came out of
|
// make sure to reparent, it's possible that the client just came out of
|
||||||
// fullscreen mode where the parent of the surface is not the container
|
// fullscreen mode where the parent of the surface is not the container
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,12 @@ static void resize_box(struct wlr_box *box, enum wlr_edges edge,
|
||||||
box->y += thickness;
|
box->y += thickness;
|
||||||
box->width -= thickness * 2;
|
box->width -= thickness * 2;
|
||||||
box->height -= thickness * 2;
|
box->height -= thickness * 2;
|
||||||
|
if (box->width < 0) {
|
||||||
|
box->width = 0;
|
||||||
|
}
|
||||||
|
if (box->height < 0) {
|
||||||
|
box->height = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,6 +159,12 @@ static bool split_titlebar(struct sway_node *node, struct sway_container *avoid,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_indicator(struct seatop_move_tiling_event *e, struct wlr_box *box) {
|
static void update_indicator(struct seatop_move_tiling_event *e, struct wlr_box *box) {
|
||||||
|
if (box->width < 0) {
|
||||||
|
box->width = 0;
|
||||||
|
}
|
||||||
|
if (box->height < 0) {
|
||||||
|
box->height = 0;
|
||||||
|
}
|
||||||
wlr_scene_node_set_position(&e->indicator_rect->node, box->x, box->y);
|
wlr_scene_node_set_position(&e->indicator_rect->node, box->x, box->y);
|
||||||
wlr_scene_rect_set_size(e->indicator_rect, box->width, box->height);
|
wlr_scene_rect_set_size(e->indicator_rect, box->width, box->height);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,15 @@ static void update_rect_list(struct wlr_scene_tree *tree, pixman_region32_t *reg
|
||||||
if (i < len) {
|
if (i < len) {
|
||||||
const pixman_box32_t *box = &rects[i++];
|
const pixman_box32_t *box = &rects[i++];
|
||||||
wlr_scene_node_set_position(&rect->node, box->x1, box->y1);
|
wlr_scene_node_set_position(&rect->node, box->x1, box->y1);
|
||||||
wlr_scene_rect_set_size(rect, box->x2 - box->x1, box->y2 - box->y1);
|
int rect_width = box->x2 - box->x1;
|
||||||
|
int rect_height = box->y2 - box->y1;
|
||||||
|
if (rect_width < 0) {
|
||||||
|
rect_width = 0;
|
||||||
|
}
|
||||||
|
if (rect_height < 0) {
|
||||||
|
rect_height = 0;
|
||||||
|
}
|
||||||
|
wlr_scene_rect_set_size(rect, rect_width, rect_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue