From bcb52960dbe8ac2cf944acbadaed1b68e366915b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 20 Nov 2024 21:13:08 +0100 Subject: [PATCH] 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: --- src/tests/cursor-tests.c | 91 +++++++++++------- .../cursor-tests-client.c | 95 ++++++++++++++++--- 2 files changed, 142 insertions(+), 44 deletions(-) diff --git a/src/tests/cursor-tests.c b/src/tests/cursor-tests.c index 6a9298517..47aa18af5 100644 --- a/src/tests/cursor-tests.c +++ b/src/tests/cursor-tests.c @@ -32,6 +32,9 @@ #include "tests/meta-wayland-test-driver.h" #include "tests/meta-wayland-test-utils.h" +#define CURSOR_SCALE_METHOD_BUFFER_SCALE "buffer-scale" +#define CURSOR_SCALE_METHOD_VIEWPORT "viewport" + struct _MetaCrossOverlay { GObject parent; @@ -278,6 +281,52 @@ meta_wait_for_window_cursor (void) 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 meta_test_native_cursor_scaling (void) { @@ -288,7 +337,6 @@ meta_test_native_cursor_scaling (void) ClutterActor *overlay_actor; ClutterStageView *view; MetaCursor cursor; - const char *cursor_name; struct { int width; int height; @@ -330,10 +378,7 @@ meta_test_native_cursor_scaling (void) for (i = 0; i < G_N_ELEMENTS (test_cases); i++) { - MetaWaylandTestClient *test_client; g_autofree char *ref_test_name = NULL; - MetaWindow *window; - MetaWindowActor *window_actor; g_debug ("Testing monitor resolution %dx%d with scale %f and " "%s layout mode", @@ -353,34 +398,16 @@ meta_test_native_cursor_scaling (void) 0, meta_ref_test_determine_ref_test_flag ()); - cursor_name = meta_cursor_get_name (cursor); - test_client = - meta_wayland_test_client_new_with_args (test_context, - "cursor-tests-client", - 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_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); + test_client_cursor (view, + CURSOR_SCALE_METHOD_BUFFER_SCALE, + cursor, + ref_test_name, 1, + meta_ref_test_determine_ref_test_flag ()); + test_client_cursor (view, + CURSOR_SCALE_METHOD_VIEWPORT, + cursor, + ref_test_name, 0, + META_REFTEST_FLAG_NONE); } clutter_actor_destroy (overlay_actor); diff --git a/src/tests/wayland-test-clients/cursor-tests-client.c b/src/tests/wayland-test-clients/cursor-tests-client.c index 3ccd4bc50..7655a58ba 100644 --- a/src/tests/wayland-test-clients/cursor-tests-client.c +++ b/src/tests/wayland-test-clients/cursor-tests-client.c @@ -22,9 +22,17 @@ #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 struct wl_surface *cursor_surface; +static struct wp_viewport *cursor_viewport; static void on_pointer_enter (WaylandSurface *surface, @@ -40,6 +48,27 @@ on_pointer_enter (WaylandSurface *surface, int num, denom; float 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"); num = lookup_property_int (display, "scale-num"); @@ -47,27 +76,62 @@ on_pointer_enter (WaylandSurface *surface, scale = (float) num / (float) denom; 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, - (int) (theme_size * ceilf (scale)), + effective_theme_size, display->shm); 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]; buffer = wl_cursor_image_get_buffer (image); 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, cursor_surface, - image->hotspot_x / ceiled_scale, - image->hotspot_y / ceiled_scale); + hotspot_x, hotspot_y); wl_surface_attach (cursor_surface, buffer, 0, 0); - wl_surface_damage (cursor_surface, 0, 0, - image->width, image->height); - wl_surface_set_buffer_scale (cursor_surface, - ceiled_scale); + wl_surface_damage_buffer (cursor_surface, 0, 0, + image->width, image->height); + + switch (scale_method) + { + case CURSOR_SCALE_METHOD_BUFFER_SCALE: + wl_surface_set_buffer_scale (cursor_surface, + 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_cursor_theme_destroy (cursor_theme); @@ -82,7 +146,14 @@ main (int argc, g_autoptr (WaylandDisplay) display = 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); surface = wayland_surface_new (display,