[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg-devel
Subject:    [PATCH xwayland 3/3] xwayland: Handle the case of windows being realized before redirection
From:       Carlos Garnacho <carlosg () gnome ! org>
Date:       2019-01-15 22:21:05
Message-ID: 20190115222105.4817-3-carlosg () gnome ! org
[Download RAW message or body]

If Xwayland gets to realize a window meant for composition before the
compositor redirected windows (i.e. redirect mode is not RedirectDrawManual
yet), the window would stay "invisible" as we wouldn't create a
wl_surface/wl_shell_surface for it at any later point.

This scenario may happen if the wayland compositor raises Xwayland on
demand for a X11 client being started. In this case the first data on
the socket is the client's, the compositor can hardly beat that in
order to redirect subwindows before the client realizes a Window.

In order to handle this case, allow the late creation of a matching
(shell) surface for the WindowPtr on SetWindowPixmapProc, so it is ensured
to be created after the compositor set up redirection.

Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
---
 hw/xwayland/xwayland.c | 37 +++++++++++++++++++++++++++++++++++++
 hw/xwayland/xwayland.h |  1 +
 2 files changed, 38 insertions(+)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 279358e07..6f7d64ca8 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -688,6 +688,40 @@ xwl_unrealize_window(WindowPtr window)
     return ret;
 }
 
+static void
+xwl_set_window_pixmap(WindowPtr window,
+                      PixmapPtr pixmap)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->SetWindowPixmap = xwl_screen->SetWindowPixmap;
+    (*screen->SetWindowPixmap) (window, pixmap);
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
+
+    if (!RegionNotEmpty(&window->winSize))
+        return;
+
+    xwl_window = xwl_window_get(window);
+    if (xwl_window)
+        return;
+
+    if (xwl_screen->rootless) {
+        if (window->redirectDraw != RedirectDrawManual)
+            return;
+    }
+    else {
+        if (window->parent)
+            return;
+    }
+
+    create_surface_for_window(window);
+}
+
 static void
 frame_callback(void *data,
                struct wl_callback *callback,
@@ -1147,6 +1181,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = xwl_close_screen;
 
+    xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
+    pScreen->SetWindowPixmap = xwl_set_window_pixmap;
+
     pScreen->CursorWarpedTo = xwl_cursor_warped_to;
     pScreen->CursorConfinedTo = xwl_cursor_confined_to;
 
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 1559b114d..65f12d478 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -130,6 +130,7 @@ struct xwl_screen {
     UnrealizeWindowProcPtr UnrealizeWindow;
     DestroyWindowProcPtr DestroyWindow;
     XYToWindowProcPtr XYToWindow;
+    SetWindowPixmapProcPtr SetWindowPixmap;
 
     struct xorg_list output_list;
     struct xorg_list seat_list;
-- 
2.19.2

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic