tests/cursor: Test Wayland client using wp_viewport for scaling

This test doesn't use a separate reference image, but verifies the
result is identical to that of the built in cursor.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3859>
This commit is contained in:
Jonas Ådahl 2024-11-20 21:13:08 +01:00 committed by Sebastian Wick
parent 3d45345789
commit bcb52960db
2 changed files with 142 additions and 44 deletions

View File

@ -32,6 +32,9 @@
#include "tests/meta-wayland-test-driver.h" #include "tests/meta-wayland-test-driver.h"
#include "tests/meta-wayland-test-utils.h" #include "tests/meta-wayland-test-utils.h"
#define CURSOR_SCALE_METHOD_BUFFER_SCALE "buffer-scale"
#define CURSOR_SCALE_METHOD_VIEWPORT "viewport"
struct _MetaCrossOverlay struct _MetaCrossOverlay
{ {
GObject parent; GObject parent;
@ -278,6 +281,52 @@ meta_wait_for_window_cursor (void)
g_main_context_iteration (NULL, TRUE); g_main_context_iteration (NULL, TRUE);
} }
static void
test_client_cursor (ClutterStageView *view,
const char *scale_method,
MetaCursor cursor,
const char *ref_test_name,
int ref_test_seq,
MetaReftestFlag ref_test_flags)
{
const char *cursor_name;
MetaWaylandTestClient *test_client;
MetaWindow *window;
MetaWindowActor *window_actor;
g_debug ("Testing cursor with client using %s", scale_method);
cursor_name = meta_cursor_get_name (cursor);
test_client =
meta_wayland_test_client_new_with_args (test_context,
"cursor-tests-client",
scale_method,
cursor_name,
NULL);
meta_wayland_test_driver_wait_for_sync_point (test_driver, 0);
window = meta_find_window_from_title (test_context,
"cursor-tests-surface");
g_assert_nonnull (window);
meta_wait_for_window_shown (window);
window_actor = meta_window_actor_from_window (window);
g_assert_nonnull (window_actor);
meta_wait_for_window_cursor ();
meta_ref_test_verify_view (view,
ref_test_name,
ref_test_seq,
ref_test_flags);
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
g_object_add_weak_pointer (G_OBJECT (window_actor),
(gpointer *) &window_actor);
meta_wayland_test_client_finish (test_client);
while (window_actor)
g_main_context_iteration (NULL, TRUE);
}
static void static void
meta_test_native_cursor_scaling (void) meta_test_native_cursor_scaling (void)
{ {
@ -288,7 +337,6 @@ meta_test_native_cursor_scaling (void)
ClutterActor *overlay_actor; ClutterActor *overlay_actor;
ClutterStageView *view; ClutterStageView *view;
MetaCursor cursor; MetaCursor cursor;
const char *cursor_name;
struct { struct {
int width; int width;
int height; int height;
@ -330,10 +378,7 @@ meta_test_native_cursor_scaling (void)
for (i = 0; i < G_N_ELEMENTS (test_cases); i++) for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
{ {
MetaWaylandTestClient *test_client;
g_autofree char *ref_test_name = NULL; g_autofree char *ref_test_name = NULL;
MetaWindow *window;
MetaWindowActor *window_actor;
g_debug ("Testing monitor resolution %dx%d with scale %f and " g_debug ("Testing monitor resolution %dx%d with scale %f and "
"%s layout mode", "%s layout mode",
@ -353,34 +398,16 @@ meta_test_native_cursor_scaling (void)
0, 0,
meta_ref_test_determine_ref_test_flag ()); meta_ref_test_determine_ref_test_flag ());
cursor_name = meta_cursor_get_name (cursor); test_client_cursor (view,
test_client = CURSOR_SCALE_METHOD_BUFFER_SCALE,
meta_wayland_test_client_new_with_args (test_context, cursor,
"cursor-tests-client", ref_test_name, 1,
cursor_name,
NULL);
meta_wayland_test_driver_wait_for_sync_point (test_driver, 0);
window = meta_find_window_from_title (test_context,
"cursor-tests-surface");
g_assert_nonnull (window);
meta_wait_for_window_shown (window);
window_actor = meta_window_actor_from_window (window);
g_assert_nonnull (window_actor);
meta_wait_for_window_cursor ();
meta_ref_test_verify_view (view,
ref_test_name,
1,
meta_ref_test_determine_ref_test_flag ()); meta_ref_test_determine_ref_test_flag ());
test_client_cursor (view,
meta_wayland_test_driver_emit_sync_event (test_driver, 0); CURSOR_SCALE_METHOD_VIEWPORT,
cursor,
g_object_add_weak_pointer (G_OBJECT (window_actor), ref_test_name, 0,
(gpointer *) &window_actor); META_REFTEST_FLAG_NONE);
meta_wayland_test_client_finish (test_client);
while (window_actor)
g_main_context_iteration (NULL, TRUE);
} }
clutter_actor_destroy (overlay_actor); clutter_actor_destroy (overlay_actor);

View File

@ -22,9 +22,17 @@
#include "wayland-test-client-utils.h" #include "wayland-test-client-utils.h"
typedef enum _CursorScaleMethod
{
CURSOR_SCALE_METHOD_BUFFER_SCALE,
CURSOR_SCALE_METHOD_VIEWPORT,
} CursorScaleMethod;
static CursorScaleMethod scale_method;
static char *cursor_name; static char *cursor_name;
static struct wl_surface *cursor_surface; static struct wl_surface *cursor_surface;
static struct wp_viewport *cursor_viewport;
static void static void
on_pointer_enter (WaylandSurface *surface, on_pointer_enter (WaylandSurface *surface,
@ -40,6 +48,27 @@ on_pointer_enter (WaylandSurface *surface,
int num, denom; int num, denom;
float scale; float scale;
int ceiled_scale; int ceiled_scale;
int effective_theme_size = 0;
float image_scale;
int hotspot_x = 0;
int hotspot_y = 0;
if (!cursor_surface)
cursor_surface = wl_compositor_create_surface (display->compositor);
switch (scale_method)
{
case CURSOR_SCALE_METHOD_BUFFER_SCALE:
g_clear_pointer (&cursor_viewport, wp_viewport_destroy);
break;
case CURSOR_SCALE_METHOD_VIEWPORT:
if (!cursor_viewport)
{
cursor_viewport = wp_viewporter_get_viewport (display->viewporter,
cursor_surface);
}
break;
}
theme_size = lookup_property_int (display, "cursor-theme-size"); theme_size = lookup_property_int (display, "cursor-theme-size");
num = lookup_property_int (display, "scale-num"); num = lookup_property_int (display, "scale-num");
@ -47,27 +76,62 @@ on_pointer_enter (WaylandSurface *surface,
scale = (float) num / (float) denom; scale = (float) num / (float) denom;
ceiled_scale = (int) ceilf (scale); ceiled_scale = (int) ceilf (scale);
switch (scale_method)
{
case CURSOR_SCALE_METHOD_BUFFER_SCALE:
effective_theme_size = (int) (theme_size * ceilf (scale));
break;
case CURSOR_SCALE_METHOD_VIEWPORT:
effective_theme_size = (int) (theme_size * ceilf (scale));
break;
}
g_debug ("Using effective cursor theme size %d for logical size %d "
"and actual scale %f",
effective_theme_size, theme_size, scale);
cursor_theme = wl_cursor_theme_load (NULL, cursor_theme = wl_cursor_theme_load (NULL,
(int) (theme_size * ceilf (scale)), effective_theme_size,
display->shm); display->shm);
cursor = wl_cursor_theme_get_cursor (cursor_theme, cursor_name); cursor = wl_cursor_theme_get_cursor (cursor_theme, cursor_name);
if (!cursor_surface)
cursor_surface = wl_compositor_create_surface (display->compositor);
image = cursor->images[0]; image = cursor->images[0];
buffer = wl_cursor_image_get_buffer (image); buffer = wl_cursor_image_get_buffer (image);
g_assert_nonnull (buffer); g_assert_nonnull (buffer);
image_scale = ((float) image->width / theme_size);
switch (scale_method)
{
case CURSOR_SCALE_METHOD_BUFFER_SCALE:
hotspot_x = (int) roundf (image->hotspot_x / ceiled_scale);
hotspot_y = (int) roundf (image->hotspot_y / ceiled_scale);
break;
case CURSOR_SCALE_METHOD_VIEWPORT:
hotspot_x = (int) roundf (image->hotspot_x / image_scale);
hotspot_y = (int) roundf (image->hotspot_y / image_scale);
break;
}
wl_pointer_set_cursor (pointer, serial, wl_pointer_set_cursor (pointer, serial,
cursor_surface, cursor_surface,
image->hotspot_x / ceiled_scale, hotspot_x, hotspot_y);
image->hotspot_y / ceiled_scale);
wl_surface_attach (cursor_surface, buffer, 0, 0); wl_surface_attach (cursor_surface, buffer, 0, 0);
wl_surface_damage (cursor_surface, 0, 0, wl_surface_damage_buffer (cursor_surface, 0, 0,
image->width, image->height); image->width, image->height);
switch (scale_method)
{
case CURSOR_SCALE_METHOD_BUFFER_SCALE:
wl_surface_set_buffer_scale (cursor_surface, wl_surface_set_buffer_scale (cursor_surface,
ceiled_scale); ceiled_scale);
break;
case CURSOR_SCALE_METHOD_VIEWPORT:
wp_viewport_set_destination (cursor_viewport,
(int) roundf (image->width / image_scale),
(int) roundf (image->height / image_scale));
break;
}
wl_surface_commit (cursor_surface); wl_surface_commit (cursor_surface);
wl_cursor_theme_destroy (cursor_theme); wl_cursor_theme_destroy (cursor_theme);
@ -82,7 +146,14 @@ main (int argc,
g_autoptr (WaylandDisplay) display = NULL; g_autoptr (WaylandDisplay) display = NULL;
g_autoptr (WaylandSurface) surface = NULL; g_autoptr (WaylandSurface) surface = NULL;
cursor_name = argv[1]; if (g_strcmp0 (argv[1], "buffer-scale") == 0)
scale_method = CURSOR_SCALE_METHOD_BUFFER_SCALE;
else if (g_strcmp0 (argv[1], "viewport") == 0)
scale_method = CURSOR_SCALE_METHOD_VIEWPORT;
else
g_error ("Missing scale method");
cursor_name = argv[2];
display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER);
surface = wayland_surface_new (display, surface = wayland_surface_new (display,