Hey Olivier!, Without getting much into the patch (the rationale makes sense to me though), restoring the XYToWindow handler probably means the patch at https://patchwork.freedesktop.org/patch/50607/ should be reconsidered again.
On Wed, Jun 15, 2016 at 4:24 PM, Olivier Fourdan <[email protected]> wrote: > Hi all, > > So this patch might deserve some more explanation... > > This is for https://bugs.freedesktop.org/show_bug.cgi?id=96437 > > The problem occurs when the pointer moves from an X11 window to a Wayland > native window which overlaps it: > > > +----------------------------------+ > | | > | > weston-terminal | > | | > | | > +-----------| | > | | | > | xev | | > | | | > | +----------------------------------+ > +--------------+ > > > When the pointer leaves the Xwayland client window to enter a Wayland native > surface, pointer_handle_leave() in xwayland-input.c calls CheckMotion() with > an NULL event, so that the Enter/Leave notify events get emitted as expected. > > CheckMotion() from dix/events.c will save the previous WindowPtr as > prevSpriteWin and calls XYToWindow() to find the new window where the pointer > resides. > > But since that new window is a Wayland native window unknown to Xwayland, > XYToWindow() via miXYToWindow() and miSpriteTrace() will return the Xwayland > window under the current pointer positioon, and that happens to be still the > same window (due to the overlap betwee nthe Wayland native window and the > Xwayland window). > > Therefore, newSpriteWin (as returned by XYToWindow) remains the same as > prevSpriteWin and therfore DoEnterLeaveEvents() is not invoked (as Xwayland > reckons the pointer is still within the X11 window...). > > What this patch does is to re-add the previously removed XYToWindow() vfunc > in Xwayland to return the root window if there is no xwl_seat->focus_window > set. As xwl_seat->focus_window is cleared in pointer_handle_leave(), in > effects it means that when the pointer leaves an X11 window to enter a > Wayland native window, XYToWindow() returns the root window and CheckMotion > will emit the expected LeaveNotify event. > > Cheers, > Olivier > > > > ----- Original Message ----- >> 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 <[email protected]> >> 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 >> >> _______________________________________________ >> [email protected]: X.Org development >> Archives: http://lists.x.org/archives/xorg-devel >> Info: https://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: https://lists.x.org/mailman/listinfo/xorg-devel _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
