From 0a7c1ff21c035c28c74bdade37142d6b608c91d4 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 15 Feb 2023 12:16:47 -0800 Subject: [PATCH] lib: use mouse-set from peer to update local position We may need to tweak this for relative mouse positions if we find we dont get reliable information from the peer. But this is a start, which I see we get back from Qemu at least when we're in -enable-kvm mode. --- lib/mks-display.c | 30 +++++++++++++++++++++++++----- lib/mks-paintable-private.h | 11 +++++++---- lib/mks-paintable.c | 27 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/lib/mks-display.c b/lib/mks-display.c index 6971d17..5448bc0 100644 --- a/lib/mks-display.c +++ b/lib/mks-display.c @@ -44,6 +44,7 @@ typedef struct gulong invalidate_contents_handler; gulong invalidate_size_handler; gulong notify_cursor_handler; + gulong mouse_set_handler; /* Tracking the last known positions of mouse events so that we may * do something "reasonable" if the pointer is not absolute. @@ -133,6 +134,21 @@ mks_display_notify_cursor_cb (MksDisplay *self, gtk_widget_set_cursor (GTK_WIDGET (self), cursor); } +static void +mks_display_mouse_set_cb (MksDisplay *self, + int x, + int y, + MksPaintable *paintable) +{ + MksDisplayPrivate *priv = mks_display_get_instance_private (self); + + g_assert (MKS_IS_DISPLAY (self)); + g_assert (MKS_IS_PAINTABLE (paintable)); + + priv->last_mouse_x = x; + priv->last_mouse_y = y; +} + static void mks_display_set_paintable (MksDisplay *self, GdkPaintable *paintable) @@ -150,6 +166,7 @@ mks_display_set_paintable (MksDisplay *self, g_clear_signal_handler (&priv->invalidate_contents_handler, priv->paintable); g_clear_signal_handler (&priv->invalidate_size_handler, priv->paintable); g_clear_signal_handler (&priv->notify_cursor_handler, priv->paintable); + g_clear_signal_handler (&priv->mouse_set_handler, priv->paintable); g_clear_object (&priv->paintable); } @@ -174,6 +191,12 @@ mks_display_set_paintable (MksDisplay *self, G_CALLBACK (mks_display_notify_cursor_cb), self, G_CONNECT_SWAPPED); + priv->notify_cursor_handler = + g_signal_connect_object (paintable, + "mouse-set", + G_CALLBACK (mks_display_mouse_set_cb), + self, + G_CONNECT_SWAPPED); } g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PAINTABLE]); @@ -388,11 +411,8 @@ mks_display_legacy_event_cb (MksDisplay *self, if (gdk_event_get_axis (event, GDK_AXIS_X, &x) && gdk_event_get_axis (event, GDK_AXIS_Y, &y)) { - double delta_x = floor (x - priv->last_mouse_x) / area.size.width * guest_width; - double delta_y = floor (y - priv->last_mouse_y) / area.size.height * guest_height; - - priv->last_mouse_x = x; - priv->last_mouse_y = y; + double delta_x = priv->last_mouse_x - (x / area.size.width) * guest_width; + double delta_y = priv->last_mouse_y - (y / area.size.height) * guest_height; mks_mouse_move_by (mouse, delta_x, diff --git a/lib/mks-paintable-private.h b/lib/mks-paintable-private.h index 0cc841e..1daa418 100644 --- a/lib/mks-paintable-private.h +++ b/lib/mks-paintable-private.h @@ -29,9 +29,12 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject) -GdkPaintable *_mks_paintable_new (GCancellable *cancellable, - int *peer_fd, - GError **error); -GdkCursor *_mks_paintable_get_cursor (MksPaintable *self); +GdkPaintable *_mks_paintable_new (GCancellable *cancellable, + int *peer_fd, + GError **error); +GdkCursor *_mks_paintable_get_cursor (MksPaintable *self); +void _mks_paintable_get_position (MksPaintable *self, + int *x, + int *y); G_END_DECLS diff --git a/lib/mks-paintable.c b/lib/mks-paintable.c index 7e6d9ca..21fa570 100644 --- a/lib/mks-paintable.c +++ b/lib/mks-paintable.c @@ -32,6 +32,8 @@ #include "mks-paintable-private.h" #include "mks-qemu.h" +#include "mks-marshal.h" + struct _MksPaintable { GObject parent_instance; @@ -40,6 +42,8 @@ struct _MksPaintable GDBusConnection *connection; GdkPaintable *child; GdkCursor *cursor; + int mouse_x; + int mouse_y; }; enum { @@ -49,7 +53,13 @@ enum { N_PROPS }; +enum { + MOUSE_SET, + N_SIGNALS +}; + static GParamSpec *properties [N_PROPS]; +static guint signals [N_SIGNALS]; static cairo_format_t _pixman_format_to_cairo_format (guint pixman_format) @@ -198,6 +208,18 @@ mks_paintable_class_init (MksPaintableClass *klass) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_properties (object_class, N_PROPS, properties); + + signals [MOUSE_SET] = + g_signal_new ("mouse-set", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _mks_marshal_VOID__INT_INT, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); + g_signal_set_va_marshaller (signals [MOUSE_SET], + G_TYPE_FROM_CLASS (klass), + _mks_marshal_VOID__INT_INTv); } static void @@ -563,8 +585,13 @@ mks_paintable_listener_mouse_set (MksPaintable *self, g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_assert (MKS_QEMU_IS_LISTENER (listener)); + self->mouse_x = x; + self->mouse_y = y; + mks_qemu_listener_complete_mouse_set (listener, invocation); + g_signal_emit (self, signals[MOUSE_SET], 0, x, y); + return TRUE; }