diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 59554b734..22c500801 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -1152,6 +1152,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) xwl_screen->ConfigNotify = pScreen->ConfigNotify; pScreen->ConfigNotify = xwl_config_notify; + xwl_screen->ReparentWindow = pScreen->ReparentWindow; + pScreen->ReparentWindow = xwl_reparent_window; + xwl_screen->ResizeWindow = pScreen->ResizeWindow; pScreen->ResizeWindow = xwl_resize_window; diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index 49a167a12..ffbaa09e7 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -78,6 +78,7 @@ struct xwl_screen { XYToWindowProcPtr XYToWindow; SetWindowPixmapProcPtr SetWindowPixmap; ChangeWindowAttributesProcPtr ChangeWindowAttributes; + ReparentWindowProcPtr ReparentWindow; ResizeWindowProcPtr ResizeWindow; MoveWindowProcPtr MoveWindow; SourceValidateProcPtr SourceValidate; diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index 55c7ba6e2..c69b24fc5 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -68,6 +68,7 @@ #define FRACTIONAL_SCALE_DENOMINATOR 120 static DevPrivateKeyRec xwl_window_private_key; +static DevPrivateKeyRec xwl_wm_window_private_key; static DevPrivateKeyRec xwl_damage_private_key; static const char *xwl_surface_tag = "xwl-surface"; @@ -474,8 +475,13 @@ static Bool window_is_wm_window(WindowPtr window) { struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen); + Bool *is_wm_window; - return CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id; + if (CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id) + return TRUE; + + is_wm_window = dixLookupPrivate(&window->devPrivates, &xwl_wm_window_private_key); + return *is_wm_window; } static WindowPtr @@ -1844,6 +1850,31 @@ xwl_config_notify(WindowPtr window, return ret; } +void +xwl_reparent_window(WindowPtr window, WindowPtr prior_parent) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + WindowPtr parent = window->parent; + Bool *is_wm_window; + + if (xwl_screen->ReparentWindow) { + screen->ReparentWindow = xwl_screen->ReparentWindow; + screen->ReparentWindow(window, prior_parent); + xwl_screen->ReparentWindow = screen->ReparentWindow; + screen->ReparentWindow = xwl_reparent_window; + } + + if (!parent->parent || + GetCurrentClient()->index != xwl_screen->wm_client_id) + return; + + /* If the WM client reparents a window, mark the new parent as a WM window */ + is_wm_window = dixLookupPrivate(&parent->devPrivates, + &xwl_wm_window_private_key); + *is_wm_window = TRUE; +} + void xwl_resize_window(WindowPtr window, int x, int y, @@ -2068,6 +2099,10 @@ xwl_window_init(void) if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) return FALSE; + if (!dixRegisterPrivateKey(&xwl_wm_window_private_key, PRIVATE_WINDOW, + sizeof(Bool))) + return FALSE; + if (!dixRegisterPrivateKey(&xwl_damage_private_key, PRIVATE_WINDOW, 0)) return FALSE; diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h index ba5c3a078..ae3e531c6 100644 --- a/hw/xwayland/xwayland-window.h +++ b/hw/xwayland/xwayland-window.h @@ -138,6 +138,7 @@ int xwl_config_notify(WindowPtr window, int x, int y, int width, int height, int bw, WindowPtr sib); +void xwl_reparent_window(WindowPtr window, WindowPtr prior_parent); void xwl_resize_window(WindowPtr window, int x, int y, unsigned int width, unsigned int height,