From f568968f8a30eab6bfd8a15518014deb8f6c81d5 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Fri, 8 Nov 2019 18:31:13 +0100 Subject: [PATCH] xwm: Use Xwayland allow commits for repaint Initially, `_XWAYLAND_ALLOW_COMMITS` was introduced in commit 7ace831ca to avoid drawing the window content before it's ready to be shown. But a repaint might also be triggered by the client damages before the XWM has finished drawing its window decorations and drop shadows, which previously was not too much of an issue since the XWM could still finish updating the X11 window after the buffer was submitted. However, with the addition of multiple window buffers in Xwayland [1] which are aimed at preventing the X11 clients from updating the buffer after it's been committed, this is no longer possible. As a result, the use of multiple window buffers in Xwayland can cause ugly repainting effects of the decorations if the buffer is submitted before the XWM has finished painting its decorations. Use the X11 property `_XWAYLAND_ALLOW_COMMITS` can be used to avoid this, by controlling when Xwayland should commit changes to the Wayland surface. [1] https://gitlab.freedesktop.org/xorg/xserver/merge_requests/316 Signed-off-by: Olivier Fourdan --- xwayland/window-manager.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 66e32dc6..49dbbddd 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -175,6 +175,9 @@ struct weston_wm_window { struct wl_list link; }; +static void +weston_wm_window_set_allow_commits(struct weston_wm_window *window, bool allow); + static struct weston_wm_window * get_wm_window(struct weston_surface *surface); @@ -739,8 +742,10 @@ weston_wm_handle_configure_request(struct weston_wm *wm, xcb_generic_event_t *ev if (configure_request->value_mask & XCB_CONFIG_WINDOW_HEIGHT) window->height = configure_request->height; - if (window->frame) + if (window->frame) { + weston_wm_window_set_allow_commits(window, false); frame_resize_inside(window->frame, window->width, window->height); + } weston_wm_window_get_child_position(window, &x, &y); values[i++] = x; @@ -958,6 +963,7 @@ weston_wm_window_set_allow_commits(struct weston_wm_window *window, bool allow) XCB_ATOM_CARDINAL, 32, /* format */ 1, property); + xcb_flush(wm->conn); } #define ICCCM_WITHDRAWN_STATE 0 @@ -1306,10 +1312,12 @@ weston_wm_window_do_repaint(void *data) window->repaint_source = NULL; + weston_wm_window_set_allow_commits(window, false); weston_wm_window_read_properties(window); weston_wm_window_draw_decoration(window); weston_wm_window_set_pending_state(window); + weston_wm_window_set_allow_commits(window, true); } static void @@ -2630,6 +2638,8 @@ weston_wm_window_configure(void *data) uint32_t values[4]; int x, y, width, height; + weston_wm_window_set_allow_commits(window, false); + weston_wm_window_get_child_position(window, &x, &y); values[0] = x; values[1] = y;