Skip to content

Commit 8e64fef

Browse files
authored
[Web] Remove workaround for touch events allowing to change state too soon (#3794)
## Description Ordering of touch events on the web was mostly aligned with Android. To unify the ordering across all platforms (along #3793), this PR changes it so that `onTouchesDown` is called before `onBegin` and `onTouchesMove` is called before `onUpdate`. Another change is enforcing going through `BEGAN` when imperatively changing the state from `UNDETERMINED` to `ACTIVE`. And a fix for an issue that came out due to the above changes - when the discrete gestures were imperatively activated inside `onTouchesDown`, the order was: ``` Touch down Gesture begin Gesture start Touch cancel Gesture end Gesture finalize Gesture begin Gesture finalize ``` This was because those gestures transition to the `END` state immediately after `ACTIVE`, and get reset immediately. Then, the normal flow resumes, and they go to the `BEGAN` as a result of touch input. To prevent that, I changed `cleanupFinishedHandlers` to be queued as a microtask instead of being executed immediately. This should ensure that it will be called in the same run loop, but after the gesture handles its state. ## Test plan Tested on the following code: ``` import React from 'react'; import { StyleSheet, View } from 'react-native'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; export default function EmptyExample() { const pan = Gesture.Pan() .onTouchesDown((e, stateManager) => { 'worklet'; console.log('Touch down'); stateManager.activate(); }) .onTouchesMove(() => { 'worklet'; console.log('Touch move'); }) .onTouchesUp(() => { 'worklet'; console.log('Touch up'); }) .onTouchesCancelled(() => { 'worklet'; console.log('Touch cancel'); }) .onBegin(() => { 'worklet'; console.log('Gesture begin'); }) .onStart((e) => { 'worklet'; console.log('Gesture start'); }) .onEnd(() => { 'worklet'; console.log('Gesture end'); }) .onFinalize(() => { 'worklet'; console.log('Gesture finalize'); }); return ( <View style={styles.container}> <GestureDetector gesture={pan}> <View style={{ width: 300, height: 300, backgroundColor: 'green' }} /> </GestureDetector> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, }); ```
1 parent ad2029d commit 8e64fef

File tree

11 files changed

+18
-24
lines changed

11 files changed

+18
-24
lines changed

packages/react-native-gesture-handler/src/handlers/gestures/gestureStateManager.web.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { State } from '../../State';
12
import NodeManager from '../../web/tools/NodeManager';
23
import { GestureStateManagerType } from './gestureStateManager';
34

@@ -11,7 +12,15 @@ export const GestureStateManager = {
1112
},
1213

1314
activate: () => {
14-
NodeManager.getHandler(handlerTag).activate(true);
15+
const handler = NodeManager.getHandler(handlerTag);
16+
17+
// Force going from UNDETERMINED to ACTIVE through BEGAN to preserve
18+
// the correct state transition flow.
19+
if (handler.state === State.UNDETERMINED) {
20+
handler.begin();
21+
}
22+
23+
handler.activate(true);
1524
},
1625

1726
fail: () => {

packages/react-native-gesture-handler/src/web/handlers/FlingGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ export default class FlingGestureHandler extends GestureHandler {
125125

126126
super.onPointerDown(event);
127127
this.newPointerAction();
128-
129-
this.tryToSendTouchEvent(event);
130128
}
131129

132130
protected override onPointerAdd(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ export default abstract class GestureHandler implements IGestureHandler {
313313
GestureHandlerOrchestrator.instance.cancelMouseAndPenGestures(this);
314314
}
315315

316-
// TODO: Bring back touch events along with introducing `handleDown` method that will handle handler specific stuff
316+
this.tryToSendTouchEvent(event);
317317
}
318318
// Adding another pointer to existing ones
319319
protected onPointerAdd(event: AdaptedEvent): void {
@@ -347,9 +347,9 @@ export default abstract class GestureHandler implements IGestureHandler {
347347
protected onPointerEnter(event: AdaptedEvent): void {
348348
this.tryToSendTouchEvent(event);
349349
}
350-
protected onPointerCancel(event: AdaptedEvent): void {
351-
this.tryToSendTouchEvent(event);
352-
350+
protected onPointerCancel(_event: AdaptedEvent): void {
351+
// No need to send a cancel touch event explicitly here. `cancel` will
352+
// handle cancelling all tracked touches if the handler expects pointer data.
353353
this.cancel();
354354
this.reset();
355355
}
@@ -370,11 +370,10 @@ export default abstract class GestureHandler implements IGestureHandler {
370370
return;
371371
}
372372

373+
this.tryToSendTouchEvent(event);
373374
if (this.active) {
374375
this.sendEvent(this.state, this.state);
375376
}
376-
377-
this.tryToSendTouchEvent(event);
378377
}
379378

380379
protected tryToSendTouchEvent(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/LongPressGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ export default class LongPressGestureHandler extends GestureHandler {
9191

9292
this.tryBegin();
9393
this.tryActivate();
94-
95-
this.tryToSendTouchEvent(event);
9694
}
9795
protected override onPointerAdd(event: AdaptedEvent): void {
9896
super.onPointerAdd(event);

packages/react-native-gesture-handler/src/web/handlers/ManualGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ export default class ManualGestureHandler extends GestureHandler {
1616
this.tracker.addToTracker(event);
1717
super.onPointerDown(event);
1818
this.begin();
19-
20-
this.tryToSendTouchEvent(event);
2119
}
2220

2321
protected override onPointerAdd(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/NativeViewGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ export default class NativeViewGestureHandler extends GestureHandler {
7474
this.tracker.addToTracker(event);
7575
super.onPointerDown(event);
7676
this.newPointerAction();
77-
78-
this.tryToSendTouchEvent(event);
7977
}
8078

8179
protected override onPointerAdd(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/PanGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,6 @@ export default class PanGestureHandler extends GestureHandler {
230230

231231
this.tryBegin(event);
232232
this.checkBegan();
233-
234-
this.tryToSendTouchEvent(event);
235233
}
236234

237235
protected override onPointerAdd(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/PinchGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ export default class PinchGestureHandler extends GestureHandler {
8181
protected override onPointerDown(event: AdaptedEvent): void {
8282
this.tracker.addToTracker(event);
8383
super.onPointerDown(event);
84-
85-
this.tryToSendTouchEvent(event);
8684
}
8785

8886
protected override onPointerAdd(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/RotationGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ export default class RotationGestureHandler extends GestureHandler {
8989
protected override onPointerDown(event: AdaptedEvent): void {
9090
this.tracker.addToTracker(event);
9191
super.onPointerDown(event);
92-
93-
this.tryToSendTouchEvent(event);
9492
}
9593

9694
protected override onPointerAdd(event: AdaptedEvent): void {

packages/react-native-gesture-handler/src/web/handlers/TapGestureHandler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,6 @@ export default class TapGestureHandler extends GestureHandler {
134134
this.lastY = event.y;
135135

136136
this.updateState(event);
137-
138-
this.tryToSendTouchEvent(event);
139137
}
140138

141139
protected override onPointerAdd(event: AdaptedEvent): void {

0 commit comments

Comments
 (0)