We need to compensate the move induced by gdk_device_warp. We cannot just ignore the next pointer move event as it may include additional user moves. The fixed issue is most visible over ssh -X. On Wayland this patch also improves mouse motion as it at least removes ignoring of each other mouse event. gdk_display_sync has been removed as I experience no effect of it both before and after this commit. Signed-off-by: Marie Stephanie Alesna <istephielicious@xxxxxxxxx> --- src/spice-widget-priv.h | 2 ++ src/spice-widget.c | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h index 1189cbb..728879c 100644 --- a/src/spice-widget-priv.h +++ b/src/spice-widget-priv.h @@ -105,6 +105,8 @@ struct _SpiceDisplayPrivate { GdkCursor *show_cursor; int mouse_last_x; int mouse_last_y; + gdouble mouse_delta_x; + gdouble mouse_delta_y; int mouse_guest_x; int mouse_guest_y; diff --git a/src/spice-widget.c b/src/spice-widget.c index 5365222..3fbb719 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -28,6 +28,9 @@ #include <X11/Xlib.h> #include <gdk/gdkx.h> #endif +#ifdef GDK_WINDOWING_WAYLAND +#include <gdk/gdkwayland.h> +#endif #ifdef G_OS_WIN32 #include <windows.h> #include <dinput.h> @@ -1145,6 +1148,8 @@ static void try_mouse_grab(SpiceDisplay *display) d->mouse_last_x = -1; d->mouse_last_y = -1; + d->mouse_delta_x = 0; + d->mouse_delta_y = 0; } static void mouse_wrap(SpiceDisplay *display, GdkEventMotion *motion) @@ -1162,18 +1167,29 @@ static void mouse_wrap(SpiceDisplay *display, GdkEventMotion *motion) d->mouse_last_x = -1; d->mouse_last_y = -1; #else + +#ifdef GDK_WINDOWING_WAYLAND + // gdk_device_warp has no effect on Wayland and mouse_delta_x/mouse_delta_y + // would block any mouse movements there. + GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display)); + GdkDisplay *gdk_display = gdk_window_get_display(window); + if (GDK_IS_WAYLAND_DISPLAY(gdk_display)) + return; +#endif + GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(display)); xr = gdk_screen_get_width(screen) / 2; yr = gdk_screen_get_height(screen) / 2; if (xr != (gint)motion->x_root || yr != (gint)motion->y_root) { GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display)); - /* FIXME: we try our best to ignore that next pointer move event.. */ - gdk_display_sync(gdk_screen_get_display(screen)); + /* We need to compensate the move induced by gdk_device_warp. + We cannot just ignore the next pointer move event as it may include + additional user moves. */ gdk_device_warp(spice_gdk_window_get_pointing_device(window), screen, xr, yr); - d->mouse_last_x = -1; - d->mouse_last_y = -1; + d->mouse_delta_x += xr - motion->x_root; + d->mouse_delta_y += yr - motion->y_root; } #endif @@ -1982,7 +1998,8 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion) try_keyboard_grab(display); } - transform_input(display, motion->x, motion->y, &x, &y); + transform_input(display, motion->x - d->mouse_delta_x, + motion->y - d->mouse_delta_y, &x, &y); switch (d->mouse_mode) { case SPICE_MOUSE_MODE_CLIENT:
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel