[mutter/wip/halfline/gesture-osk-fix] clutter-gester-action: Cancel gesture when a device gets grabbed
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/halfline/gesture-osk-fix] clutter-gester-action: Cancel gesture when a device gets grabbed
- Date: Thu, 7 Oct 2021 17:38:17 +0000 (UTC)
commit 57ffff35496f14d1712945dea83e7e3e0f74323b
Author: Ray Strode <rstrode redhat com>
Date: Wed Oct 6 22:03:46 2021 -0400
clutter-gester-action: Cancel gesture when a device gets grabbed
If an actor takes a grab on an input device, that's a good indicator
that the user expects input to be handled solely by the actor and
any gestures that are taking place aren't meant for the stage.
At the moment, the gesture code has no insight into when a grab
gets taken, though. If a grab does get taken it missed out on the
motion and button release events that have now been redirected to
the actor.
Those missed events can confuse the event processing code into thinking
the user is doing a multi-press gesture, when the user is actually just
e.g., doing a series of clicks.
This commit addresses the problem by installing an event filter that
can see the events before they're delivered to the grabbed actor.
The filter checkes if a device a grabbed, and if so cancels any
in-flight gestures that are currently getting processed.
clutter/clutter/clutter-gesture-action.c | 54 +++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 19 deletions(-)
---
diff --git a/clutter/clutter/clutter-gesture-action.c b/clutter/clutter/clutter-gesture-action.c
index f938a549aa..008668f976 100644
--- a/clutter/clutter/clutter-gesture-action.c
+++ b/clutter/clutter/clutter-gesture-action.c
@@ -120,6 +120,7 @@ struct _ClutterGestureActionPrivate
gulong actor_capture_id;
gulong stage_capture_id;
+ guint event_filter_id;
ClutterGestureTriggerEdge edge;
float distance_x, distance_y;
@@ -312,6 +313,7 @@ cancel_gesture (ClutterGestureAction *action)
priv->in_gesture = FALSE;
+ g_clear_handle_id (&priv->event_filter_id, clutter_event_remove_filter);
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
@@ -353,6 +355,26 @@ begin_gesture (ClutterGestureAction *action,
return TRUE;
}
+static gboolean
+event_filter_cb (const ClutterEvent *event,
+ ClutterGestureAction *action)
+{
+ ClutterInputDevice *device = NULL;
+ ClutterActor *grabbed_actor;
+
+ device = clutter_event_get_device (event);
+
+ if (device == NULL)
+ return CLUTTER_EVENT_PROPAGATE;
+
+ grabbed_actor = clutter_input_device_get_grabbed_actor (device);
+
+ if (grabbed_actor != NULL)
+ cancel_gesture (action);
+
+ return CLUTTER_EVENT_PROPAGATE;
+}
+
static gboolean
stage_captured_event_cb (ClutterActor *stage,
ClutterEvent *event,
@@ -383,21 +405,7 @@ stage_captured_event_cb (ClutterActor *stage,
switch (clutter_event_type (event))
{
case CLUTTER_MOTION:
- {
- ClutterModifierType mods = clutter_event_get_state (event);
-
- /* we might miss a button-release event in case of grabs,
- * so we need to check whether the button is still down
- * during a motion event
- */
- if (!(mods & CLUTTER_BUTTON1_MASK))
- {
- cancel_gesture (action);
- return CLUTTER_EVENT_PROPAGATE;
- }
- }
/* Follow same code path as a touch event update */
-
case CLUTTER_TOUCH_UPDATE:
if (!priv->in_gesture)
{
@@ -482,7 +490,10 @@ stage_captured_event_cb (ClutterActor *stage,
}
if (priv->points->len == 0)
- g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
+ {
+ g_clear_handle_id (&priv->event_filter_id, clutter_event_remove_filter);
+ g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
+ }
return CLUTTER_EVENT_PROPAGATE;
}
@@ -508,6 +519,12 @@ actor_captured_event_cb (ClutterActor *actor,
if (priv->stage == NULL)
priv->stage = clutter_actor_get_stage (actor);
+ if (priv->event_filter_id == 0)
+ priv->event_filter_id = clutter_event_add_filter (priv->stage,
+ (ClutterEventFilterFunc) event_filter_cb,
+ NULL,
+ action);
+
if (priv->stage_capture_id == 0)
priv->stage_capture_id =
g_signal_connect_after (priv->stage, "captured-event",
@@ -542,12 +559,11 @@ clutter_gesture_action_set_actor (ClutterActorMeta *meta,
priv->actor_capture_id = 0;
}
- if (priv->stage_capture_id != 0)
+ if (priv->stage != NULL)
{
- if (priv->stage != NULL)
- g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
+ g_clear_handle_id (&priv->event_filter_id, clutter_event_remove_filter);
+ g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
- priv->stage_capture_id = 0;
priv->stage = NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]