diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 74f27d345..91de40c2d 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -638,6 +638,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) xwl_screen->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = xwl_close_screen; + xwl_screen->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; + pScreen->ChangeWindowAttributes = xwl_change_window_attributes; + 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 264c6b515..fb87ddb30 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -48,6 +48,7 @@ struct xwl_screen { int height; int depth; ScreenPtr screen; + int wm_client_id; int expecting_event; enum RootClipMode root_clip_mode; @@ -62,6 +63,7 @@ struct xwl_screen { DestroyWindowProcPtr DestroyWindow; XYToWindowProcPtr XYToWindow; SetWindowPixmapProcPtr SetWindowPixmap; + ChangeWindowAttributesProcPtr ChangeWindowAttributes; ResizeWindowProcPtr ResizeWindow; struct xorg_list output_list; diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index dc12b8e21..89106d0a3 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -243,20 +243,11 @@ xwl_window_enable_viewport(struct xwl_window *xwl_window, } static Bool -xwl_screen_client_is_window_manager(struct xwl_screen *xwl_screen, - ClientPtr client) +window_is_wm_window(WindowPtr window) { - WindowPtr root = xwl_screen->screen->root; - OtherClients *others; + struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen); - for (others = wOtherClients(root); others; others = others->next) { - if (SameClient(others, client)) { - if (others->mask & (SubstructureRedirectMask | ResizeRedirectMask)) - return TRUE; - } - } - - return FALSE; + return CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id; } static ClientPtr @@ -270,7 +261,7 @@ xwl_window_get_owner(struct xwl_window *xwl_window) * decoration window. In that case return the client of the * first *and only* child of the toplevel (decoration) window. */ - if (xwl_screen_client_is_window_manager(xwl_window->xwl_screen, client)) { + if (window_is_wm_window(window)) { if (window->firstChild && window->firstChild == window->lastChild) return wClient(window->firstChild); else @@ -356,9 +347,7 @@ xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window) Bool xwl_window_is_toplevel(WindowPtr window) { - struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen); - - if (xwl_screen_client_is_window_manager(xwl_screen, wClient(window))) + if (window_is_wm_window(window)) return FALSE; /* CSD and override-redirect toplevel windows */ @@ -660,6 +649,30 @@ xwl_window_set_window_pixmap(WindowPtr window, xwl_window_buffers_recycle(xwl_window); } +Bool +xwl_change_window_attributes(WindowPtr window, unsigned long mask) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + OtherClients *others; + Bool ret; + + screen->ChangeWindowAttributes = xwl_screen->ChangeWindowAttributes; + ret = (*screen->ChangeWindowAttributes) (window, mask); + xwl_screen->ChangeWindowAttributes = screen->ChangeWindowAttributes; + screen->ChangeWindowAttributes = xwl_change_window_attributes; + + if (window != screen->root || !(mask & CWEventMask)) + return ret; + + for (others = wOtherClients(window); others; others = others->next) { + if (others->mask & (SubstructureRedirectMask | ResizeRedirectMask)) + xwl_screen->wm_client_id = CLIENT_ID(others->resource); + } + + return ret; +} + void xwl_resize_window(WindowPtr window, int x, int y, diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h index 873e191f2..526e08fb7 100644 --- a/hw/xwayland/xwayland-window.h +++ b/hw/xwayland/xwayland-window.h @@ -69,6 +69,7 @@ void xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window) void xwl_window_set_window_pixmap(WindowPtr window, PixmapPtr pixmap); Bool xwl_realize_window(WindowPtr window); Bool xwl_unrealize_window(WindowPtr window); +Bool xwl_change_window_attributes(WindowPtr window, unsigned long mask); void xwl_resize_window(WindowPtr window, int x, int y, unsigned int width, unsigned int height,