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:
parent
848612b08f
commit
1cb46f203c
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
g_clear_pointer (&window_drag->handler, clutter_actor_destroy);
|
||||
g_clear_object (&window_drag->grab);
|
||||
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);
|
||||
|
||||
clutter_grab_dismiss (window_drag->grab);
|
||||
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,26 +1861,39 @@ meta_window_drag_begin (MetaWindowDrag *window_drag,
|
||||
|
||||
stage = meta_backend_get_stage (backend);
|
||||
|
||||
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");
|
||||
g_signal_connect_swapped (window_drag->handler, "event",
|
||||
G_CALLBACK (on_window_drag_event), window_drag);
|
||||
clutter_actor_add_child (stage, window_drag->handler);
|
||||
|
||||
window_drag->grab = clutter_stage_grab (CLUTTER_STAGE (stage),
|
||||
window_drag->handler);
|
||||
|
||||
if ((clutter_grab_get_seat_state (window_drag->grab) &
|
||||
CLUTTER_GRAB_STATE_POINTER) == 0 &&
|
||||
!meta_grab_op_is_keyboard (grab_op))
|
||||
if (grab_actor)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Pointer grab failed on a pointer grab op");
|
||||
return FALSE;
|
||||
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);
|
||||
|
||||
window_drag->grab = clutter_stage_grab (CLUTTER_STAGE (stage),
|
||||
window_drag->handler);
|
||||
|
||||
if ((clutter_grab_get_seat_state (window_drag->grab) &
|
||||
CLUTTER_GRAB_STATE_POINTER) == 0 &&
|
||||
!meta_grab_op_is_keyboard (grab_op))
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Pointer grab failed on a pointer grab op");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporarily release the passive key grabs on the window */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -6149,7 +6149,7 @@ meta_window_begin_grab_op (MetaWindow *window,
|
||||
window, op,
|
||||
device, sequence,
|
||||
timestamp,
|
||||
pos_hint);
|
||||
pos_hint, NULL);
|
||||
}
|
||||
|
||||
MetaStackLayer
|
||||
|
Loading…
x
Reference in New Issue
Block a user