wayland: Take over cursor feedback during DnD

The original strategy to let the drag source client be in
charge of pointer cursor feedback during DnD has gotten
way too complex, with tablets and tools, toplevel drags,
and now the cursor shape protocol.

Instead, let the compositor be in charge of pointer cursor
feedback during DnD operation, it will know right away the
cursor renderer to update, and the appropriate feedback
through the current DnD action.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4368>
This commit is contained in:
Carlos Garnacho 2025-03-26 11:28:03 +01:00 committed by Bruce Leidl
parent 73cab206d7
commit ce698b9a87
2 changed files with 75 additions and 13 deletions

View File

@ -218,21 +218,88 @@ on_drag_focus_destroyed (MetaWaylandSurface *surface,
grab->drag_focus = NULL;
}
static void
meta_wayland_drag_grab_set_cursor (MetaWaylandDragGrab *drag_grab,
MetaCursor cursor)
{
MetaWaylandCompositor *compositor =
meta_wayland_seat_get_compositor (drag_grab->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);
g_autoptr (MetaCursorSprite) cursor_sprite = NULL;
MetaCursorRenderer *cursor_renderer;
cursor_sprite =
META_CURSOR_SPRITE (meta_cursor_sprite_xcursor_new (cursor, cursor_tracker));
cursor_renderer =
meta_backend_get_cursor_renderer_for_device (backend, drag_grab->device);
if (cursor_renderer && cursor_sprite)
meta_cursor_renderer_set_cursor (cursor_renderer, cursor_sprite);
}
static void
meta_wayland_drag_grab_update_cursor (MetaWaylandDragGrab *drag_grab)
{
enum wl_data_device_manager_dnd_action action =
meta_wayland_data_source_get_current_action (drag_grab->drag_data_source);
MetaCursor cursor = META_CURSOR_DEFAULT;
switch (action)
{
case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
cursor = META_CURSOR_NOT_ALLOWED;
break;
case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
cursor = META_CURSOR_MOVE;
break;
case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
cursor = META_CURSOR_COPY;
break;
case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
cursor = META_CURSOR_DND_ASK;
break;
default:
break;
}
meta_wayland_drag_grab_set_cursor (drag_grab, cursor);
}
static void
on_data_source_action_changed (MetaWaylandDataSource *source,
MetaWaylandDragGrab *drag_grab)
{
meta_wayland_drag_grab_update_cursor (drag_grab);
}
static void
meta_wayland_drag_grab_set_source (MetaWaylandDragGrab *drag_grab,
MetaWaylandDataSource *source)
{
if (drag_grab->drag_data_source)
g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
drag_grab_data_source_destroyed,
drag_grab);
{
g_signal_handlers_disconnect_by_func (drag_grab->drag_data_source,
on_data_source_action_changed,
drag_grab);
g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
drag_grab_data_source_destroyed,
drag_grab);
}
drag_grab->drag_data_source = source;
if (source)
g_object_weak_ref (G_OBJECT (source),
drag_grab_data_source_destroyed,
drag_grab);
{
g_signal_connect (drag_grab->drag_data_source, "action-changed",
G_CALLBACK (on_data_source_action_changed),
drag_grab);
g_object_weak_ref (G_OBJECT (source),
drag_grab_data_source_destroyed,
drag_grab);
}
}
static void
@ -411,6 +478,7 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
drag_grab->handler = NULL;
}
meta_wayland_drag_grab_set_cursor (drag_grab, META_CURSOR_DEFAULT);
meta_dnd_wayland_handle_end_modal (compositor);
g_free (drag_grab);

View File

@ -1141,15 +1141,9 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
{
MetaBackend *backend = backend_from_pointer (pointer);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer);
MetaWaylandDragGrab *drag_grab;
MetaWaylandSurface *surface;
drag_grab = meta_wayland_data_device_get_current_grab (&seat->data_device);
if (drag_grab)
surface = meta_wayland_drag_grab_get_origin (drag_grab);
else
surface = pointer->focus_surface;
surface = pointer->focus_surface;
if (surface)
{