xwayland: do not add output into output_list multiple times
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@gmail.com>
This commit is contained in:
parent
95014ad2a7
commit
21f384b7b8
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user