diff options
author | Haochen Tong <i@hexchain.org> | 2020-07-08 21:53:08 +0200 |
---|---|---|
committer | Frediano Ziglio <freddy77@gmail.com> | 2020-08-19 10:46:08 +0100 |
commit | a945a3c24b11de017a3b22acb5085fec59efa662 (patch) | |
tree | 10867911cbddaa41586eb26a0cb8d6e33e98f30d | |
parent | 3c9efe24bdfb1bdbcdd5f734b22f49b521fdad77 (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.c | 19 |
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)) |