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_contents_handler;
gulong invalidate_size_handler; gulong invalidate_size_handler;
gulong notify_cursor_handler; gulong notify_cursor_handler;
gulong mouse_set_handler;
/* Tracking the last known positions of mouse events so that we may /* Tracking the last known positions of mouse events so that we may
* do something "reasonable" if the pointer is not absolute. * 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); 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 static void
mks_display_set_paintable (MksDisplay *self, mks_display_set_paintable (MksDisplay *self,
GdkPaintable *paintable) 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_contents_handler, priv->paintable);
g_clear_signal_handler (&priv->invalidate_size_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->notify_cursor_handler, priv->paintable);
g_clear_signal_handler (&priv->mouse_set_handler, priv->paintable);
g_clear_object (&priv->paintable); g_clear_object (&priv->paintable);
} }
@ -174,6 +191,12 @@ mks_display_set_paintable (MksDisplay *self,
G_CALLBACK (mks_display_notify_cursor_cb), G_CALLBACK (mks_display_notify_cursor_cb),
self, self,
G_CONNECT_SWAPPED); 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]); 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) && if (gdk_event_get_axis (event, GDK_AXIS_X, &x) &&
gdk_event_get_axis (event, GDK_AXIS_Y, &y)) 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_x = priv->last_mouse_x - (x / area.size.width) * guest_width;
double delta_y = floor (y - priv->last_mouse_y) / area.size.height * guest_height; double delta_y = priv->last_mouse_y - (y / area.size.height) * guest_height;
priv->last_mouse_x = x;
priv->last_mouse_y = y;
mks_mouse_move_by (mouse, mks_mouse_move_by (mouse,
delta_x, delta_x,

View File

@ -29,9 +29,12 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject) G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject)
GdkPaintable *_mks_paintable_new (GCancellable *cancellable, GdkPaintable *_mks_paintable_new (GCancellable *cancellable,
int *peer_fd, int *peer_fd,
GError **error); GError **error);
GdkCursor *_mks_paintable_get_cursor (MksPaintable *self); GdkCursor *_mks_paintable_get_cursor (MksPaintable *self);
void _mks_paintable_get_position (MksPaintable *self,
int *x,
int *y);
G_END_DECLS G_END_DECLS

View File

@ -32,6 +32,8 @@
#include "mks-paintable-private.h" #include "mks-paintable-private.h"
#include "mks-qemu.h" #include "mks-qemu.h"
#include "mks-marshal.h"
struct _MksPaintable struct _MksPaintable
{ {
GObject parent_instance; GObject parent_instance;
@ -40,6 +42,8 @@ struct _MksPaintable
GDBusConnection *connection; GDBusConnection *connection;
GdkPaintable *child; GdkPaintable *child;
GdkCursor *cursor; GdkCursor *cursor;
int mouse_x;
int mouse_y;
}; };
enum { enum {
@ -49,7 +53,13 @@ enum {
N_PROPS N_PROPS
}; };
enum {
MOUSE_SET,
N_SIGNALS
};
static GParamSpec *properties [N_PROPS]; static GParamSpec *properties [N_PROPS];
static guint signals [N_SIGNALS];
static cairo_format_t static cairo_format_t
_pixman_format_to_cairo_format (guint pixman_format) _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_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties); 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 static void
@ -563,8 +585,13 @@ mks_paintable_listener_mouse_set (MksPaintable *self,
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
g_assert (MKS_QEMU_IS_LISTENER (listener)); g_assert (MKS_QEMU_IS_LISTENER (listener));
self->mouse_x = x;
self->mouse_y = y;
mks_qemu_listener_complete_mouse_set (listener, invocation); mks_qemu_listener_complete_mouse_set (listener, invocation);
g_signal_emit (self, signals[MOUSE_SET], 0, x, y);
return TRUE; return TRUE;
} }