Gesture Recognizer Overview
This document describes the process by which Touch Events received by a WindowEventDispatcher are transformed into Gesture Events.
- Cancel: fired on preventDefault'ed release, or when we need to truncate a touch stream (i.e. when something else takes window capture)
Gesture Events contain type specific data in their GestureEventDetails object. See here for a summary of the typical event sequences.
- Tap Down
- Fired when the first finger is pressed.
- Show Press
- Fired on a delay after a tap down if no movement has occurred, or directly before a tap if the finger is released before the delay is finished.
- Triggers the active state.
- Fired after a press followed by a release, within the tap timeout window.
- Has a "tap_count" field, indicating whether or not this is a single, double or triple tap.
- Tap Cancel
- Eventually fired after every Tap Down which doesn't result in a tap.
- Double Tap
- Only fired on Android, where it is used for double tap zooming.
- Tap Unconfirmed
- Only fired on Android.
- Occurs whenever a tap would occur on Aura.
- On Android, tap is fired after a delay, to ensure the current gesture isn't a double tap.
- Long Press
- Fired on a delay after a tap down, if no movement has occurred.
- Some number of fingers were pressed, and then at least one finger was released while all fingers were moving in the same direction.
- Contains the direction the fingers were moving in.
- Scroll Begin
- Contains the offset from the tap down, to hint at the direct the scroll is likely to be in.
- Scroll Update
- Contains the scroll delta.
- Scroll End
- Fired when a finger is lifted during scroll, without enough velocity to cause a fling.
- Fling Start
- Fired when a finger is lifted during scroll, with enough velocity to cause a fling.
- Fling Cancel
- If we're in a fling, stop it. This is synthesized and dispatched immediately before each tap down event.
- Pinch Begin
- Pinch Update
- Associated scale.
- Pinch End
- Two Finger Tap
- Two fingers were pressed, then one was released, without much finger movement.
- A finger was pressed. You can figure out how many fingers are down now using event.details.touch_points().
- A finger was released. You can figure out how many fingers are down now using event.details.touch_points().
- Touch Lock:
- The association between an existing touch and its target.
- Touch Capture:
- If a window is capturing touches, new touches will be targetted at the capturing window.
- Touch Id:
- The global id given to each touch. Contiguous starting from 0 for each display.
- Rail Scroll:
- A scroll which is locked to only move vertically or horizontally.
- When scrolling, if the user releases their fingers, but the scroll should continue, this is known as a fling.
Finding a Target
Possible ways of establishing a target
- If a touch is already locked to a target, keep it.
- If a window is capturing touches, target that window.
- If it's outside the root window, target the root window.
- If it's near another touch, use the other touch's target.
- Otherwise, use whichever window the touch is above.
In the following images, a filled in circle represents a touch down, and the outline of a circle represents a position the touch has moved to. The dotted green line indicates the window that a touch is targeted at. The rounded rectangle represents a window, and the outer rectangle represents the root window.
|1. If a touch is already locked to a target, keep it.||2. If a window is capturing touches, target that window.|
|3. If it's outside the root window, target the root window.||4. If it's near another touch, use the other touch's target.|
|5. Otherwise, use whichever window the touch is above.|
When a touch capture occurs, all touches on windows other than the window gaining capture need to be ignored until they are released. To do this, we fire a touch cancel for each of these touches.
Generating Gesture Events
Each touch-id has an associated window (See GestureRecognizerImpl::touch_id_target_), and each window has an associated GestureProviderAura.
GestureProviderAura contains a FilteredGestureProvider, which is responsible for performing gesture detection on both Android and Aura.
Where To Start
- Responsible for mapping from touches to windows, and hosts the GestureProviderAura objects.
- Take in touches, and fire callbacks for each gesture.
- Hosts the GestureDetector and ScaleGestureDetector.
- Constructs GestureEventData objects, which are turned into GestureEvent objects in GestureProviderAura.