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. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3463 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3747>
This commit is contained in:
parent
5ba364a947
commit
8e5f3a1f83
5 changed files with 69 additions and 14 deletions
|
@ -36,6 +36,9 @@
|
|||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterGrab, clutter_grab, CLUTTER, GRAB, GObject)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_grab_activate (ClutterGrab *grab);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_grab_dismiss (ClutterGrab *grab);
|
||||
|
||||
|
|
|
@ -3834,18 +3834,45 @@ clutter_stage_grab_full (ClutterStage *stage,
|
|||
ClutterActor *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_ACTOR (actor), NULL);
|
||||
g_return_val_if_fail (stage ==
|
||||
(ClutterStage *) _clutter_actor_get_stage_internal (actor),
|
||||
NULL);
|
||||
|
||||
return clutter_grab_new (stage, actor, owns_actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_grab_activate:
|
||||
* @grab: a `ClutterGrab`
|
||||
*
|
||||
* Activates a grab onto its assigned actor. Events will be propagated as
|
||||
* usual inside its hierarchy. Activating an already active grab will have
|
||||
* no side effects.
|
||||
*
|
||||
* This method is necessary for grabs obtained through
|
||||
* [method@Stage.grab_inactive]. Grabs obtained through [method@Stage.grab]
|
||||
* will be activated implicitly.
|
||||
*
|
||||
* to undo the effects of this function, call [method@Grab.dismiss].
|
||||
**/
|
||||
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);
|
||||
|
||||
/* This grab is already active */
|
||||
if (grab->prev || grab->next || priv->topmost_grab == grab)
|
||||
return;
|
||||
|
||||
if (!priv->topmost_grab)
|
||||
{
|
||||
ClutterContext *context;
|
||||
|
@ -3858,8 +3885,6 @@ clutter_stage_grab_full (ClutterStage *stage,
|
|||
clutter_seat_grab (seat, clutter_get_current_event_time ());
|
||||
}
|
||||
|
||||
grab = clutter_grab_new (stage, actor, owns_actor);
|
||||
|
||||
grab->prev = NULL;
|
||||
grab->next = priv->topmost_grab;
|
||||
|
||||
|
@ -3880,10 +3905,10 @@ clutter_stage_grab_full (ClutterStage *stage,
|
|||
|
||||
CLUTTER_NOTE (GRABS,
|
||||
"[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);
|
||||
|
||||
if (was_grabbed != !!priv->topmost_grab)
|
||||
|
@ -3891,8 +3916,6 @@ clutter_stage_grab_full (ClutterStage *stage,
|
|||
|
||||
if (grab->next)
|
||||
clutter_grab_notify (grab->next);
|
||||
|
||||
return grab;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3909,15 +3932,37 @@ clutter_stage_grab_full (ClutterStage *stage,
|
|||
ClutterGrab *
|
||||
clutter_stage_grab (ClutterStage *stage,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterGrab *grab;
|
||||
|
||||
grab = clutter_stage_grab_full (stage, actor, FALSE);
|
||||
clutter_grab_activate (grab);
|
||||
|
||||
return grab;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_grab_inactive:
|
||||
* @stage: The #ClutterStage
|
||||
* @actor: The actor that will grab input
|
||||
*
|
||||
* Creates an inactive grab. The grab will become effective
|
||||
* after [method@Grab.activate].
|
||||
*
|
||||
* Returns: (transfer full): an opaque #ClutterGrab handle
|
||||
**/
|
||||
ClutterGrab *
|
||||
clutter_stage_grab_inactive (ClutterStage *stage,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
return clutter_stage_grab_full (stage, actor, FALSE);
|
||||
}
|
||||
|
||||
ClutterGrab *
|
||||
clutter_stage_grab_input_only (ClutterStage *stage,
|
||||
ClutterEventHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_destroy)
|
||||
clutter_stage_grab_input_only (ClutterStage *stage,
|
||||
ClutterEventHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_destroy)
|
||||
{
|
||||
ClutterInputOnlyActor *input_only_actor;
|
||||
ClutterActor *actor;
|
||||
|
|
|
@ -223,6 +223,10 @@ CLUTTER_EXPORT
|
|||
ClutterGrab * clutter_stage_grab (ClutterStage *stage,
|
||||
ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterGrab * clutter_stage_grab_inactive (ClutterStage *stage,
|
||||
ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_stage_get_grab_actor (ClutterStage *stage);
|
||||
|
||||
|
|
|
@ -628,6 +628,7 @@ grab_input_only (void)
|
|||
grab = clutter_stage_grab_input_only (CLUTTER_STAGE (data.stage),
|
||||
handle_input_only_event,
|
||||
data.events, NULL);
|
||||
clutter_grab_activate (grab);
|
||||
event_log_compare ((EventLog *) &grab1_log, data.events);
|
||||
|
||||
clutter_virtual_input_device_notify_button (pointer,
|
||||
|
|
|
@ -303,6 +303,8 @@ meta_wayland_input_attach_event_handler (MetaWaylandInput *input,
|
|||
grab_handle_event,
|
||||
input,
|
||||
NULL);
|
||||
clutter_grab_activate (input->grab);
|
||||
|
||||
g_signal_connect_swapped (input->grab, "notify::revoked",
|
||||
G_CALLBACK (on_grab_revocation_change),
|
||||
input);
|
||||
|
|
Loading…
Add table
Reference in a new issue