diff options
author | Roman Gilg <subdiff@gmail.com> | 2017-08-22 15:38:26 +0200 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2017-09-13 11:51:10 -0400 |
commit | 82df2ce38c560915f8c6574052bd56215b649072 (patch) | |
tree | 2a7ac74a2c42366ebeae5757be78314806e33736 | |
parent | 1089d5d518a315963a8cda6c7d47a0ce09de0979 (diff) |
xwayland: Avoid repeatedly looping through window ancestor chain
Calling xwl_window_from_window means looping through the window ancestor
chain whenever it is called on a child window or on an automatically
redirected window.
Since these properties and the potential ancestor's xwl_window are constant
between window realization and unrealization, we can omit the looping by
always putting the respective xwl_window in the Window's private field on
its realization. If the Window doesn't feature an xwl_window on its own,
it's the xwl_window of its first ancestor with one.
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-rw-r--r-- | hw/xwayland/xwayland-input.c | 2 | ||||
-rw-r--r-- | hw/xwayland/xwayland.c | 54 | ||||
-rw-r--r-- | hw/xwayland/xwayland.h | 2 |
3 files changed, 31 insertions, 27 deletions
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index d45bee410..68e365051 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -1067,7 +1067,7 @@ xwl_keyboard_activate_grab(DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bo if (xwl_seat == NULL) xwl_seat = find_matching_seat(device); if (xwl_seat) - set_grab(xwl_seat, xwl_window_from_window(grab->window)); + set_grab(xwl_seat, xwl_window_of_top(grab->window)); } ActivateKeyboardGrab(device, grab, time, passive); diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index cb929cad5..79deead8d 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -105,12 +105,23 @@ static DevPrivateKeyRec xwl_window_private_key; static DevPrivateKeyRec xwl_screen_private_key; static DevPrivateKeyRec xwl_pixmap_private_key; -static struct xwl_window * -xwl_window_get(WindowPtr window) +struct xwl_window * +xwl_window_of_top(WindowPtr window) { return dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); } +static struct xwl_window * +xwl_window_of_self(WindowPtr window) +{ + struct xwl_window *xwl_window = dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + + if (xwl_window && xwl_window->window == window) + return xwl_window; + else + return NULL; +} + struct xwl_screen * xwl_screen_get(ScreenPtr screen) { @@ -195,7 +206,7 @@ xwl_property_callback(CallbackListPtr *pcbl, void *closure, if (rec->win->drawable.pScreen != screen) return; - xwl_window = xwl_window_get(rec->win); + xwl_window = xwl_window_of_self(rec->win); if (!xwl_window) return; @@ -234,22 +245,6 @@ xwl_close_screen(ScreenPtr screen) return screen->CloseScreen(screen); } -struct xwl_window * -xwl_window_from_window(WindowPtr window) -{ - struct xwl_window *xwl_window; - - while (window) { - xwl_window = xwl_window_get(window); - if (xwl_window) - return xwl_window; - - window = window->parent; - } - - return NULL; -} - static struct xwl_seat * xwl_screen_get_default_seat(struct xwl_screen *xwl_screen) { @@ -274,7 +269,7 @@ xwl_cursor_warped_to(DeviceIntPtr device, if (!xwl_seat) xwl_seat = xwl_screen_get_default_seat(xwl_screen); - xwl_window = xwl_window_from_window(window); + xwl_window = xwl_window_of_top(window); if (!xwl_window && xwl_seat->focus_window) { focus = xwl_seat->focus_window->window; @@ -317,7 +312,7 @@ xwl_cursor_confined_to(DeviceIntPtr device, return; } - xwl_window = xwl_window_from_window(window); + xwl_window = xwl_window_of_top(window); if (!xwl_window && xwl_seat->focus_window) { /* Allow confining on InputOnly windows, but only if the geometry * is the same than the focus window. @@ -433,6 +428,7 @@ xwl_realize_window(WindowPtr window) struct xwl_screen *xwl_screen; struct xwl_window *xwl_window; struct wl_region *region; + Bool create_xwl_window = TRUE; Bool ret; xwl_screen = xwl_screen_get(screen); @@ -452,11 +448,17 @@ xwl_realize_window(WindowPtr window) if (xwl_screen->rootless) { if (window->redirectDraw != RedirectDrawManual) - return ret; + create_xwl_window = FALSE; } else { if (window->parent) - return ret; + create_xwl_window = FALSE; + } + + if (!create_xwl_window) { + if (window->parent) + dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window_of_top(window->parent)); + return ret; } xwl_window = calloc(1, sizeof *xwl_window); @@ -560,9 +562,11 @@ xwl_unrealize_window(WindowPtr window) xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; screen->UnrealizeWindow = xwl_unrealize_window; - xwl_window = xwl_window_get(window); - if (!xwl_window) + xwl_window = xwl_window_of_self(window); + if (!xwl_window) { + dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); return ret; + } wl_surface_destroy(xwl_window->surface); if (RegionNotEmpty(DamageRegion(xwl_window->damage))) diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 6d3edf33b..3adee82fa 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -309,7 +309,7 @@ RRModePtr xwayland_cvt(int HDisplay, int VDisplay, void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap); struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap); -struct xwl_window *xwl_window_from_window(WindowPtr window); +struct xwl_window *xwl_window_of_top(WindowPtr window); Bool xwl_shm_create_screen_resources(ScreenPtr screen); PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height, |