wayland: Use a viewport for pointer surfaces

This should give us more flexibility for buffer size vs surface
size. Unfortunately, mutter doesn't play along, so for now the
use of a viewporter for pointer surfaces is gated behind the
POINTER_USE_VIEWPORT environment variable.
This commit is contained in:
Matthias Clasen
2024-03-19 12:58:41 -04:00
parent ce8cf6866b
commit 160b8a0f7e
5 changed files with 38 additions and 11 deletions

View File

@@ -158,15 +158,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))
{
@@ -177,7 +181,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)
{
@@ -194,7 +198,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))
{
@@ -263,9 +267,14 @@ from_texture2:
*width = gdk_paintable_get_intrinsic_width (paintable);
*height = gdk_paintable_get_intrinsic_height (paintable);
*scale = desired_scale;
if (!use_viewporter)
*scale = desired_scale_factor;
else
*scale = desired_scale;
texture = gdk_cursor_create_texture (cursor, desired_scale);
texture = gdk_cursor_create_texture (cursor, *scale);
can_cache = (gdk_paintable_get_flags (paintable) & GDK_PAINTABLE_STATIC_CONTENTS) != 0;
goto from_texture2;
}
@@ -274,6 +283,7 @@ from_texture2:
return _gdk_wayland_cursor_get_buffer (display,
gdk_cursor_get_fallback (cursor),
desired_scale,
use_viewporter,
image_index,
hotspot_x, hotspot_y,
width, height,

View File

@@ -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;

View File

@@ -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);

View File

@@ -115,13 +115,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,

View File

@@ -3877,6 +3877,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
@@ -4240,6 +4241,9 @@ init_pointer_data (GdkWaylandPointerData *pointer_data,
wl_surface_add_listener (pointer_data->pointer_surface,
&pointer_surface_listener,
logical_device);
if (display_wayland->viewporter && g_getenv ("POINTER_USE_VIEWPORT"))
pointer_data->pointer_surface_viewport = wp_viewporter_get_viewport (display_wayland->viewporter, pointer_data->pointer_surface);
}
void