[PATCH xwayland] xwayland: do not add output into output_list multiple times

Marek Chalupa mchqwerty at gmail.com
Thu May 14 02:58:10 PDT 2015


output.done event can be sent even on some property change, not only
when announcing the output. Therefore we must check if we already have it
otherwise we may corrupt the list by adding it multiple times.

This fixes bug when xwayland looped indefinitely in output.done handler
and that can be reproduced following these steps (under X without
multi-monitor setup):
 1) run weston --output-count=2
 2) run xterm, move it so that half is on one output
    and half on the other
 3) close second output, try run weston-terminal

weston sends updated outputs which trigger this bug.

Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>
---
 hw/xwayland/xwayland-output.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 155cbc1..0c96e87 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -116,15 +116,28 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
 static void
 output_handle_done(void *data, struct wl_output *wl_output)
 {
-    struct xwl_output *xwl_output = data;
+    struct xwl_output *it, *xwl_output = data;
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-    int width, height;
+    int width = 0, height = 0, has_this_output = 0;
+
+    xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
+        /* output done event is sent even when some property
+         * of output is changed. That means that we may already
+         * have this output. If it is true, we must not add it
+         * into the output_list otherwise we'll corrupt it */
+        if (it == xwl_output)
+            has_this_output = 1;
+
+        if (width < it->x + it->width)
+            width = it->x + it->width;
+        if (height < it->y + it->height)
+            height = it->y + it->height;
+    }
 
-    xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+    if (!has_this_output) {
+        xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
 
-    width = 0;
-    height = 0;
-    xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
+        /* we did not check this output for new screen size, do it now */
         if (width < xwl_output->x + xwl_output->width)
             width = xwl_output->x + xwl_output->width;
         if (height < xwl_output->y + xwl_output->height)
-- 
2.1.0



More information about the xorg-devel mailing list