From b145cc3c37423f4309654d5a0528b4e49efd7d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 8 Apr 2019 19:02:01 +0200 Subject: [PATCH] xwayland/rootless: Always paint background for toplevel windows If a toplevel window has no background, temporarily use the root window's background for it in PaintWindow. This avoids presenting uninitialized window contents, which should fix issue #636. --- hw/xwayland/xwayland.c | 38 ++++++++++++++++++++++++++++++++++++++ hw/xwayland/xwayland.h | 1 + 2 files changed, 39 insertions(+) diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 739f86cf1..3e4e80dac 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -485,6 +485,39 @@ send_surface_id_event(struct xwl_window *xwl_window) &e, 1, SubstructureRedirectMask, NullGrab); } +static void +xwl_paint_window(WindowPtr window, RegionPtr region, int what) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + WindowPtr bg_window = NULL; + + if (what == PW_BACKGROUND) { + struct xwl_window *xwl_window; + + bg_window = window; + while (bg_window->backgroundState == ParentRelative) + bg_window = bg_window->parent; + + /* If a toplevel window has background None, temporarily set it to + * ParentRelative, so the root window's background will be used + */ + xwl_window = xwl_window_get(bg_window); + if (xwl_window && bg_window->backgroundState == None) + bg_window->backgroundState = ParentRelative; + else + bg_window = NULL; + } + + screen->PaintWindow = xwl_screen->PaintWindow; + (*screen->PaintWindow) (window, region, what); + xwl_screen->PaintWindow = screen->PaintWindow; + screen->PaintWindow = xwl_paint_window; + + if (bg_window) + bg_window->backgroundState = None; +} + static Bool xwl_realize_window(WindowPtr window) { @@ -1092,6 +1125,11 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) pScreen->DestroyPixmap = xwl_shm_destroy_pixmap; } + if (xwl_screen->rootless) { + xwl_screen->PaintWindow = pScreen->PaintWindow; + pScreen->PaintWindow = xwl_paint_window; + } + xwl_screen->RealizeWindow = pScreen->RealizeWindow; pScreen->RealizeWindow = xwl_realize_window; diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 92664e812..73fc5b2e4 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -126,6 +126,7 @@ struct xwl_screen { CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; + PaintWindowProcPtr PaintWindow; RealizeWindowProcPtr RealizeWindow; UnrealizeWindowProcPtr UnrealizeWindow; DestroyWindowProcPtr DestroyWindow; -- GitLab