From 39d72f513a88d1cfc84d3104089776f90227f616 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 27 Sep 2024 22:06:17 -0400 Subject: [PATCH] wayland: Bring back the pointer viewporter This was a thinko in 403da9a2d5355c199682b. We have the cursor image in device pixels, but we still need to apply the viewporter to inform the compositor about the desired pointer size in application pixels. --- gdk/wayland/gdkcursor-wayland.c | 20 ++++++++++++++------ gdk/wayland/gdkdevice-wayland-private.h | 1 + gdk/wayland/gdkdevice-wayland.c | 13 ++++++++++++- gdk/wayland/gdkprivate-wayland.h | 3 ++- gdk/wayland/gdkseat-wayland.c | 3 +++ 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index 68c24de4892..45bcb9d940b 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; + *width = image->width / desired_scale; + *height = image->height / desired_scale; + *hotspot_x = image->hotspot_x / desired_scale; + *hotspot_y = image->hotspot_y / desired_scale; + + *scale = MIN (image->width / (double) *width, image->height / (double) *height); 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 01ed67dfa8a..9b0c4e429c8 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 771be3cdfd5..5c41e99fd8b 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 d2a87240b0f..b2549c67a99 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 823cfe93ac5..007c973810d 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 -- GitLab