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 <ofour...@redhat.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96437
---
 Sending this as an RFC for now.
 See also: https://bugzilla.gnome.org/show_bug.cgi?id=766377

 hw/xwayland/xwayland-input.c | 23 +++++++++++++++++++++++
 hw/xwayland/xwayland.h       |  1 +
 2 files changed, 24 insertions(+)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 0735d43..246defa 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 70a0492..ef8811f 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -63,6 +63,7 @@ struct xwl_screen {
     DestroyWindowProcPtr DestroyWindow;
     RealizeWindowProcPtr RealizeWindow;
     UnrealizeWindowProcPtr UnrealizeWindow;
+    XYToWindowProcPtr XYToWindow;
 
     struct xorg_list output_list;
     struct xorg_list seat_list;
-- 
2.7.4

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to