diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index ba43df91b4..d8a13578b0 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -155,15 +155,19 @@ static const struct wl_buffer_listener buffer_listener = { struct wl_buffer * _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, GdkCursor *cursor, - guint desired_scale, + double desired_scale, + gboolean use_viewporter, guint image_index, int *hotspot_x, int *hotspot_y, int *width, int *height, - int *scale) + double *scale) { GdkTexture *texture; + int desired_scale_factor; + + desired_scale_factor = (int) ceil (desired_scale); if (gdk_cursor_get_name (cursor)) { @@ -174,7 +178,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, c = gdk_wayland_cursor_load_for_name (display, _gdk_wayland_display_get_cursor_theme (display), - desired_scale, + desired_scale_factor, gdk_cursor_get_name (cursor)); if (c && c->image_count > 0) { @@ -191,7 +195,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, image = c->images[image_index]; - cursor_scale = desired_scale; + cursor_scale = desired_scale_factor; if ((image->width % cursor_scale != 0) || (image->height % cursor_scale != 0)) { @@ -252,11 +256,14 @@ from_texture: } else { - *scale = desired_scale; + if (!use_viewporter) + *scale = desired_scale_factor; + else + *scale = desired_scale; texture = gdk_cursor_get_texture_for_size (cursor, display->cursor_theme_size, - desired_scale, + *scale, width, height, hotspot_x, @@ -290,6 +297,7 @@ from_texture: return _gdk_wayland_cursor_get_buffer (display, gdk_cursor_get_fallback (cursor), desired_scale, + use_viewporter, image_index, hotspot_x, hotspot_y, width, height, diff --git a/gdk/wayland/gdkdevice-wayland-private.h b/gdk/wayland/gdkdevice-wayland-private.h index 01ed67dfa8..9b0c4e429c 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 fd03d4fcaa..0d7257eef1 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -260,7 +260,8 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device) GdkWaylandPointerData *pointer = gdk_wayland_device_get_pointer (wayland_device); struct wl_buffer *buffer; - int x, y, w, h, scale; + int x, y, w, h; + double scale; guint next_image_index, next_image_delay; gboolean retval = G_SOURCE_REMOVE; GdkWaylandTabletData *tablet; @@ -271,7 +272,8 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device) { buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display), pointer->cursor, - (int) ceil (pointer->current_output_scale), + pointer->current_output_scale, + pointer->pointer_surface_viewport != NULL, pointer->cursor_image_index, &x, &y, &w, &h, &scale); } @@ -310,7 +312,16 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device) if (buffer) { wl_surface_attach (pointer->pointer_surface, buffer, 0, 0); - if (wl_surface_get_version (pointer->pointer_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) + 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); + } + else if (wl_surface_get_version (pointer->pointer_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION) wl_surface_set_buffer_scale (pointer->pointer_surface, scale); 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 1d0b27f9fa..9dade70f73 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -116,13 +116,14 @@ void gdk_wayland_display_system_bell (GdkDisplay *display, struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display, GdkCursor *cursor, - guint desired_scale, + double desired_scale, + gboolean use_viewporter, guint image_index, int *hotspot_x, int *hotspot_y, int *w, int *h, - int *scale); + 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 268df2abe3..643552c3f8 100644 --- a/gdk/wayland/gdkseat-wayland.c +++ b/gdk/wayland/gdkseat-wayland.c @@ -3878,6 +3878,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 @@ -4241,6 +4242,9 @@ 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