Skip to content

WIP: Refactor ClutterGestureAction and meta-gesture-tracker

Jonas Dreßler requested to merge verdre/mutter:gesture-action-fixes into master

Commit message of 516a1643:

The current architecture of gesture tracking that depends on event delivery using the traditional capture-bubble mechanism has a few problems:

  • Mutter needs to know about recognized gestures very early so it's able to block event delivery without leaking events to windows or other Clutter actors. This is impossible if we wait for the event to reach the gesture actor, because the event processing code in Mutter notifies Wayland clients before Clutter actors, so the first event of a gesture will always be leaked.

  • Touch-sequence grabs also bypass the normal event delivery, which causes the gesture actor to not get notified about events anymore. This can lead to gestures being "stuck" in the recognition phase.

  • There's no concept of tracking the gesture state other than "priv->in_gesture". This doesn't allow for features like blocking events that belong to gesture-points after the gesture has ended or a proper cancelled state that disallows restarting the gesture during the same user interaction.

Refactor ClutterGestureAction to fix those issues and make the class much more flexible:

  • Implement a new clutter_gesture_action_eval_event() method we can call directly from Mutter inside its event filter. This function will process the event to update the gesture and return CLUTTER_EVENT_STOP if a gesture was recognized.

  • For non-global, actor specific gestures, grab the touch sequences and pointer device the whole time until the finger is lifted or the button is released. To make sure we don't get into situations where touch events or mouse might not be delivered to us anymore (like interacting with a window on x11), reset the gesture on every change of the "mapped" property of the actor. Since grabs only send events to one actor instead of bubbling, propagating an event in non-stage gestures won't really do anything for now.

  • Instead of removing the list of points after a gesture is cancelled, always keep track of the points to allow detecting that all touches or buttons have been released.

  • Use four self-explaining states to save the current state of the gesture: Waiting, recognized, ended and cancelled. Gestures always get reset to the "waiting" state after all touchpoints and buttons have been released.


Further changes: We now only reject touches that happened above window actors, we have proper support for adding and removing touches during a gesture, we don't have to forward every single touch event to Clutter anymore and much more...

If we start using implicit grabs in Clutter at some point, supporting them should be relatively easy, basically only the grab and ungrab calls would have to be removed.

Depends on: !396 (merged), !422 (merged), !423 (merged), !425 (closed), !649 (closed)

This also requires a few changes in gestures, those are done in gnome-shell!596 (closed).

Marked as WIP because I'm implementing proper gesture-state synchronization and running non-stage multiple gestures at the same time.

Edited by Jonas Dreßler

Merge request reports