From 5ea838be638e1c1525bdbd7d9e6105c864b6a5af Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Tue, 16 Sep 2025 10:16:19 -0500 Subject: [PATCH] compositor: Fix output reflowing when mirroring is in use When we have a mirror, it will be at the same x,y position as the output it's mirroring. On hot unplug, the current logic results in the mirroring output being moved to the left by the width of its target output. The mirror will then be destroyed, and the views can be left dangling outside of usable space when a hot plug restores the outputs. Subtly change the reflow logic to only reflow outputs to the right of the removed output by testing co-ordinates, instead of assuming that every output in the list is to the right of the previous. Signed-off-by: Derek Foreman (cherry picked from commit 1a9cf3bfb606d27818a00ed94842599942f57b0f) --- libweston/compositor.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index 84c25b6fe..069dff287 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -7286,7 +7286,6 @@ weston_compositor_reflow_outputs(struct weston_compositor *compositor, struct weston_output *resized_output, int delta_width) { struct weston_output *output; - bool start_resizing = false; if (compositor->output_flow_dirty) return; @@ -7295,17 +7294,21 @@ weston_compositor_reflow_outputs(struct weston_compositor *compositor, return; wl_list_for_each(output, &compositor->output_list, link) { - if (output == resized_output) { - start_resizing = true; + struct weston_coord_global pos = output->pos; + + /* Since outputs are in a horizontal line, reflow any to the + * right of the removed output. + * + * There's an easter egg here - with mirrored outputs, there + * may still be an output at the same place as the removed + * output, and we don't want to move its contents, so we use + * <= here. + */ + if (pos.c.x <= resized_output->pos.c.x) continue; - } - if (start_resizing) { - struct weston_coord_global pos = output->pos; - - pos.c.x += delta_width; - weston_output_set_position(output, pos); - } + pos.c.x += delta_width; + weston_output_set_position(output, pos); } }