---
title: "Gesture Recognizers"
canonical_url: https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers/
last_updated: 2026-11-09
sdk_version: 4.44
---
# Gesture Recognizers

Source: https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers/

The APIs on this page will only work with SDK 4.9+.

Low-level touch-gesture recognizers for building fully custom touch interactions on touch-capable hardware.

A recognizer watches the raw touch stream for one gesture — a tap, a pan (single-axis drag) or a swipe — and calls a [RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) as the gesture progresses. Create one with a per-gesture constructor ([tap\_recognizer\_create](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#tap_recognizer_create), [pan\_recognizer\_create](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#pan_recognizer_create), [swipe\_recognizer\_create](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#swipe_recognizer_create)), attach it to a [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md), and read the current gesture data from the event callback. Recognizers are the building block for a custom scroll or drag.

For an ordinary scrollable list you do not need recognizers at all: on touch hardware [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) already scrolls by touch. Reach for recognizers to build an interaction the built-in list does not give you — a custom menu, a drag, or acting on a raw tap or swipe. Note that a bare [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md) does not scroll by touch on its own; you drive it with a pan recognizer, as below.

### Usage example: scrolling a custom menu

A [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md) holds your own content but does not scroll by touch by itself. Attach a vertical pan recognizer to the window and feed its delta into [scroll\_layer\_set\_content\_offset()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_offset) to scroll the content by finger:

```
static ScrollLayer \*s\_scroll;static int16\_t s\_base;// content offset committed on Completestatic void pan\_handler(const Recognizer \*recognizer, RecognizerEvent event) {switch (event) {case RecognizerEvent\_Updated: {// delta\_since\_start is (0, 0) at Start, so the content does not jump.GPoint d = pan\_recognizer\_get\_delta\_since\_start(recognizer);scroll\_layer\_set\_content\_offset(s\_scroll, GPoint(0, s\_base + d.y), false);break;}case RecognizerEvent\_Completed:s\_base = scroll\_layer\_get\_content\_offset(s\_scroll).y;// commitbreak;case RecognizerEvent\_Cancelled:scroll\_layer\_set\_content\_offset(s\_scroll, GPoint(0, s\_base), true);// roll backbreak;default:break;}}static void window\_load(Window \*window) {Layer \*root = window\_get\_root\_layer(window);s\_scroll = scroll\_layer\_create(layer\_get\_bounds(root));scroll\_layer\_set\_content\_size(s\_scroll, GSize(layer\_get\_bounds(root).size.w,total\_content\_height));// Add your custom row layers as children of s\_scroll here.layer\_add\_child(root, scroll\_layer\_get\_layer(s\_scroll));// The window owns the recognizer and destroys it when the window unloads.Recognizer \*pan = pan\_recognizer\_create(pan\_handler, NULL, PanAxis\_Vertical);window\_attach\_recognizer(window, pan);}
```

 While the global system recognizer set is live, attaching alone is not enough: a window opts out of it with [window\_set\_touch\_bridge\_disabled()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_touch_bridge_disabled) (added by the touch-bridge change) so its own recognizers receive the touch stream. 
## Function Documentation

Recognizer \* tap\_recognizer\_create([RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) event\_cb, void \* user\_data)

Create a tap recognizer. The default recognizer recognizes a single tap from a single finger.

#### Parameters
 event\_cb

event callback

 user\_data

user data associated with recognizer

#### Returns

recognizer reference

Recognizer \* pan\_recognizer\_create([RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) event\_cb, void \* user\_data, [PanAxis](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#PanAxis) axis)

Create a pan recognizer locked to a single axis. The recognizer stays in the Possible state until the finger moves unambiguously along _axis_ and crosses the start threshold, at which point it Starts. It Fails if the finger instead moves unambiguously along the foreign axis.

#### Parameters
 event\_cb

event callback

 user\_data

user data associated with recognizer

 axis

axis to which the pan is locked

#### Returns

recognizer reference

Recognizer \* swipe\_recognizer\_create([RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) event\_cb, void \* user\_data, uint8\_t direction\_mask)

Create a swipe recognizer that accepts the directions set in _direction\_mask_. The recognizer stays Possible while tracking the path and Completes on liftoff if the path is a fast, straight, long-enough flick whose direction is in the mask; otherwise it Fails.

#### Parameters
 event\_cb

event callback

 user\_data

user data associated with recognizer

 direction\_mask

bitwise-OR of the [SwipeDirection](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#SwipeDirection) values to accept

#### Returns

recognizer reference

[GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) tap\_recognizer\_get\_tap\_point(const Recognizer \* recognizer)

Get the coordinate of the recognized tap. The coordinate is taken from the last position update, not the liftoff. Valid once the recognizer has completed.

#### Parameters
 recognizer

recognizer from which to get the tap coordinate

#### Returns

tap coordinate

[GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_total\_delta(const Recognizer \* recognizer)

Get the total movement of the pan since the touchdown point. Component-wise.

#### Parameters
 recognizer

recognizer from which to get the delta

#### Returns

total delta from touchdown

[GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_delta\_since\_start(const Recognizer \* recognizer)

Get the movement of the pan since it Started (i.e. since the start threshold was crossed). This is exactly (0, 0) at the instant the recognizer transitions to Started, so live scroll that consumes this value does not jump at gesture start. Component-wise.

#### Parameters
 recognizer

recognizer from which to get the delta

#### Returns

delta since the pan started

[GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_delta\_since\_prev(const Recognizer \* recognizer)

Get the movement of the pan since the previous position update. Component-wise.

#### Parameters
 recognizer

recognizer from which to get the delta

#### Returns

delta since the previous event

[GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_velocity(const Recognizer \* recognizer)

Get the current velocity of the pan, in pixels per second, component-wise. Computed over the most-recent events within a short time window (see PAN\_VELOCITY\_WINDOW\_MS). Zero when the elapsed time across the sampled events is zero.

#### Parameters
 recognizer

recognizer from which to get the velocity

#### Returns

velocity in px/s

[SwipeDirection](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#SwipeDirection) swipe\_recognizer\_get\_direction(const Recognizer \* recognizer)

Get the recognized swipe direction. Valid once the recognizer has Completed; otherwise SwipeDirection\_None.

#### Parameters
 recognizer

recognizer from which to get the direction

#### Returns

recognized swipe direction

[GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) swipe\_recognizer\_get\_velocity(const Recognizer \* recognizer)

Get the velocity of the swipe, in pixels per second, component-wise. Computed over the most-recent events within a short time window. Zero when the elapsed time is zero.

#### Parameters
 recognizer

recognizer from which to get the velocity

#### Returns

velocity in px/s

void recognizer\_destroy(Recognizer \* recognizer)

Destroy an un-owned recognizer. If a recognizer is not owned, this will destroy the recognizer freeing it's data and calling the destructor (see recognizer\_set\_on\_destroy), if set. If it is owned, this will do nothing.

#### Parameters
 recognizer

[Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) to destroy

void recognizer\_set\_simultaneous\_with(Recognizer \* recognizer, [RecognizerSimultaneousWithCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerSimultaneousWithCb) simultaneous\_with\_cb)

Specify a callback to determine whether a recognizer should be evaluated simultaneously with another recognizer.

#### Parameters
 recognizer

recognizer to modify

 simultaneous\_with\_cb

callback that determines whether this recognizer will be evaluated simultaneous with another recognizer

void recognizer\_set\_fail\_after(Recognizer \* recognizer, Recognizer \* fail\_after)

Tell a recognizer to only evaluate after the another recognizer fails.

#### Parameters
 recognizer

recognizer to modify

 fail\_after

recognizer after which the modified gesture will be evaluated

## Enum Documentation

enum RecognizerEvent

#### Enumerators
RecognizerEvent\_StartedRecognizerEvent\_UpdatedRecognizerEvent\_CompletedRecognizerEvent\_Cancelled

enum PanAxis

Axis to which a pan recognizer is locked. A pan is only recognized when the finger moves unambiguously along this axis.

#### Enumerators
PanAxis\_HorizontalPanAxis\_Vertical

enum SwipeDirection

Swipe direction, also used as a bitmask when configuring which directions a swipe recognizer accepts. Screen coordinates grow downward, so a positive y delta is a downward swipe.

#### Enumerators
SwipeDirection\_NoneSwipeDirection\_UpSwipeDirection\_DownSwipeDirection\_LeftSwipeDirection\_Right

## Typedef Documentation

 typedef struct Recognizer Recognizer

 typedef void(\* RecognizerEventCb)(const Recognizer \*recognizer, RecognizerEvent event\_type) 

User event callback. When a recognizer changes state to any state other than the failed state the user callback of this type will be called.

#### Parameters
 recognizer

recognizer affected by the event

 event\_type

event that occurred

 typedef bool(\* RecognizerSimultaneousWithCb)(const Recognizer \*recognizer, const Recognizer \*simultaneous\_with) 

This function is called to determine whether _recognizer_ should be evaluated simultaneously with _simultaneous\_with_.

#### Parameters
 recognizer

recognizer to be tested

 simultaneous\_with

recognizer with which _recognizer_ would be evaluated simultaneously should this test pass

#### Returns

true if recognizers should be evaluated simultaneously
