Skip to content

Add onNativeTouchEnd event (Android finger-lift from WebView MotionEvent stream)#13

Merged
artemlitch merged 1 commit into
masterfrom
artem/native-touch-end
Jun 3, 2026
Merged

Add onNativeTouchEnd event (Android finger-lift from WebView MotionEvent stream)#13
artemlitch merged 1 commit into
masterfrom
artem/native-touch-end

Conversation

@artemlitch
Copy link
Copy Markdown
Collaborator

What

Adds a new onNativeTouchEnd direct event to the WebView. It fires from the WebView's own MotionEvent stream on a terminal gesture action, with a typed payload:

onNativeTouchEnd?: (event: { nativeEvent: {
  action: 'up' | 'cancel' | 'pointerUp';
  pointerCount: number;
  x: number;
  y: number;
} }) => void;

Why

On Android, once Chromium's native text-selection controller seizes a selection-drag gesture, it dispatches touchcancel/pointercancel and delivers no further events to React Native's view tree or the WebView's DOM — so RN's View.onTouchEnd, onPointerUp, RNGH onTouchesUp, DOM touchend/pointerup all get cancelled and never report the finger lift.

The WebView's own dispatchTouchEvent, however, still receives the real ACTION_UP on a selection-drag release. This event surfaces that signal so a consumer can reliably detect when the user finishes a text selection. (Used downstream to fix First Class Lookup not opening on Android word-select.)

Verified on a Pixel 6a: a 2–3 word drag-select release reports action: 'up'; a selection-handle re-drag (separate popup window) reports only 'cancel'.

Changes

  • Codegen spec + JS types (src/RNCWebViewNativeComponent.ts, src/WebViewTypes.ts) with the typed string-union action.
  • Android: new TopNativeTouchEndEvent, a dispatchTouchEvent override (observe-only — always returns super, no behavior change), mapping the MotionEvent action to the string, registered in both old- and new-arch managers.
  • iOS: no-op RCTDirectEventBlock property + export so the shared codegen interface stays consistent across platforms (never fired on iOS/macOS).
  • Rebuilt lib/ (declarations + view config).

Risk

dispatchTouchEvent is observe-only and always returns super.dispatchTouchEvent(event), so existing touch/scroll/selection behavior is unchanged. The event is Android-only; the iOS side is a compile-time stub.

🤖 Generated with Claude Code

…ent stream)

Exposes a new `onNativeTouchEnd` direct event that fires from the WebView's own
MotionEvent stream on a terminal action, carrying { action, pointerCount, x, y }
where `action` is one of 'up' | 'cancel' | 'pointerUp'. Unlike RN's onTouchEnd
responder, this observes the WebView's native touch stream directly, so it can
detect a finger lift even when Chromium's native text-selection controller seizes
the gesture and suppresses the usual RN/DOM release signals.

- Codegen spec + JS types (src/RNCWebViewNativeComponent.ts, src/WebViewTypes.ts)
  with a typed string-union action ('up' | 'cancel' | 'pointerUp')
- Android: TopNativeTouchEndEvent, dispatchTouchEvent override (observe-only,
  always returns super), maps the MotionEvent action to the string and is
  registered in old+new arch managers
- iOS: no-op RCTDirectEventBlock property + export for codegen-interface parity
  (never fired on iOS/macOS)
- Rebuilt lib/ declarations + view config

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@artemlitch artemlitch merged commit f3b2237 into master Jun 3, 2026
5 of 9 checks passed
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.

1 participant