1
0
Fork 0

clutter: Add API to create inactive ClutterGrabs, and activate them explicitly

This gives greater control to the callers on the place where a grab is being
activated, this may make a difference in the handling of crossing events
triggered through it, e.g. by having callers rely on having already obtained
a ClutterGrab prior to handling the resulting effects.

The "input only" grab has also been turned inactive by default, in order to
to have the ClutterGrab pointer available for checks at the MetaWaylandEventHandler
focus changing methods triggered through grab activation.

(cherry-picked from commit 8e5f3a1f83)

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3874>
This commit is contained in:
Carlos Garnacho 2024-05-11 11:59:13 +02:00
parent 0ffc27ad5c
commit 827c4fea4b
4 changed files with 45 additions and 14 deletions

View file

@ -151,4 +151,11 @@ ClutterActor * clutter_stage_update_device_for_event (ClutterStage *stage,
void clutter_stage_update_devices_in_view (ClutterStage *stage, void clutter_stage_update_devices_in_view (ClutterStage *stage,
ClutterStageView *view); ClutterStageView *view);
CLUTTER_EXPORT
ClutterGrab * clutter_stage_grab_inactive (ClutterStage *stage,
ClutterActor *actor);
CLUTTER_EXPORT
void clutter_grab_activate (ClutterGrab *grab);
G_END_DECLS G_END_DECLS

View file

@ -3830,18 +3830,31 @@ clutter_stage_grab_full (ClutterStage *stage,
ClutterActor *actor, ClutterActor *actor,
gboolean owns_actor) gboolean owns_actor)
{ {
ClutterStagePrivate *priv;
ClutterGrab *grab;
gboolean was_grabbed;
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
g_return_val_if_fail (stage == g_return_val_if_fail (stage ==
(ClutterStage *) _clutter_actor_get_stage_internal (actor), (ClutterStage *) _clutter_actor_get_stage_internal (actor),
NULL); NULL);
return clutter_grab_new (stage, actor, owns_actor);
}
void
clutter_grab_activate (ClutterGrab *grab)
{
ClutterStage *stage;
ClutterStagePrivate *priv;
gboolean was_grabbed;
g_return_if_fail (CLUTTER_IS_GRAB (grab));
stage = grab->stage;
priv = clutter_stage_get_instance_private (stage); priv = clutter_stage_get_instance_private (stage);
/* This grab is already active */
if (grab->prev || grab->next || priv->topmost_grab == grab)
return;
if (!priv->topmost_grab) if (!priv->topmost_grab)
{ {
ClutterContext *context; ClutterContext *context;
@ -3854,8 +3867,6 @@ clutter_stage_grab_full (ClutterStage *stage,
clutter_seat_grab (seat, clutter_get_current_event_time ()); clutter_seat_grab (seat, clutter_get_current_event_time ());
} }
grab = clutter_grab_new (stage, actor, owns_actor);
grab->prev = NULL; grab->prev = NULL;
grab->next = priv->topmost_grab; grab->next = priv->topmost_grab;
@ -3876,10 +3887,10 @@ clutter_stage_grab_full (ClutterStage *stage,
CLUTTER_NOTE (GRABS, CLUTTER_NOTE (GRABS,
"[grab=%p] Attached seat grab (n_grabs: %u) on actor: %s", "[grab=%p] Attached seat grab (n_grabs: %u) on actor: %s",
grab, n_grabs, _clutter_actor_get_debug_name (actor)); grab, n_grabs, _clutter_actor_get_debug_name (grab->actor));
} }
clutter_actor_attach_grab (actor, grab); clutter_actor_attach_grab (grab->actor, grab);
clutter_stage_notify_grab (stage, grab, grab->next); clutter_stage_notify_grab (stage, grab, grab->next);
if (was_grabbed != !!priv->topmost_grab) if (was_grabbed != !!priv->topmost_grab)
@ -3887,8 +3898,6 @@ clutter_stage_grab_full (ClutterStage *stage,
if (grab->next) if (grab->next)
clutter_grab_notify (grab->next); clutter_grab_notify (grab->next);
return grab;
} }
/** /**
@ -3905,6 +3914,18 @@ clutter_stage_grab_full (ClutterStage *stage,
ClutterGrab * ClutterGrab *
clutter_stage_grab (ClutterStage *stage, clutter_stage_grab (ClutterStage *stage,
ClutterActor *actor) ClutterActor *actor)
{
ClutterGrab *grab;
grab = clutter_stage_grab_full (stage, actor, FALSE);
clutter_grab_activate (grab);
return grab;
}
ClutterGrab *
clutter_stage_grab_inactive (ClutterStage *stage,
ClutterActor *actor)
{ {
return clutter_stage_grab_full (stage, actor, FALSE); return clutter_stage_grab_full (stage, actor, FALSE);
} }

View file

@ -628,6 +628,7 @@ grab_input_only (void)
grab = clutter_stage_grab_input_only (CLUTTER_STAGE (data.stage), grab = clutter_stage_grab_input_only (CLUTTER_STAGE (data.stage),
handle_input_only_event, handle_input_only_event,
data.events, NULL); data.events, NULL);
clutter_grab_activate (grab);
event_log_compare ((EventLog *) &grab1_log, data.events); event_log_compare ((EventLog *) &grab1_log, data.events);
clutter_virtual_input_device_notify_button (pointer, clutter_virtual_input_device_notify_button (pointer,

View file

@ -303,6 +303,8 @@ meta_wayland_input_attach_event_handler (MetaWaylandInput *input,
grab_handle_event, grab_handle_event,
input, input,
NULL); NULL);
clutter_grab_activate (input->grab);
g_signal_connect_swapped (input->grab, "notify::revoked", g_signal_connect_swapped (input->grab, "notify::revoked",
G_CALLBACK (on_grab_revocation_change), G_CALLBACK (on_grab_revocation_change),
input); input);