wayland/xdg-toplevel-drag: Support non-grabbing mode in MetaWindowDrag

- This adds a new ClutterActor parameter to meta_compositor_drag_window
  and meta_window_drag_begin such that it's possible to inject an
  external grab actor, which is then used to implement a "non-grabbing"
  mode that allow a MetaWindowDrag to be used in conjunction, for
  example, with a Wayland drag-and-drop session;
- This new API is going to be used to implement the toplevel drag
  protocol in a subsequent commit.

Signed-off-by: Nick Diego Yamane <nickdiego@igalia.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4107>
This commit is contained in:
Nick Diego Yamane 2024-11-21 10:53:11 -03:00
parent 848612b08f
commit 1cb46f203c
5 changed files with 61 additions and 28 deletions

View File

@ -79,7 +79,8 @@ gboolean meta_compositor_drag_window (MetaCompositor *compositor,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
uint32_t timestamp,
graphene_point_t *pos_hint);
graphene_point_t *pos_hint,
ClutterActor *grab_actor);
MetaWindowDrag * meta_compositor_get_current_window_drag (MetaCompositor *compositor);

View File

@ -1587,7 +1587,8 @@ meta_compositor_drag_window (MetaCompositor *compositor,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
uint32_t timestamp,
graphene_point_t *pos_hint)
graphene_point_t *pos_hint,
ClutterActor *grab_actor)
{
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
@ -1603,7 +1604,8 @@ meta_compositor_drag_window (MetaCompositor *compositor,
priv->current_drag = g_steal_pointer (&window_drag);
if (!meta_window_drag_begin (priv->current_drag, device, sequence, timestamp))
if (!meta_window_drag_begin (priv->current_drag, device,
sequence, timestamp, grab_actor))
{
g_clear_object (&priv->current_drag);
return FALSE;

View File

@ -79,6 +79,7 @@ struct _MetaWindowDrag {
gulong unmanaged_id;
gulong size_changed_id;
gulong event_handler_id;
guint tile_preview_timeout_id;
guint preview_tile_mode : 2;
@ -175,14 +176,24 @@ hide_tile_preview (MetaWindowDrag *window_drag)
meta_compositor_hide_tile_preview (window->display->compositor);
}
static gboolean
owns_grab_actor (MetaWindowDrag *window_drag)
{
g_assert (META_IS_WINDOW_DRAG (window_drag));
return window_drag->grab != NULL;
}
static void
meta_window_drag_finalize (GObject *object)
{
MetaWindowDrag *window_drag = META_WINDOW_DRAG (object);
hide_tile_preview (window_drag);
if (owns_grab_actor (window_drag))
{
g_clear_pointer (&window_drag->handler, clutter_actor_destroy);
g_clear_object (&window_drag->grab);
}
g_clear_object (&window_drag->effective_grab_window);
G_OBJECT_CLASS (meta_window_drag_parent_class)->finalize (object);
@ -387,7 +398,11 @@ meta_window_drag_end (MetaWindowDrag *window_drag)
meta_window_grab_op_ended (grab_window, grab_op);
if (owns_grab_actor (window_drag))
clutter_grab_dismiss (window_drag->grab);
else
g_clear_signal_handler (&window_drag->event_handler_id,
window_drag->handler);
g_clear_signal_handler (&window_drag->unmanaged_id, grab_window);
g_clear_signal_handler (&window_drag->size_changed_id, grab_window);
@ -1780,7 +1795,8 @@ gboolean
meta_window_drag_begin (MetaWindowDrag *window_drag,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
uint32_t timestamp)
uint32_t timestamp,
ClutterActor *grab_actor)
{
MetaWindow *window = window_drag->window, *grab_window = NULL;
MetaDisplay *display = meta_window_get_display (window);
@ -1845,12 +1861,24 @@ meta_window_drag_begin (MetaWindowDrag *window_drag,
stage = meta_backend_get_stage (backend);
if (grab_actor)
{
meta_topic (META_DEBUG_WINDOW_OPS, "Reusing grab actor %p.", grab_actor);
window_drag->handler = grab_actor;
window_drag->event_handler_id =
g_signal_connect_swapped (window_drag->handler, "event",
G_CALLBACK (on_window_drag_event), window_drag);
}
else
{
meta_topic (META_DEBUG_WINDOW_OPS, "Creating a new grab.");
window_drag->handler = clutter_actor_new ();
clutter_actor_hide (window_drag->handler);
clutter_actor_set_name (window_drag->handler,
"Window drag helper");
clutter_actor_set_accessible_name (window_drag->handler,
"Window drag helper");
window_drag->event_handler_id =
g_signal_connect_swapped (window_drag->handler, "event",
G_CALLBACK (on_window_drag_event), window_drag);
clutter_actor_add_child (stage, window_drag->handler);
@ -1866,6 +1894,7 @@ meta_window_drag_begin (MetaWindowDrag *window_drag,
"Pointer grab failed on a pointer grab op");
return FALSE;
}
}
/* Temporarily release the passive key grabs on the window */
#ifdef HAVE_X11

View File

@ -32,7 +32,8 @@ MetaWindowDrag * meta_window_drag_new (MetaWindow *window,
gboolean meta_window_drag_begin (MetaWindowDrag *drag,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
uint32_t timestamp);
uint32_t timestamp,
ClutterActor *grab_actor);
void meta_window_drag_end (MetaWindowDrag *drag);

View File

@ -6149,7 +6149,7 @@ meta_window_begin_grab_op (MetaWindow *window,
window, op,
device, sequence,
timestamp,
pos_hint);
pos_hint, NULL);
}
MetaStackLayer