[PATCH] xwayland: Avoid repeatedly looping through window ancestor chain
Roman Gilg
subdiff at gmail.com
Tue Aug 22 13:38:26 UTC 2017
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 at gmail.com>
---
hw/xwayland/xwayland-input.c | 2 +-
hw/xwayland/xwayland.c | 54 ++++++++++++++++++++++++--------------------
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 92e530d..5a905c7 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1068,7 +1068,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 cb929ca..79deead 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 6d3edf3..3adee82 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,
--
2.7.4
More information about the xorg-devel
mailing list