[Android] Properly handle requestDisallowInterceptTouchEvent for v3 - #4367
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adjusts Android’s requestDisallowInterceptTouchEvent handling to avoid canceling v3 gestures too broadly (notably inside pagers), by making cancellation more targeted across root/orchestrator and v3 detector/button views.
Changes:
- Add
GestureHandlerOrchestrator.cancelAllLegacyHandlers()and use it from the root helper instead of triggering cancellation via the internal root handler. - Override
requestDisallowInterceptTouchEventin v3 host detector and button view to cancel only relevant handlers (and skip cancellation while the orchestrator is handling touch). - Update root view lookup to prefer the nearest enabled
RNGestureHandlerRootViewand expose the orchestrator via the root view/root helper.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt | Exposes orchestrator and returns nearest enabled GH root view when searching ancestors. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt | Switches root-level cancellation to cancelAllLegacyHandlers and attaches root handler with ACTION_TYPE_NONE. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt | Adds requestDisallowInterceptTouchEvent override to cancel v3 handlers attached via the host detector. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt | Adds requestDisallowInterceptTouchEvent override to cancel the button’s managed v3 handler. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt | Introduces cancelAllLegacyHandlers() to selectively cancel v1/v2 action types. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
934af71 to
c30a19c
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe Android gesture-handler implementation now exposes orchestrator state, centralizes legacy-handler cancellation, and cancels attached handlers during disallowed touch interception. Root lookup now prefers enabled gesture-handler roots. ChangesNative interception cancellation
Sequence Diagram(s)sequenceDiagram
participant ButtonViewGroup
participant RNGestureHandlerDetectorView
participant RNGestureHandlerRootView
participant GestureHandlerOrchestrator
ButtonViewGroup->>RNGestureHandlerDetectorView: requestDisallowInterceptTouchEvent(true)
RNGestureHandlerDetectorView->>RNGestureHandlerRootView: find gesture-handler root
RNGestureHandlerRootView->>GestureHandlerOrchestrator: read isHandlingTouch
RNGestureHandlerDetectorView->>GestureHandlerOrchestrator: cancel attached handlers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
Comment |
…m/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt Co-authored-by: Michał Bert <63123542+m-bert@users.noreply.github.com>
dd2e6bc to
dc49bcc
Compare
Description
On Android, when a native view calls
requestDisallowInterceptTouchEvent(e.g. a pager starting a swipe),RNGestureHandlerRootViewreacted by cancelling all handlers registered on the root.react-native-pager-viewcalls it eagerly on touch down, so any v3 gesture rendered inside a pager (e.g. inside material top tabs) was cancelled before it could activate — a long press nested in top tabs never activated at all.This PR makes the cancellation targeted:
GestureHandlerOrchestrator.cancelAllLegacyHandlers, instead of the old trick of activating the internalRootViewGestureHandler. The root handler is now attached withACTION_TYPE_NONEso it's excluded from that sweep (and no longer sends dead events to JS).requestDisallowInterceptTouchEventoverrides onRNGestureHandlerDetectorViewandButtonViewGroup. Since the request only bubbles upward from the requesting view, only handlers attached to its ancestors are cancelled — handlers below the requester (like the long press under the pager) keep working.isHandlingTouch), mirroring the existingpassingTouchguard, so disallow requests caused by RNGH's own event delivery don't cancel gestures.findGestureHandlerRootViewnow returns the nearest enabled root view so the checks above consult the orchestrator that actually manages the subtree.Test plan
Tested on reproducer from #2383
Screen.Recording.2026-07-31.at.11.38.38.mov