[PATCH xwayland v2] xwayland: do not add output into output_list multiple times
Marek Chalupa
mchqwerty at gmail.com
Wed Jul 15 03:22:33 PDT 2015
On 05/21/2015 03:43 PM, Marek Chalupa wrote:
> 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
>
ping
More information about the xorg-devel
mailing list