summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaochen Tong <i@hexchain.org>2020-07-08 21:53:08 +0200
committerFrediano Ziglio <freddy77@gmail.com>2020-08-19 10:46:08 +0100
commita945a3c24b11de017a3b22acb5085fec59efa662 (patch)
tree10867911cbddaa41586eb26a0cb8d6e33e98f30d
parent3c9efe24bdfb1bdbcdd5f734b22f49b521fdad77 (diff)
spice-widget: fix hotspot position on X11/HiDPI
GDK scales hotspot coordinates using screen scale factor on X11. We need to undo this to get the correct hotspot behavior, otherwise mouse selection becomes very inaccurate and difficult in the guest. See [1]. [1] https://gitlab.gnome.org/GNOME/gtk/-/blob/3.24.21/gdk/x11/gdkcursor-x11.c#L556-557 Signed-off-by: Haochen Tong <i@hexchain.org> Acked-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--src/spice-widget.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/spice-widget.c b/src/spice-widget.c
index a620084..b7938c1 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -2964,6 +2964,7 @@ static void cursor_set(SpiceCursorChannel *channel,
SpiceDisplayPrivate *d = display->priv;
GdkCursor *cursor = NULL;
SpiceCursorShape *cursor_shape;
+ gint hotspot_x, hotspot_y;
g_object_get(G_OBJECT(channel), "cursor", &cursor_shape, NULL);
if (G_UNLIKELY(cursor_shape == NULL || cursor_shape->data == NULL)) {
@@ -2985,12 +2986,22 @@ static void cursor_set(SpiceCursorChannel *channel,
cursor_shape_destroy, cursor_shape);
d->cursor_surface = gdk_cairo_surface_create_from_pixbuf(d->mouse_pixbuf, 0,
gtk_widget_get_window(GTK_WIDGET(display)));
- d->mouse_hotspot.x = cursor_shape->hot_spot_x;
- d->mouse_hotspot.y = cursor_shape->hot_spot_y;
+ hotspot_x = d->mouse_hotspot.x = cursor_shape->hot_spot_x;
+ hotspot_y = d->mouse_hotspot.y = cursor_shape->hot_spot_y;
+
+#ifdef GDK_WINDOWING_X11
+ /* undo hotspot scaling in gdkcursor */
+ if (GDK_IS_X11_DISPLAY(gtk_widget_get_display(GTK_WIDGET(display)))) {
+ gint scale_factor = gdk_window_get_scale_factor(gtk_widget_get_window(GTK_WIDGET(display)));
+ hotspot_x /= scale_factor;
+ hotspot_y /= scale_factor;
+ }
+#endif
+
cursor = gdk_cursor_new_from_surface(gtk_widget_get_display(GTK_WIDGET(display)),
d->cursor_surface,
- d->mouse_hotspot.x,
- d->mouse_hotspot.y);
+ hotspot_x,
+ hotspot_y);
#if HAVE_EGL
if (egl_enabled(d))