xwayland: Cache client-id for the window-manager client

Instead of iterating over all clients which are listening for events on the
root window and checking if the client we are dealing with is the one
listening for SubstructureRedirectMask | ResizeRedirectMask events and thus
is the window-manager, cache the client-id of the window-manager in
xwl_screen and use that when checking if a client is the window-manager.

Note that we cache and compare the client-id rather then the ClienPtr,
this saves reading the ClientPtr from the global clients array when doing
the comparison.

Suggested-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Hans de Goede 2020-01-27 11:08:00 +01:00
parent 1e44861aba
commit ded89300c1
4 changed files with 35 additions and 16 deletions

View File

@ -638,6 +638,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
xwl_screen->CloseScreen = pScreen->CloseScreen; xwl_screen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = xwl_close_screen; pScreen->CloseScreen = xwl_close_screen;
xwl_screen->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
pScreen->ChangeWindowAttributes = xwl_change_window_attributes;
xwl_screen->ResizeWindow = pScreen->ResizeWindow; xwl_screen->ResizeWindow = pScreen->ResizeWindow;
pScreen->ResizeWindow = xwl_resize_window; pScreen->ResizeWindow = xwl_resize_window;

View File

@ -48,6 +48,7 @@ struct xwl_screen {
int height; int height;
int depth; int depth;
ScreenPtr screen; ScreenPtr screen;
int wm_client_id;
int expecting_event; int expecting_event;
enum RootClipMode root_clip_mode; enum RootClipMode root_clip_mode;
@ -62,6 +63,7 @@ struct xwl_screen {
DestroyWindowProcPtr DestroyWindow; DestroyWindowProcPtr DestroyWindow;
XYToWindowProcPtr XYToWindow; XYToWindowProcPtr XYToWindow;
SetWindowPixmapProcPtr SetWindowPixmap; SetWindowPixmapProcPtr SetWindowPixmap;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ResizeWindowProcPtr ResizeWindow; ResizeWindowProcPtr ResizeWindow;
struct xorg_list output_list; struct xorg_list output_list;

View File

@ -243,20 +243,11 @@ xwl_window_enable_viewport(struct xwl_window *xwl_window,
} }
static Bool static Bool
xwl_screen_client_is_window_manager(struct xwl_screen *xwl_screen, window_is_wm_window(WindowPtr window)
ClientPtr client)
{ {
WindowPtr root = xwl_screen->screen->root; struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
OtherClients *others;
for (others = wOtherClients(root); others; others = others->next) { return CLIENT_ID(window->drawable.id) == xwl_screen->wm_client_id;
if (SameClient(others, client)) {
if (others->mask & (SubstructureRedirectMask | ResizeRedirectMask))
return TRUE;
}
}
return FALSE;
} }
static ClientPtr 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 * decoration window. In that case return the client of the
* first *and only* child of the toplevel (decoration) window. * 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) if (window->firstChild && window->firstChild == window->lastChild)
return wClient(window->firstChild); return wClient(window->firstChild);
else else
@ -356,9 +347,7 @@ xwl_window_check_resolution_change_emulation(struct xwl_window *xwl_window)
Bool Bool
xwl_window_is_toplevel(WindowPtr window) xwl_window_is_toplevel(WindowPtr window)
{ {
struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen); if (window_is_wm_window(window))
if (xwl_screen_client_is_window_manager(xwl_screen, wClient(window)))
return FALSE; return FALSE;
/* CSD and override-redirect toplevel windows */ /* CSD and override-redirect toplevel windows */
@ -660,6 +649,30 @@ xwl_window_set_window_pixmap(WindowPtr window,
xwl_window_buffers_recycle(xwl_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 void
xwl_resize_window(WindowPtr window, xwl_resize_window(WindowPtr window,
int x, int y, int x, int y,

View File

@ -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); void xwl_window_set_window_pixmap(WindowPtr window, PixmapPtr pixmap);
Bool xwl_realize_window(WindowPtr window); Bool xwl_realize_window(WindowPtr window);
Bool xwl_unrealize_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, void xwl_resize_window(WindowPtr window,
int x, int y, int x, int y,
unsigned int width, unsigned int height, unsigned int width, unsigned int height,