# Gestures

## How are hit tests performed?

* The `RendererBinding` is `HitTestable`, which implies the presence of a `hitTest` method. The default implementation defers to `RenderView`, which itself implements `hitTest` to visit the entire render tree. Each render object is given an opportunity to add itself to a shared `HitTestResult`.
* `GestureBinding.dispatchEvent` (via `HitTestDispatcher`) uses the `PointerRouter` to pass the original event to all render objects that were hit (`RenderObject` implements `HitTestTarget`, and therefore provides `handleEvent`). If a `GestureRecognizer` is utilized, the event’s pointer is passed via `GestureRecognizer.addPointer` which registers with the `PointerRouter` to receive future events.
* Related events are sent to all original `HitTestTarget` as well as any routes registered with the `PointerRouter`. `PointerDownEvent` will close the gesture area, barring additional entries, whereas `PointerUpEvent` will sweep it, resolving competing gestures and preventing indecisive gestures from locking up input.

## How are gestures captured and propagated?

* `Window.onPointerDataPacket` captures pointer updates from the engine and generates `PointerEvents` from the raw data. `PointerEventConverter` is utilized to map physical coordinates from the engine to logical coordinates, taking into account the device’s pixel ratio (via `PointerEventConverter.expand`).&#x20;

## What does a gesture recognizer do?

* A pointer is added to the gesture recognizer by client code on `PointerDownEvent`. Gesture recognizers determine whether a pointer is allowed by overriding `GestureRecognizer.isPointerAllowed`. If so, the recognizer subscribes to future pointer events via the `PointerRouter` and adds the pointer to the gesture arena via `GestureArenaManager.add`.
* The recognizer will process incoming events, outcomes from the gesture arena (`GestureArenaMember.accept`/`rejectGesture`), spontaneous decisions about the gesture (`GestureArenaEntry.resolve`), and other externalities. Typically, recognizers watch the stream of `PointerEvents` via `HitTestTarget.handleEvent`, looking for terminating events like `PointerDown`, or criteria that will cause acceptance / rejection. If the gesture is accepted, the recognizer will continue to process events to characterize the gesture, invoking user-provided callbacks at key moments.
* The gesture recognizer must unsubscribe from the pointer when rejecting or done processing, removing itself from the `PointerRouter` (`OneSequenceGestureRecognizer.stopTrackingPointer` does this).

## What does the gesture arena do?

* The arena disambiguates multiple gestures in a way that allows single gestures to resolve immediately if there is no competition. A recognizer “wins” if it declares itself the winner or if it’s the last/sole survivor.

## Can gesture recognizers be grouped together?

* A `GestureArenaTeam` combines multiple recognizers together into a group.&#x20;
* Captained teams cause the captain recognizer to win when all unaffiliated recognizers reject or a constituent accepts.
* A non-captained team causes the first added recognizer to win when all unaffiliated recognizers reject. However, if a constituent accepts, that recognizer still takes the win.

## What auxiliary classes support gesture handling?

* There are two major categories of gesture recognizers, multi-touch recognizers (i.e., `MultiTapGestureRecognizer`) that simultaneously process multiple pointers (i.e., tapping with two fingers will register twice), and single-touch recognizer (i.e., `OneSequenceGestureRecognizer`) that will only consider events from a single pointer (i.e., tapping with two fingers will register once).&#x20;
* There is a helper “Drag” object that is used to communicate drag-related updates to other parts of the framework (like `DragScrollActivity`)
* There’s a `VelocityTracker` that generates fairly accurate estimates about drag velocity using curve fitting.
* There are local and global `PointerRoutes` in `PointerRouter`. Local routes are used as described above; global routes are used to react to any interaction (i.e., to dismiss a tooltip).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://flutter.megathink.com/interaction/gestures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
