Skip to content

fix(android): respect pointer events on gesture root views - #4565

Open
huytdps13400 wants to merge 1 commit into
software-mansion:mainfrom
huytdps13400:fix/android-root-pointer-events
Open

huytdps13400 wants to merge 1 commit into
software-mansion:mainfrom
huytdps13400:fix/android-root-pointer-events

Conversation

@huytdps13400

Copy link
Copy Markdown

Description

On Android, GestureHandlerRootView accepts pointerEvents through ViewProps, but its generated manager delegate never forwards that prop. A nested root with box-none intercepts taps in its empty area; none still allows child Pressables and v3 gestures to activate.

Declare the prop explicitly in the native spec and forward it to ReactViewGroup.pointerEvents, following the existing detector/button managers. Add a basic-example screen comparing a nested gesture root with a plain View across all pointer-event modes.

This addresses the gesture-root blocker described in heroui-inc/heroui-native#490. The separate HeroUI wrapper behavior is outside this change.

Test plan

  • Built the unmodified and patched Android example from source, React Native 0.87.0 / Fabric / Hermes, arm64 Android 12L emulator.
  • Before: box-none blocks the background where a plain View allows it; none still fires the child Pressable and useTapGesture callbacks.
  • After: tested auto, none, box-only, box-none, and removing the prop on the same mounted view. Background, child Pressable, and v3 gesture counters match the expected behavior. Also verified the new screen through the example navigator.
  • Library Jest: 185 tests passed. Monorepo TypeScript checks, changed-file ESLint/Prettier, and Android Spotless checks passed.

To reproduce: launch apps/basic-example, advance to Root Pointer Events, and tap Empty side, Child press, and Child gesture. Switch modes without remounting; Use View provides the native View control.

Copilot AI balanced review requested due to automatic review settings October 4, 2026 15:21
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3420aa46-d8ad-483d-9cb6-30a731157560
📥 Commits

Reviewing files that changed from the base of the PR and between b9c337c and ecb3e5b.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 50c89d65-861e-4c97-9492-6d3a9d22ee39
📥 Commits

Reviewing files that changed from the base of the PR and between 736318e and b9c337c.

📒 Files selected for processing (4)
  • apps/basic-example/src/App.tsx
  • apps/basic-example/src/PointerEventsRepro.tsx
  • packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.kt
  • packages/react-native-gesture-handler/src/specs/RNGestureHandlerRootViewNativeComponent.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Summary

Summary by CodeRabbit

  • New Features
    • Root gesture-handler views now support the pointerEvents options auto, none, box-only, and box-none.
    • Added a “Root Pointer Events” example where you can compare pointer-event behavior on a standard view and a gesture-handler root view, and track or reset background presses, child presses, and tap gestures.

Walkthrough

The Android gesture-handler root view now accepts a pointerEvents prop. The basic example app adds a screen to compare pointer-event modes on a plain view and a gesture-handler root view.

Changes

Root Pointer Events

Layer / File(s) Summary
Declare and apply root pointerEvents
packages/react-native-gesture-handler/src/specs/RNGestureHandlerRootViewNativeComponent.ts, packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.kt
The native component spec declares pointerEvents with auto as the default. The Android manager parses the prop value and assigns it to the root view.
Add the pointer-events example screen
apps/basic-example/src/PointerEventsRepro.tsx, apps/basic-example/src/App.tsx
The screen provides wrapper and pointer-event selectors, interaction counts, reset controls, and background, child, and gesture targets. The app registers the screen as “Root Pointer Events.”

Suggested reviewers: m-bert

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to b9c33

No actionable issue is established for the Android pointer-events change or its example screen. The change is ready to merge after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to b9c33

The inspected change affects touch routing within an application view, without introducing a new privileged operation. No concrete security regression was identified, but prop removal and updates during active gestures remain incompletely verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The directly affected scope is touch targeting for each configured Android root and its descendants, including gesture callbacks. The setter introduces no global state or cross-view mutation; the available downstream graph does not establish broader exposure.

Trust Boundaries and Controls

  • inferred — The inspected path carries an application-supplied prop across the JavaScript-to-native component boundary into per-view touch configuration. It does not demonstrate an external attacker acquiring application authority or reaching a privileged sink. Pointer-events filtering is touch-routing behavior, not an established authorization control.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Android gesture root views now respect the pointerEvents prop.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The focused fix follows existing detector-manager patterns and includes a suitable manual regression screen.

Review effort: Balanced
Findings: None

What changed in this PR

Ensures Android gesture root views correctly honor React Native pointerEvents semantics.

Changes:

  • Declares and forwards pointerEvents through native codegen.
  • Applies parsed pointer-event modes to the Android root view.
  • Adds an interactive v3 API comparison screen.
File Description
RNGestureHandlerRootViewNativeComponent.ts Adds the codegen prop declaration.
RNGestureHandlerRootViewManager.kt Forwards the prop to the native view.
PointerEventsRepro.tsx Demonstrates all pointer-event modes.
App.tsx Registers the new example screen.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@m-bert m-bert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @huytdps13400 👋

Thank you for this PR ❤️ It looks good, the only thing I'd like you to change is to remove the example - in this case a code change is enough.

Let me know when it's ready!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants