[PATCH RFC v2 xserver] xwayland-input: Fake crossing to rootwin

Daniel Stone daniel at fooishbar.org
Tue Jun 21 11:08:42 UTC 2016


Hi Olivier,

On 20 June 2016 at 19:03, Olivier Fourdan <ofourdan at redhat.com> wrote:
> 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 at redhat.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96437

I'm currently travelling so can't easily test this, but with the
comment below addressed:
Acked-by: Daniel Stone <daniels at collabora.com>

> diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
> index 45acf0c..5184cb4 100644
> --- a/hw/xwayland/xwayland-input.c
> +++ b/hw/xwayland/xwayland-input.c
> @@ -944,6 +944,28 @@ 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) {
> +        sprite->spriteTraceGood = 1;
> +        return sprite->spriteTrace[0];
> +    }
> +
> +    return (*xwl_seat->xwl_screen->XYToWindow)(screen, sprite, x, y);

The wrapping here is broken. Instead you'll need something like:
    pScreen->XYToWindow = xwl_seat->xwl_screen->XYToWindow;
    ret = pScreen->XYToWindow(...);
    xwl_seat->xwl_screen->XYToWindow = pScreen->XYToWindow;
    pScreen->XYToWindow = xwl_xy_to_window;
    return ret;

This allows functions to modify the wrapping chain dynamically.

Cheers,
Daniel


More information about the xorg-devel mailing list