ext_image_capture_source_v1/scene: fix extents

Currently the width/height of the extents is too small if the first node
visited has position/dimensions 0,0,100,100 and the second node has
position/dimensions -20,-20,10,10.

In this case the current code calculates total extents as
-20,-20,100,100 but the correct extents are -20,-20,120,120.

References: https://codeberg.org/river/river-classic/issues/17
This commit is contained in:
Isaac Freund 2026-03-30 11:45:54 +02:00
parent 334019f839
commit e22084f639
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11

View file

@ -34,13 +34,14 @@ struct scene_node_source_frame_event {
static size_t last_output_num = 0;
static void _get_scene_node_extents(struct wlr_scene_node *node, struct wlr_box *box, int lx, int ly) {
static void _get_scene_node_extents(struct wlr_scene_node *node, int lx, int ly,
int *x_min, int *y_min, int *x_max, int *y_max) {
switch (node->type) {
case WLR_SCENE_NODE_TREE:;
struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node);
struct wlr_scene_node *child;
wl_list_for_each(child, &scene_tree->children, link) {
_get_scene_node_extents(child, box, lx + child->x, ly + child->y);
_get_scene_node_extents(child, lx + child->x, ly + child->y, x_min, y_min, x_max, y_max);
}
break;
case WLR_SCENE_NODE_RECT:
@ -48,27 +49,30 @@ static void _get_scene_node_extents(struct wlr_scene_node *node, struct wlr_box
struct wlr_box node_box = { .x = lx, .y = ly };
scene_node_get_size(node, &node_box.width, &node_box.height);
if (node_box.x < box->x) {
box->x = node_box.x;
if (node_box.x < *x_min) {
*x_min = node_box.x;
}
if (node_box.y < box->y) {
box->y = node_box.y;
if (node_box.y < *y_min) {
*y_min = node_box.y;
}
if (node_box.x + node_box.width > box->x + box->width) {
box->width = node_box.x + node_box.width - box->x;
if (node_box.x + node_box.width > *x_max) {
*x_max = node_box.x + node_box.width;
}
if (node_box.y + node_box.height > box->y + box->height) {
box->height = node_box.y + node_box.height - box->y;
if (node_box.y + node_box.height > *y_max) {
*y_max = node_box.y + node_box.height;
}
break;
}
}
static void get_scene_node_extents(struct wlr_scene_node *node, struct wlr_box *box) {
*box = (struct wlr_box){ .x = INT_MAX, .y = INT_MAX };
int lx = 0, ly = 0;
wlr_scene_node_coords(node, &lx, &ly);
_get_scene_node_extents(node, box, lx, ly);
*box = (struct wlr_box){ .x = INT_MAX, .y = INT_MAX };
int x_max = INT_MIN, y_max = INT_MIN;
_get_scene_node_extents(node, lx, ly, &box->x, &box->y, &x_max, &y_max);
box->width = x_max - box->x;
box->height = y_max - box->y;
}
static void source_render(struct scene_node_source *source) {