diff options
Diffstat (limited to 'xorg-server/hw/xwayland')
-rw-r--r-- | xorg-server/hw/xwayland/Makefile.am | 4 | ||||
-rw-r--r-- | xorg-server/hw/xwayland/xwayland-input.c | 9 | ||||
-rw-r--r-- | xorg-server/hw/xwayland/xwayland.c | 48 | ||||
-rw-r--r-- | xorg-server/hw/xwayland/xwayland.h | 1 |
4 files changed, 46 insertions, 16 deletions
diff --git a/xorg-server/hw/xwayland/Makefile.am b/xorg-server/hw/xwayland/Makefile.am index dc16b8bbe..4e0e1bb00 100644 --- a/xorg-server/hw/xwayland/Makefile.am +++ b/xorg-server/hw/xwayland/Makefile.am @@ -39,8 +39,6 @@ nodist_Xwayland_SOURCES = \ CLEANFILES = $(nodist_Xwayland_SOURCES) -EXTRA_DIST = drm.xml - xwayland-glamor.c : $(nodist_Xwayland_SOURCES) glamor_lib = $(top_builddir)/glamor/libglamor.la @@ -48,6 +46,8 @@ glamor_lib = $(top_builddir)/glamor/libglamor.la Xwayland_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) -lEGL -lGL endif +EXTRA_DIST = drm.xml + relink: $(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT) diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c index cc5f7df05..b8c543ce4 100644 --- a/xorg-server/hw/xwayland/xwayland-input.c +++ b/xorg-server/hw/xwayland/xwayland-input.c @@ -152,6 +152,15 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, ScreenPtr pScreen = xwl_seat->xwl_screen->screen; ValuatorMask mask; + /* There's a race here where if we create and then immediately + * destroy a surface, we might end up in a state where the Wayland + * compositor sends us an event for a surface that doesn't exist. + * + * Don't process enter events in this case. + */ + if (surface == NULL) + return; + xwl_seat->xwl_screen->serial = serial; xwl_seat->pointer_enter_serial = serial; diff --git a/xorg-server/hw/xwayland/xwayland.c b/xorg-server/hw/xwayland/xwayland.c index 17b7bf7fd..913296947 100644 --- a/xorg-server/hw/xwayland/xwayland.c +++ b/xorg-server/hw/xwayland/xwayland.c @@ -308,6 +308,9 @@ xwl_unrealize_window(WindowPtr window) xorg_list_del(&xwl_window->link_damage); DamageUnregister(xwl_window->damage); DamageDestroy(xwl_window->damage); + if (xwl_window->frame_callback) + wl_callback_destroy(xwl_window->frame_callback); + free(xwl_window); dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); @@ -321,20 +324,35 @@ xwl_save_screen(ScreenPtr pScreen, int on) } static void +frame_callback(void *data, + struct wl_callback *callback, + uint32_t time) +{ + struct xwl_window *xwl_window = data; + xwl_window->frame_callback = NULL; +} + +static const struct wl_callback_listener frame_listener = { + frame_callback +}; + +static void xwl_screen_post_damage(struct xwl_screen *xwl_screen) { - struct xwl_window *xwl_window; + struct xwl_window *xwl_window, *next_xwl_window; RegionPtr region; BoxPtr box; - int count, i; struct wl_buffer *buffer; PixmapPtr pixmap; - xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list, - link_damage) { - region = DamageRegion(xwl_window->damage); - count = RegionNumRects(region); + xorg_list_for_each_entry_safe(xwl_window, next_xwl_window, + &xwl_screen->damage_window_list, link_damage) { + /* If we're waiting on a frame callback from the server, + * don't attach a new buffer. */ + if (xwl_window->frame_callback) + continue; + region = DamageRegion(xwl_window->damage); pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window); #if GLAMOR_HAS_GBM @@ -345,17 +363,19 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) buffer = xwl_shm_pixmap_get_wl_buffer(pixmap); wl_surface_attach(xwl_window->surface, buffer, 0, 0); - for (i = 0; i < count; i++) { - box = &RegionRects(region)[i]; - wl_surface_damage(xwl_window->surface, - box->x1, box->y1, - box->x2 - box->x1, box->y2 - box->y1); - } + + box = RegionExtents(region); + wl_surface_damage(xwl_window->surface, box->x1, box->y1, + box->x2 - box->x1, box->y2 - box->y1); + + xwl_window->frame_callback = wl_surface_frame(xwl_window->surface); + wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window); + wl_surface_commit(xwl_window->surface); DamageEmpty(xwl_window->damage); - } - xorg_list_init(&xwl_screen->damage_window_list); + xorg_list_del(&xwl_window->link_damage); + } } static void diff --git a/xorg-server/hw/xwayland/xwayland.h b/xorg-server/hw/xwayland/xwayland.h index 60b0c2964..bfffa712f 100644 --- a/xorg-server/hw/xwayland/xwayland.h +++ b/xorg-server/hw/xwayland/xwayland.h @@ -102,6 +102,7 @@ struct xwl_window { WindowPtr window; DamagePtr damage; struct xorg_list link_damage; + struct wl_callback *frame_callback; }; #define MODIFIER_META 0x01 |