[PATCH xwayland v2] xwayland: do not add output into output_list multiple times
Marek Chalupa
mchqwerty at gmail.com
Thu May 21 06:43:43 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.
v2. factor out common code into function
move expecting_events into right branch
Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>
---
hw/xwayland/xwayland-output.c | 42 ++++++++++++++++++++++++++++++------------
1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 155cbc1..8949930 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -113,29 +113,47 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
}
+static inline void
+output_get_new_size(struct xwl_output *xwl_output,
+ int *height, int *width)
+{
+ if (*width < xwl_output->x + xwl_output->width)
+ *width = xwl_output->x + xwl_output->width;
+
+ if (*height < xwl_output->y + xwl_output->height)
+ *height = xwl_output->y + xwl_output->height;
+}
+
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_append(&xwl_output->link, &xwl_screen->output_list);
+ 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;
- width = 0;
- height = 0;
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- if (width < xwl_output->x + xwl_output->width)
- width = xwl_output->x + xwl_output->width;
- if (height < xwl_output->y + xwl_output->height)
- height = xwl_output->y + xwl_output->height;
+ output_get_new_size(it, &height, &width);
+ }
+
+ if (!has_this_output) {
+ xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+
+ /* we did not check this output for new screen size, do it now */
+ output_get_new_size(xwl_output, &height, &width);
+
+ --xwl_screen->expecting_event;
}
xwl_screen->width = width;
xwl_screen->height = height;
RRScreenSizeNotify(xwl_screen->screen);
-
- xwl_screen->expecting_event--;
}
static void
--
2.1.0
More information about the xorg-devel
mailing list