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.
This commit is contained in:
Christian Hergert 2023-02-15 12:16:47 -08:00
parent 03f64892e5
commit 0a7c1ff21c
3 changed files with 59 additions and 9 deletions

View File

@ -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,

View File

@ -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

View File

@ -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;
}