summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2016-06-08 13:37:40 +0200
committerOlivier Fourdan <ofourdan@redhat.com>2016-06-09 16:35:14 +0200
commitc30267f9cae1c3d80e74a79adb3e10b0e1c61121 (patch)
treed52c651b775a37d33fbeb03beb5451b791695ed8
parent615954333a11b8847bd3267c01bfa4c0bc9e3a0e (diff)
xwayland-input: Fake crossing to rootwinxwayland-test
This partially reverts commit c1565f3. When the pointer moves from an X11 window to a Wayland native window, no LeaveNotify event is emitted which can lead to various unexpected behaviors like tooltips remaining visible after the pointer has left the window. Yet the pointer_handle_leave() is called and so is the DIX CheckMotion() but since the pointer enters a Wayland native window with no other Xwayland window matching, DoEnterLeaveEvents() does not get invoked and therefore no LeaveNotify event is sent to the X11 client at the time the pointer leaves the window for a Wayland native surface. Restore the XYToWindow() handler in xwayland-input that was previously removed with commit c1565f3 and use that handler to pretend that the pointer entered the root window in this case so that the LeaveNotify event is emitted. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96437
-rw-r--r--hw/xwayland/xwayland-input.c23
-rw-r--r--hw/xwayland/xwayland.h1
2 files changed, 24 insertions, 0 deletions
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 0735d43c7..246defaf3 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -944,6 +944,26 @@ 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;
+
+ 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)
+ return sprite->spriteTrace[0];
+
+ return (*xwl_seat->xwl_screen->XYToWindow)(screen, sprite, x, y);
+}
+
void
xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr window)
{
@@ -970,6 +990,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;