[PATCH xserver 2/2] xwayland: update Xwayland present window on reparent

Olivier Fourdan ofourdan at redhat.com
Thu Sep 27 15:31:06 UTC 2018


When reparenting a window, the Xwayland present window either on the
prior parent or on the new parent may need to be updated:

1. If the window is flipping, clear the present window on its old
   parent.
2. If the new parent has no flipping already, set its flipping window to
   the reparented window.

Install new ReparentWindow hooks in Xwayland to handle those cases.

Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
---
 hw/xwayland/xwayland-present.c | 16 ++++++++++++++++
 hw/xwayland/xwayland.c         | 23 +++++++++++++++++++++++
 hw/xwayland/xwayland.h         |  2 ++
 3 files changed, 41 insertions(+)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 316e04443..f54fe2ac4 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -558,3 +558,19 @@ xwl_present_init(ScreenPtr screen)
 
     return present_wnmd_screen_init(screen, &xwl_present_info);
 }
+
+void
+xwl_present_reparent_window(WindowPtr pWin, WindowPtr pPriorParent)
+{
+    struct xwl_window *xwl_window;
+
+    /* If the window is flipping, clear the present window on its old parent */
+    xwl_window = xwl_window_from_window(pPriorParent);
+    if (xwl_present_is_flipping(pWin, xwl_window))
+        xwl_window->present_window = NULL;
+
+    /* If the new parent window has no child flipping, update its present_window */
+    xwl_window = xwl_window_from_window(pWin->parent);
+    if (xwl_window && xwl_window->present_window == NULL)
+        xwl_window->present_window = pWin;
+}
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 96b4db18c..345b62f59 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -660,6 +660,26 @@ xwl_destroy_window(WindowPtr window)
     return ret;
 }
 
+static void
+xwl_reparent_window(WindowPtr pWin, WindowPtr pPriorParent)
+{
+    ScreenPtr screen = pWin->drawable.pScreen;
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_screen->present)
+        xwl_present_reparent_window(pWin, pPriorParent);
+#endif
+
+    /* Chain up with previous ReparentWindow, if any */
+    if (xwl_screen->ReparentWindow) {
+        screen->ReparentWindow = xwl_screen->ReparentWindow;
+        (*screen->ReparentWindow) (pWin, pPriorParent);
+        xwl_screen->ReparentWindow = screen->ReparentWindow;
+        screen->ReparentWindow = xwl_reparent_window;
+    }
+}
+
 static void
 xwl_window_post_damage(struct xwl_window *xwl_window)
 {
@@ -1109,6 +1129,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = xwl_close_screen;
 
+    xwl_screen->ReparentWindow = pScreen->ReparentWindow;
+    pScreen->ReparentWindow = xwl_reparent_window;
+
     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 67819e178..a7c7f2aee 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -132,6 +132,7 @@ struct xwl_screen {
     RealizeWindowProcPtr RealizeWindow;
     UnrealizeWindowProcPtr UnrealizeWindow;
     DestroyWindowProcPtr DestroyWindow;
+    ReparentWindowProcPtr ReparentWindow;
     XYToWindowProcPtr XYToWindow;
 
     struct xorg_list output_list;
@@ -451,6 +452,7 @@ void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
 #ifdef GLAMOR_HAS_GBM
 Bool xwl_present_init(ScreenPtr screen);
 void xwl_present_cleanup(WindowPtr window);
+void xwl_present_reparent_window(WindowPtr pWin, WindowPtr pPriorParent);
 #endif /* GLAMOR_HAS_GBM */
 
 #ifdef XV
-- 
2.19.0



More information about the xorg-devel mailing list