diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 45acf0c97..e295c71a4 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -944,6 +944,34 @@ DDXRingBell(int volume, int pitch, int duration) { } +static WindowPtr +xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y) +{ + struct xwl_seat *xwl_seat = NULL; + DeviceIntPtr device; + WindowPtr ret; + + for (device = inputInfo.devices; device; device = device->next) { + if (device->deviceProc == xwl_pointer_proc && + device->spriteInfo->sprite == sprite) { + xwl_seat = device->public.devicePrivate; + break; + } + } + + if (xwl_seat == NULL || !xwl_seat->focus_window) { + sprite->spriteTraceGood = 1; + return sprite->spriteTrace[0]; + } + + screen->XYToWindow = xwl_seat->xwl_screen->XYToWindow; + ret = screen->XYToWindow(screen, sprite, x, y); + xwl_seat->xwl_screen->XYToWindow = screen->XYToWindow; + screen->XYToWindow = xwl_xy_to_window; + + return ret; +} + void xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr window) { @@ -970,6 +998,9 @@ InitInput(int argc, char *argv[]) wl_registry_add_listener(xwl_screen->input_registry, &input_listener, xwl_screen); + xwl_screen->XYToWindow = pScreen->XYToWindow; + pScreen->XYToWindow = xwl_xy_to_window; + wl_display_roundtrip(xwl_screen->display); while (xwl_screen->expecting_event) wl_display_roundtrip(xwl_screen->display); diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index aead0a8af..b8a58e76a 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -62,6 +62,7 @@ struct xwl_screen { DestroyWindowProcPtr DestroyWindow; RealizeWindowProcPtr RealizeWindow; UnrealizeWindowProcPtr UnrealizeWindow; + XYToWindowProcPtr XYToWindow; struct xorg_list output_list; struct xorg_list seat_list;