diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 17b7bf7fd..e0ae2a957 100644 --- a/hw/xwayland/xwayland.c +++ b/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); @@ -320,18 +323,36 @@ xwl_save_screen(ScreenPtr pScreen, int on) return TRUE; } +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) { + 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); count = RegionNumRects(region); @@ -351,11 +372,15 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen) 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/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 60b0c2964..bfffa712f 100644 --- a/hw/xwayland/xwayland.h +++ b/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