diff options
author | Olivier Fourdan <ofourdan@redhat.com> | 2016-06-23 15:31:30 +0200 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2016-08-19 11:04:25 +1000 |
commit | 6e5bec261c3f7af069b57618d6c82b070dc4579d (patch) | |
tree | 3cb839710985e1ccdb2327d02f0c86f82c58dc32 /hw | |
parent | 48c5c23a1b250c7f9d7a1747c76e4669ebf752cf (diff) |
wayland: Emulate crossing for native window
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 <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xwayland/xwayland-input.c | 15 | ||||
-rw-r--r-- | hw/xwayland/xwayland.c | 3 | ||||
-rw-r--r-- | 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 e295c71a4..043379ea3 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 a41b619bf..847321e87 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -324,7 +324,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 8db8df589..db3dd0b77 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; |