clutter: Always unregister point on GRAB_NOTIFY leave event

The ClutterGestureAction base code would correctly try to cancel a
gesture if it would receive GRAB_NOTIFY leave events (that would indicate
other portions of the actor tree stole input away from the gesture actor),
but it would mistakenly do so only if the gesture was already initiated,
possibly leaving stale point information if the gesture collected input
but didn't initiate yet.

This could be indirectly seen clicking with the mouse on OSK keys with
no motions in between, clicks would accumulate on the swipeTracker
gestures until the trigger point, so the third click could drag the
workspaces.

We do always want to unregister the related device/sequence here, do that
while still cancelling any already initiated gesture.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1907
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4987
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2334>
This commit is contained in:
Carlos Garnacho 2022-03-09 23:00:40 +01:00 committed by Marge Bot
parent 5c5e30638d
commit 58bcd30ee6

View File

@ -380,12 +380,15 @@ clutter_gesture_action_handle_event (ClutterAction *action,
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
} }
if (priv->in_gesture && point && if (point &&
event_type == CLUTTER_LEAVE && event_type == CLUTTER_LEAVE &&
(event->crossing.flags & CLUTTER_EVENT_FLAG_GRAB_NOTIFY) != 0) (event->crossing.flags & CLUTTER_EVENT_FLAG_GRAB_NOTIFY) != 0)
{ {
priv->in_gesture = FALSE; gesture_unregister_point (gesture_action, position);
cancel_gesture (gesture_action);
if (priv->in_gesture)
cancel_gesture (gesture_action);
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
} }