blob: ea60cf1aad119a0cd2ab35b1e8cdbb92f536e1bd [file] [log] [blame] [view]
# Pointer Input Design
At a high level the embedder's job is to handle the input events from Scenic and
transform the fuchsia specific FIDL events into a generic type
(`FlutterPointerEvent`, defined in `embedder.h`) and send it to the flutter
engine via the Embedder API's `FlutterEngineSendPointerEvent` function. The
flutter engine implements this function in
[embedder.cc](https://osscs.corp.google.com/flutter/engine/+/master:shell/platform/embedder/embedder.cc;l=1?q=embedder.cc).
```
Scenic --(Touch/Mouse Event)--> Embedder --(FlutterPointerEvent)--> Flutter Engine`
```
There are two forms of pointer input (Touch and Mouse), and each has some unique
differences that are described below.
## Touch Input
Embedder must convert the `TouchEvent` from Scenic's `TouchSource` protocol into
a generic `FlutterPointerEvent` that we can send to the flutter engine.
Touch input is unique from mouse input in several ways:
1. There can be multiple fingers touching the screen at once. In order to
support "multi-touch" we need to encode both fuchsia's `device_id` and
`pointer_id` into the `device` field in the `FlutterPointerEvent` object
that is sent to the flutter engine.
2. Touch input requires adhering to the
[Gesture Disambiguation Protocol](https://www.tdcommons.org/dpubs_series/3872/).
The embedder must buffer new interactions and only handle them once Scenic
has determined who is the true owner of this event.
### Responsibilities
1. Initialize the `TouchSourceHandle`
2. Call `Watch()` on the channel to begin listening for events
3. Implement a handler function that converts
`fuchsia::ui::pointer::TouchEvent` types to `FlutterPointerEvent` types
4. Handler should follow the rules of Gesture Disambiguation
5. Send the pointer events to the flutter engine using the embedder API's
`FlutterEngineSendPointerEvent` function
## Mouse Input
Embedder must convert the `MouseEvent` from Scenic's `MouseSource` protocol into
a generic `FlutterPointerEvent` that we can send to the flutter engine.
Mouse input is unique from touch input because it has buttons that can be
clicked or scrolled. Therefore, the mouse input channel processor needs to keep
track of additional state (i.e. whether any buttons are down or up) and relay
this to the flutter engine.
### Responsibilities
1. Initialize the `MouseSourceHandle`
2. Call `Watch()` on the channel to begin listening for events
3. Implement a handler function that converts
`fuchsia::ui::pointer::MouseEvent` types to `FlutterPointerEvent` types
4. Send the pointer events to the flutter engine using the embedder API's
`FlutterEngineSendPointerEvent` function
## Usage & Implementation
The `TouchDelegate` and `MouseDelegate` classes implement the responsibilities
for touch and mouse input respectively. Both are initialized on the embedder's
main thread directly on the stack of `main()`. These objects lifetime is
therefore tied to the scope of the main function, which will run as long as the
embedder's async processing loop is still running.
The Embedder API is a C header, therefore the structs don't have constructors.
When initializing a `FlutterPointerEvent` we need to `memset()` the values to be
0 and then set the `struct_size` field which is used by the flutter engine. See
`ResetFlutterPointerEvent()`.