File 0001-cursor-Unify-prepare_func-for-shape-cursors.patch of Package mutter
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Jan Alexander Steffens (heftig)" <heftig@archlinux.org>
Date: Tue, 18 Mar 2025 22:58:37 +0100
Subject: [PATCH] cursor: Unify prepare_func for shape cursors
Move the root cursor prepare function into MetaCursorSpriteXcursor to
become its default prepare function. This should solve two issues:
- The root cursor prepare function was changed in f77d8e2a12a07ef6abe9
to solve an issue with fractional scales. The tool cursor prepare
function was missing this fix.
- The cursors created via the shape protocol had no prepare function at
all, so were not getting scaled.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3975
---
src/backends/meta-cursor-sprite-xcursor.c | 57 ++++++++++++++++++++
src/core/display.c | 63 ++---------------------
src/wayland/meta-wayland-tablet-tool.c | 39 --------------
3 files changed, 60 insertions(+), 99 deletions(-)
diff --git a/src/backends/meta-cursor-sprite-xcursor.c b/src/backends/meta-cursor-sprite-xcursor.c
index a4b9cbb988ab..dc2580f65db9 100644
--- a/src/backends/meta-cursor-sprite-xcursor.c
+++ b/src/backends/meta-cursor-sprite-xcursor.c
@@ -24,6 +24,7 @@
#include "backends/meta-cursor.h"
#include "backends/meta-cursor-renderer.h"
#include "backends/meta-cursor-tracker-private.h"
+#include "backends/meta-logical-monitor.h"
#include "clutter/clutter.h"
#include "cogl/cogl.h"
#include "meta/prefs.h"
@@ -510,22 +511,78 @@ meta_cursor_sprite_xcursor_new (MetaCursor cursor,
return sprite_xcursor;
}
+static void
+xcursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
+ float best_scale,
+ int x,
+ int y,
+ void *user_data)
+{
+ MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
+ MetaCursorTracker *cursor_tracker =
+ meta_cursor_sprite_get_cursor_tracker (cursor_sprite);
+ MetaBackend *backend =
+ meta_cursor_tracker_get_backend (cursor_tracker);
+
+ if (meta_backend_is_stage_views_scaled (backend))
+ {
+ if (best_scale != 0.0f)
+ {
+ float ceiled_scale;
+ int cursor_width, cursor_height;
+
+ ceiled_scale = ceilf (best_scale);
+ meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
+ (int) ceiled_scale);
+
+ meta_cursor_sprite_realize_texture (cursor_sprite);
+ meta_cursor_sprite_xcursor_get_scaled_image_size (sprite_xcursor,
+ &cursor_width,
+ &cursor_height);
+ meta_cursor_sprite_set_viewport_dst_size (cursor_sprite,
+ cursor_width,
+ cursor_height);
+ }
+ }
+ else
+ {
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
+ MetaLogicalMonitor *logical_monitor;
+
+ logical_monitor =
+ meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
+
+ /* Reload the cursor texture if the scale has changed. */
+ if (logical_monitor)
+ {
+ meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
+ (int) logical_monitor->scale);
+ meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0f);
+ }
+ }
+}
+
static void
meta_cursor_sprite_xcursor_finalize (GObject *object)
{
MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (object);
g_clear_pointer (&sprite_xcursor->xcursor_images,
xcursor_images_destroy);
G_OBJECT_CLASS (meta_cursor_sprite_xcursor_parent_class)->finalize (object);
}
static void
meta_cursor_sprite_xcursor_init (MetaCursorSpriteXcursor *sprite_xcursor)
{
sprite_xcursor->theme_scale = 1;
sprite_xcursor->theme_dirty = TRUE;
+
+ meta_cursor_sprite_set_prepare_func (META_CURSOR_SPRITE (sprite_xcursor),
+ (MetaCursorPrepareFunc) xcursor_prepare_at,
+ NULL);
}
static void
diff --git a/src/core/display.c b/src/core/display.c
index ae66a0cfcb8e..2bdf5be44c2c 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1681,76 +1681,19 @@ meta_display_notify_window_created (MetaDisplay *display,
g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window);
}
-static void
-root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
- float best_scale,
- int x,
- int y,
- MetaDisplay *display)
-{
- MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
- MetaBackend *backend = backend_from_display (display);
-
- if (meta_backend_is_stage_views_scaled (backend))
- {
- if (best_scale != 0.0f)
- {
- float ceiled_scale;
- int cursor_width, cursor_height;
-
- ceiled_scale = ceilf (best_scale);
- meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
- (int) ceiled_scale);
-
- meta_cursor_sprite_realize_texture (cursor_sprite);
- meta_cursor_sprite_xcursor_get_scaled_image_size (sprite_xcursor,
- &cursor_width,
- &cursor_height);
- meta_cursor_sprite_set_viewport_dst_size (cursor_sprite,
- cursor_width,
- cursor_height);
- }
- }
- else
- {
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaLogicalMonitor *logical_monitor;
-
- logical_monitor =
- meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
-
- /* Reload the cursor texture if the scale has changed. */
- if (logical_monitor)
- {
- meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
- (int) logical_monitor->scale);
- meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0f);
- }
- }
-}
-
-static void
-manage_root_cursor_sprite_scale (MetaDisplay *display,
- MetaCursorSpriteXcursor *sprite_xcursor)
-{
- meta_cursor_sprite_set_prepare_func (META_CURSOR_SPRITE (sprite_xcursor),
- (MetaCursorPrepareFunc) root_cursor_prepare_at,
- display);
-}
-
void
meta_display_reload_cursor (MetaDisplay *display)
{
MetaCursor cursor = display->current_cursor;
MetaCursorSpriteXcursor *sprite_xcursor;
MetaBackend *backend = backend_from_display (display);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor, cursor_tracker);
- if (meta_is_wayland_compositor ())
- manage_root_cursor_sprite_scale (display, sprite_xcursor);
+ if (!meta_is_wayland_compositor ())
+ meta_cursor_sprite_set_prepare_func (META_CURSOR_SPRITE (sprite_xcursor),
+ NULL, NULL);
meta_cursor_tracker_set_root_cursor (cursor_tracker,
META_CURSOR_SPRITE (sprite_xcursor));
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
index 86523918ba34..8306babf0cf3 100644
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ b/src/wayland/meta-wayland-tablet-tool.c
@@ -32,7 +32,6 @@
#include "wayland/meta-wayland-tablet.h"
#include "wayland/meta-wayland-tablet-seat.h"
#include "backends/meta-input-settings-private.h"
-#include "backends/meta-logical-monitor.h"
#include "tablet-unstable-v2-server-protocol.h"
@@ -425,87 +424,49 @@ tablet_tool_handle_cursor_surface_destroy (struct wl_listener *listener,
meta_wayland_tablet_tool_set_cursor_surface (tool, NULL);
}
-static void
-tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
- float best_scale,
- int x,
- int y,
- MetaWaylandTabletTool *tool)
-{
- MetaBackend *backend = backend_from_tool (tool);
- MetaMonitorManager *monitor_manager =
- meta_backend_get_monitor_manager (backend);
- MetaLogicalMonitor *logical_monitor;
-
- logical_monitor =
- meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
-
- /* Reload the cursor texture if the scale has changed. */
- if (logical_monitor)
- {
- MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
- float ceiled_scale;
-
- ceiled_scale = ceilf (logical_monitor->scale);
- meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
- (int) ceiled_scale);
-
- if (meta_backend_is_stage_views_scaled (backend))
- meta_cursor_sprite_set_texture_scale (cursor_sprite,
- 1.0f / ceiled_scale);
- else
- meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0f);
- }
-}
-
MetaWaylandTabletTool *
meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat,
ClutterInputDeviceTool *device_tool)
{
MetaWaylandCompositor *compositor =
meta_wayland_seat_get_compositor (seat->seat);
MetaContext *context = meta_wayland_compositor_get_context (compositor);
MetaBackend *backend = meta_context_get_backend (context);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
MetaWaylandTabletTool *tool;
tool = g_new0 (MetaWaylandTabletTool, 1);
tool->seat = seat;
tool->device_tool = device_tool;
wl_list_init (&tool->resource_list);
wl_list_init (&tool->focus_resource_list);
tool->focus_surface_destroy_listener.notify = tablet_tool_handle_focus_surface_destroy;
tool->cursor_surface_destroy_listener.notify = tablet_tool_handle_cursor_surface_destroy;
tool->default_sprite = meta_cursor_sprite_xcursor_new (META_CURSOR_DEFAULT,
cursor_tracker);
- meta_cursor_sprite_set_prepare_func (META_CURSOR_SPRITE (tool->default_sprite),
- (MetaCursorPrepareFunc) tool_cursor_prepare_at,
- tool);
return tool;
}
void
meta_wayland_tablet_tool_free (MetaWaylandTabletTool *tool)
{
struct wl_resource *resource, *next;
meta_wayland_tablet_tool_set_current_surface (tool, NULL);
meta_wayland_tablet_tool_set_focus (tool, NULL, NULL);
meta_wayland_tablet_tool_set_cursor_surface (tool, NULL);
g_clear_object (&tool->cursor_renderer);
wl_resource_for_each_safe (resource, next, &tool->resource_list)
{
zwp_tablet_tool_v2_send_removed (resource);
wl_list_remove (wl_resource_get_link (resource));
wl_list_init (wl_resource_get_link (resource));
}
- meta_cursor_sprite_set_prepare_func (META_CURSOR_SPRITE (tool->default_sprite),
- NULL, NULL);
g_object_unref (tool->default_sprite);
g_free (tool);