clutter: Move ClutterGestureAction to the handle_event vfunc
This will not try the captured-event shenanigans to emulate grab behavior, instead relying on event delivery being influenced by other grab mechanisms. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2024>
This commit is contained in:
parent
5133815cc1
commit
6d0b7381da
@ -118,9 +118,6 @@ struct _ClutterGestureActionPrivate
|
||||
gint requested_nb_points;
|
||||
GArray *points;
|
||||
|
||||
gulong actor_capture_id;
|
||||
gulong stage_capture_id;
|
||||
|
||||
ClutterGestureTriggerEdge edge;
|
||||
float distance_x, distance_y;
|
||||
|
||||
@ -155,7 +152,8 @@ static guint gesture_signals[LAST_SIGNAL] = { 0, };
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterGestureAction, clutter_gesture_action, CLUTTER_TYPE_ACTION)
|
||||
|
||||
static GesturePoint *
|
||||
gesture_register_point (ClutterGestureAction *action, ClutterEvent *event)
|
||||
gesture_register_point (ClutterGestureAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
@ -188,8 +186,8 @@ gesture_register_point (ClutterGestureAction *action, ClutterEvent *event)
|
||||
|
||||
static GesturePoint *
|
||||
gesture_find_point (ClutterGestureAction *action,
|
||||
ClutterEvent *event,
|
||||
gint *position)
|
||||
const ClutterEvent *event,
|
||||
int *position)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
@ -232,8 +230,8 @@ gesture_unregister_point (ClutterGestureAction *action, gint position)
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_update_motion_point (GesturePoint *point,
|
||||
ClutterEvent *event)
|
||||
gesture_update_motion_point (GesturePoint *point,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
gfloat motion_x, motion_y;
|
||||
gint64 _time;
|
||||
@ -254,8 +252,8 @@ gesture_update_motion_point (GesturePoint *point,
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_update_release_point (GesturePoint *point,
|
||||
ClutterEvent *event)
|
||||
gesture_update_release_point (GesturePoint *point,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
gint64 _time;
|
||||
|
||||
@ -283,7 +281,7 @@ gesture_get_default_threshold (void)
|
||||
static gboolean
|
||||
gesture_point_pass_threshold (ClutterGestureAction *action,
|
||||
GesturePoint *point,
|
||||
ClutterEvent *event)
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
float threshold_x, threshold_y;
|
||||
gfloat motion_x, motion_y;
|
||||
@ -312,8 +310,6 @@ cancel_gesture (ClutterGestureAction *action)
|
||||
|
||||
priv->in_gesture = FALSE;
|
||||
|
||||
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor);
|
||||
|
||||
@ -354,34 +350,50 @@ begin_gesture (ClutterGestureAction *action,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stage_captured_event_cb (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterGestureAction *action)
|
||||
clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (action);
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
clutter_gesture_action_get_instance_private (gesture_action);
|
||||
ClutterActor *actor =
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
gint position;
|
||||
float threshold_x, threshold_y;
|
||||
gboolean return_value;
|
||||
GesturePoint *point;
|
||||
ClutterEventType event_type;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
event_type = clutter_event_type (event);
|
||||
if (event_type != CLUTTER_TOUCH_CANCEL &&
|
||||
event_type != CLUTTER_TOUCH_UPDATE &&
|
||||
event_type != CLUTTER_TOUCH_END &&
|
||||
event_type != CLUTTER_MOTION &&
|
||||
event_type != CLUTTER_BUTTON_RELEASE)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if ((point = gesture_find_point (action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
if (event_type == CLUTTER_BUTTON_PRESS ||
|
||||
event_type == CLUTTER_TOUCH_BEGIN)
|
||||
{
|
||||
point = gesture_register_point (gesture_action, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((point = gesture_find_point (gesture_action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
/* Start the gesture immediately if the gesture has no
|
||||
* _TRIGGER_EDGE_AFTER drag threshold. */
|
||||
if ((priv->points->len >= priv->requested_nb_points) &&
|
||||
(priv->edge != CLUTTER_GESTURE_TRIGGER_EDGE_AFTER))
|
||||
begin_gesture (gesture_action, actor);
|
||||
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
{
|
||||
ClutterModifierType mods = clutter_event_get_state (event);
|
||||
@ -392,7 +404,7 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
*/
|
||||
if (!(mods & CLUTTER_BUTTON1_MASK))
|
||||
{
|
||||
cancel_gesture (action);
|
||||
cancel_gesture (gesture_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
}
|
||||
@ -410,7 +422,7 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
/* Wait until the drag threshold has been exceeded
|
||||
* before starting _TRIGGER_EDGE_AFTER gestures. */
|
||||
if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_AFTER &&
|
||||
gesture_point_pass_threshold (action, point, event))
|
||||
gesture_point_pass_threshold (gesture_action, point, event))
|
||||
{
|
||||
gesture_update_motion_point (point, event);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
@ -418,31 +430,33 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
|
||||
gesture_update_motion_point (point, event);
|
||||
|
||||
if (!begin_gesture (action, actor))
|
||||
if (!begin_gesture (gesture_action, actor))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if ((point = gesture_find_point (action, event, &position)) == NULL)
|
||||
if ((point = gesture_find_point (gesture_action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
gesture_update_motion_point (point, event);
|
||||
|
||||
g_signal_emit (action, gesture_signals[GESTURE_PROGRESS], 0, actor,
|
||||
g_signal_emit (gesture_action, gesture_signals[GESTURE_PROGRESS], 0, actor,
|
||||
&return_value);
|
||||
if (!return_value)
|
||||
{
|
||||
cancel_gesture (action);
|
||||
cancel_gesture (gesture_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
/* Check if a _TRIGGER_EDGE_BEFORE gesture needs to be cancelled because
|
||||
* the drag threshold has been exceeded. */
|
||||
clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y);
|
||||
clutter_gesture_action_get_threshold_trigger_distance (gesture_action,
|
||||
&threshold_x,
|
||||
&threshold_y);
|
||||
if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE &&
|
||||
((fabsf (point->press_y - point->last_motion_y) > threshold_y) ||
|
||||
(fabsf (point->press_x - point->last_motion_x) > threshold_x)))
|
||||
{
|
||||
cancel_gesture (action);
|
||||
cancel_gesture (gesture_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
break;
|
||||
@ -456,10 +470,10 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
((priv->points->len - 1) < priv->requested_nb_points))
|
||||
{
|
||||
priv->in_gesture = FALSE;
|
||||
g_signal_emit (action, gesture_signals[GESTURE_END], 0, actor);
|
||||
g_signal_emit (gesture_action, gesture_signals[GESTURE_END], 0, actor);
|
||||
}
|
||||
|
||||
gesture_unregister_point (action, position);
|
||||
gesture_unregister_point (gesture_action, position);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -470,10 +484,10 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
if (priv->in_gesture)
|
||||
{
|
||||
priv->in_gesture = FALSE;
|
||||
cancel_gesture (action);
|
||||
cancel_gesture (gesture_action);
|
||||
}
|
||||
|
||||
gesture_unregister_point (action, position);
|
||||
gesture_unregister_point (gesture_action, position);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -481,85 +495,9 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->points->len == 0)
|
||||
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
actor_captured_event_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
GesturePoint *point G_GNUC_UNUSED;
|
||||
|
||||
if ((clutter_event_type (event) != CLUTTER_BUTTON_PRESS) &&
|
||||
(clutter_event_type (event) != CLUTTER_TOUCH_BEGIN))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
point = gesture_register_point (action, event);
|
||||
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
if (priv->stage_capture_id == 0)
|
||||
priv->stage_capture_id =
|
||||
g_signal_connect_after (priv->stage, "captured-event",
|
||||
G_CALLBACK (stage_captured_event_cb),
|
||||
action);
|
||||
|
||||
/* Start the gesture immediately if the gesture has no
|
||||
* _TRIGGER_EDGE_AFTER drag threshold. */
|
||||
if ((priv->points->len >= priv->requested_nb_points) &&
|
||||
(priv->edge != CLUTTER_GESTURE_TRIGGER_EDGE_AFTER))
|
||||
begin_gesture (action, actor);
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_gesture_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (meta));
|
||||
ClutterActorMetaClass *meta_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
|
||||
|
||||
if (priv->actor_capture_id != 0)
|
||||
{
|
||||
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
|
||||
|
||||
if (old_actor != NULL)
|
||||
g_clear_signal_handler (&priv->actor_capture_id, old_actor);
|
||||
|
||||
priv->actor_capture_id = 0;
|
||||
}
|
||||
|
||||
if (priv->stage_capture_id != 0)
|
||||
{
|
||||
if (priv->stage != NULL)
|
||||
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
|
||||
|
||||
priv->stage_capture_id = 0;
|
||||
priv->stage = NULL;
|
||||
}
|
||||
|
||||
if (actor != NULL)
|
||||
{
|
||||
priv->actor_capture_id =
|
||||
g_signal_connect (actor, "captured-event",
|
||||
G_CALLBACK (actor_captured_event_cb),
|
||||
meta);
|
||||
}
|
||||
|
||||
meta_class->set_actor (meta, actor);
|
||||
return priv->in_gesture ?
|
||||
CLUTTER_EVENT_STOP :
|
||||
CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -683,14 +621,16 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = clutter_gesture_action_finalize;
|
||||
gobject_class->set_property = clutter_gesture_action_set_property;
|
||||
gobject_class->get_property = clutter_gesture_action_get_property;
|
||||
|
||||
meta_class->set_actor = clutter_gesture_action_set_actor;
|
||||
meta_class->set_enabled = clutter_gesture_action_set_enabled;
|
||||
|
||||
action_class->handle_event = clutter_gesture_action_handle_event;
|
||||
|
||||
klass->gesture_begin = default_event_handler;
|
||||
klass->gesture_progress = default_event_handler;
|
||||
klass->gesture_prepare = default_event_handler;
|
||||
|
Loading…
Reference in New Issue
Block a user