diff --git a/gdk/wayland/cursor/xcursor.c b/gdk/wayland/cursor/xcursor.c index 8ee675b37576647f1100c02ea16552173816f539..7570b067cc25d823749856bde7f3aee5a37d7f9f 100644 --- a/gdk/wayland/cursor/xcursor.c +++ b/gdk/wayland/cursor/xcursor.c @@ -402,6 +402,38 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader, if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) continue; thisSize = fileHeader->tocs[n].subtype; + if (thisSize == size) + { + bestSize = size; + nsizes++; + } + } + + if (bestSize) + goto done; + + for (n = 0; n < fileHeader->ntoc; n++) + { + if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) + continue; + thisSize = fileHeader->tocs[n].subtype; + if (thisSize == 2 * size) + { + bestSize = 2 * size; + nsizes++; + } + } + + if (bestSize) + goto done; + + for (n = 0; n < fileHeader->ntoc; n++) + { + if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) + continue; + thisSize = fileHeader->tocs[n].subtype; + if (thisSize < size) + continue; if (!bestSize || dist (thisSize, size) < dist (bestSize, size)) { bestSize = thisSize; @@ -410,6 +442,25 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader, else if (thisSize == bestSize) nsizes++; } + + if (bestSize) + goto done; + + for (n = 0; n < fileHeader->ntoc; n++) + { + if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) + continue; + thisSize = fileHeader->tocs[n].subtype; + if (!bestSize || dist (thisSize, size) < dist (bestSize, size)) + { + bestSize = thisSize; + nsizes = 1; + } + else if (thisSize == bestSize) + nsizes++; + } + +done: *nsizesp = nsizes; return bestSize; } diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index 68c24de4892dcc7888721a46170d991325d77f64..577379f5ec03d84ff0671e1e5aef4f8b8fd9f19f 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -160,7 +160,8 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, int *hotspot_x, int *hotspot_y, int *width, - int *height) + int *height, + double *scale) { GdkTexture *texture; @@ -172,6 +173,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, { *hotspot_x = *hotspot_y = 0; *width = *height = 0; + *scale = 1; return NULL; } @@ -194,10 +196,12 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, image = c->images[image_index]; - *width = image->width; - *height = image->height; - *hotspot_x = image->hotspot_x; - *hotspot_y = image->hotspot_y; + *scale = c->size / (double) display->cursor_theme_size; + + *width = image->width / *scale; + *height = image->height / *scale; + *hotspot_x = image->hotspot_x / *scale; + *hotspot_y = image->hotspot_y / *scale; return wl_cursor_image_get_buffer (image); } @@ -231,6 +235,7 @@ from_texture: *hotspot_y = gdk_cursor_get_hotspot_y (cursor); *width = gdk_texture_get_width (texture); *height = gdk_texture_get_height (texture); + *scale = 1; cairo_surface_reference (surface); buffer = _gdk_wayland_shm_surface_get_wl_buffer (surface); @@ -242,6 +247,8 @@ from_texture: } else { + *scale = desired_scale; + texture = gdk_cursor_get_texture_for_size (cursor, display->cursor_theme_size, desired_scale, @@ -281,7 +288,8 @@ from_texture: desired_scale, image_index, hotspot_x, hotspot_y, - width, height); + width, height, + scale); } else { diff --git a/gdk/wayland/gdkdevice-wayland-private.h b/gdk/wayland/gdkdevice-wayland-private.h index 01ed67dfa8a797e18b2e28e87b702e2302de4136..9b0c4e429c8e4c1298a186eb9eb18e32940afee8 100644 --- a/gdk/wayland/gdkdevice-wayland-private.h +++ b/gdk/wayland/gdkdevice-wayland-private.h @@ -62,6 +62,7 @@ struct _GdkWaylandPointerData { uint32_t grab_time; struct wl_surface *pointer_surface; + struct wp_viewport *pointer_surface_viewport; guint cursor_is_default: 1; GdkCursor *cursor; guint cursor_timeout_id; diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 771be3cdfd5c14f670c5e93f64d121e1cb4eed89..5c41e99fd8bfef0916e42bcbacf14fc7736daddb 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -261,6 +261,7 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device) gdk_wayland_device_get_pointer (wayland_device); struct wl_buffer *buffer; int x, y, w, h; + double scale; guint next_image_index, next_image_delay; gboolean retval = G_SOURCE_REMOVE; GdkWaylandTabletData *tablet; @@ -273,7 +274,8 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device) pointer->cursor, pointer->current_output_scale, pointer->cursor_image_index, - &x, &y, &w, &h); + &x, &y, &w, &h, + &scale); } else { @@ -310,6 +312,15 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device) if (buffer) { wl_surface_attach (pointer->pointer_surface, buffer, 0, 0); + if (pointer->pointer_surface_viewport) + { + wp_viewport_set_source (pointer->pointer_surface_viewport, + wl_fixed_from_int (0), + wl_fixed_from_int (0), + wl_fixed_from_double (w * scale), + wl_fixed_from_double (h * scale)); + wp_viewport_set_destination (pointer->pointer_surface_viewport, w, h); + } wl_surface_damage (pointer->pointer_surface, 0, 0, w, h); wl_surface_commit (pointer->pointer_surface); } diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index d2a87240b0fbf95dec189df9fa697cfe0aef36e1..b2549c67a995d43f53a7c8e302b3f0f140dc2b2a 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -121,7 +121,8 @@ struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, int *hotspot_x, int *hotspot_y, int *w, - int *h); + int *h, + double *scale); guint _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display, GdkCursor *cursor, guint scale, diff --git a/gdk/wayland/gdkseat-wayland.c b/gdk/wayland/gdkseat-wayland.c index 823cfe93ac5744d9331047a94a0d1180367c0ddf..007c973810d917b036608dc8f19a73d86f55df93 100644 --- a/gdk/wayland/gdkseat-wayland.c +++ b/gdk/wayland/gdkseat-wayland.c @@ -3894,6 +3894,7 @@ gdk_wayland_pointer_data_finalize (GdkWaylandPointerData *pointer) g_clear_object (&pointer->cursor); wl_surface_destroy (pointer->pointer_surface); g_slist_free (pointer->pointer_surface_outputs); + g_clear_pointer (&pointer->pointer_surface_viewport, wp_viewport_destroy); } static void @@ -4260,6 +4261,8 @@ init_pointer_data (GdkWaylandPointerData *pointer_data, wl_surface_add_listener (pointer_data->pointer_surface, &pointer_surface_listener, logical_device); + if (display_wayland->viewporter) + pointer_data->pointer_surface_viewport = wp_viewporter_get_viewport (display_wayland->viewporter, pointer_data->pointer_surface); } void