summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2016-06-23 15:31:30 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2016-08-19 11:04:25 +1000
commit6e5bec261c3f7af069b57618d6c82b070dc4579d (patch)
tree3cb839710985e1ccdb2327d02f0c86f82c58dc32
parent48c5c23a1b250c7f9d7a1747c76e4669ebf752cf (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>
-rw-r--r--hw/xwayland/xwayland-input.c15
-rw-r--r--hw/xwayland/xwayland.c3
-rw-r--r--hw/xwayland/xwayland.h1
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;