xwayland-input: Fake crossing to rootwin

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.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96437

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Daniel Stone <daniels@collabora.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Olivier Fourdan 2016-06-21 13:54:35 +02:00 committed by Peter Hutterer
parent 111a045dcf
commit 7397a2191f
2 changed files with 32 additions and 0 deletions

View File

@ -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);

View File

@ -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;