Emitting a LeaveNotify event every time the pointer leaves an X11 window may confuse focus follow mouse mode in window managers such as mutter/gnome-shell.
Keep the previously found X window and compare against the new one, and if they match then it means the pointer has left an Xwayland window for a native Wayland surface, only in this case fake the crossing to the root window. Signed-off-by: Olivier Fourdan <ofour...@redhat.com> --- hw/xwayland/xwayland-input.c | 15 ++++++++++++++- hw/xwayland/xwayland.c | 3 ++- hw/xwayland/xwayland.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index e295c71..043379e 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -959,7 +959,7 @@ xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y) } } - if (xwl_seat == NULL || !xwl_seat->focus_window) { + if (xwl_seat == NULL) { sprite->spriteTraceGood = 1; return sprite->spriteTrace[0]; } @@ -969,6 +969,19 @@ xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y) xwl_seat->xwl_screen->XYToWindow = screen->XYToWindow; screen->XYToWindow = xwl_xy_to_window; + /* If the pointer has left the Wayland surface but the DIX still + * finds the pointer within the previous X11 window, it means that + * the pointer has crossed to another native Wayland window, in this + * case, pretend we entered the root window so that a LeaveNotify + * event is emitted. + */ + if (xwl_seat->focus_window == NULL && xwl_seat->last_xwindow == ret) { + sprite->spriteTraceGood = 1; + return sprite->spriteTrace[0]; + } + + xwl_seat->last_xwindow = ret; + return ret; } diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 8c49b0b..1b29491 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -323,7 +323,8 @@ xwl_unrealize_window(WindowPtr window) xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) { if (xwl_seat->focus_window && xwl_seat->focus_window->window == window) xwl_seat->focus_window = NULL; - + if (xwl_seat->last_xwindow == window) + xwl_seat->last_xwindow = NullWindow; xwl_seat_clear_touch(xwl_seat, window); } diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index b8a58e7..aa78b44 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -132,6 +132,7 @@ struct xwl_seat { struct wl_surface *cursor; struct wl_callback *cursor_frame_cb; Bool cursor_needs_update; + WindowPtr last_xwindow; struct xorg_list touches; -- 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