compositor: recompute output position on mode switch
When an output permanently changes its resolution, the output on the right
should be moved accordingly. We also add an event for output resizing so that
plugins can react when an output is resized.
Signed-off-by: David Fort <contact@hardening-consulting.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
diff --git a/src/compositor.c b/src/compositor.c
index 44126dd..c6feae2 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -143,6 +143,11 @@
}
}
+
+static void
+weston_compositor_reflow_outputs(struct weston_compositor *compositor,
+ struct weston_output *resized_output, int delta_width);
+
WL_EXPORT int
weston_output_mode_set_native(struct weston_output *output,
struct weston_mode *mode,
@@ -150,6 +155,7 @@
{
int ret;
int mode_changed = 0, scale_changed = 0;
+ int32_t old_width;
if (!output->switch_mode)
return -1;
@@ -165,11 +171,17 @@
}
}
+ old_width = output->width;
output->native_mode = mode;
output->native_scale = scale;
weston_mode_switch_finish(output, mode_changed, scale_changed);
+ if (mode_changed || scale_changed) {
+ weston_compositor_reflow_outputs(output->compositor, output, output->width - old_width);
+
+ wl_signal_emit(&output->compositor->output_resized_signal, output);
+ }
return 0;
}
@@ -3918,23 +3930,25 @@
wl_output_send_done(resource);
}
-/* Move other outputs when one is removed so the space remains contiguos. */
+/* Move other outputs when one is resized so the space remains contiguous. */
static void
-weston_compositor_remove_output(struct weston_compositor *compositor,
- struct weston_output *remove_output)
+weston_compositor_reflow_outputs(struct weston_compositor *compositor,
+ struct weston_output *resized_output, int delta_width)
{
struct weston_output *output;
- int offset = 0;
+ bool start_resizing = false;
+
+ if (!delta_width)
+ return;
wl_list_for_each(output, &compositor->output_list, link) {
- if (output == remove_output) {
- offset = output->width;
+ if (output == resized_output) {
+ start_resizing = true;
continue;
}
- if (offset > 0) {
- weston_output_move(output,
- output->x - offset, output->y);
+ if (start_resizing) {
+ weston_output_move(output, output->x + delta_width, output->y);
output->dirty = 1;
}
}
@@ -3957,7 +3971,7 @@
weston_presentation_feedback_discard_list(&output->feedback_list);
- weston_compositor_remove_output(output->compositor, output);
+ weston_compositor_reflow_outputs(output->compositor, output, output->width);
wl_list_remove(&output->link);
wl_signal_emit(&output->compositor->output_destroyed_signal, output);
@@ -4560,6 +4574,7 @@
wl_signal_init(&ec->output_created_signal);
wl_signal_init(&ec->output_destroyed_signal);
wl_signal_init(&ec->output_moved_signal);
+ wl_signal_init(&ec->output_resized_signal);
wl_signal_init(&ec->session_signal);
ec->session_active = 1;