From 1728dd8c2836f8d3b9575cd322437a42820749a7 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 7 Aug 2026 11:38:32 +0200 Subject: [PATCH] [General] Align `pointerType` across native and JS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description The JS `PointerType` enum is `TOUCH, STYLUS, MOUSE, KEY, OTHER`, but the native constants stopped at `OTHER = 3` — the value JS reads as `KEY`. Native pointer types travel to JS as plain ints with no translation layer (`gestureHandlerCommon.ts` types them as `PointerType`), so every native "other pointer" surfaced as `PointerType.KEY`, and `PointerType.OTHER` was unreachable from native. It is reachable on Android through `TOOL_TYPE_ERASER` / `TOOL_TYPE_UNKNOWN`, and on Apple through tvOS focus-driven hover and any touch that is neither direct, pencil, nor indirect pointer. Declares `KEY` on both platforms so `OTHER` lands on 4. Native never emits `KEY` — it is produced only by the web `KeyboardEventManager`. With the values consistent, `ButtonEvent.pointerType` is narrowed from `number` to `PointerType`. It only mirrored the codegen spec's `Int32`; the spec keeps its own self-contained copy, so codegen is unaffected. Numeric enums and `number` are mutually assignable, so this breaks no consumer — which is also why the `buttonEventTest` drift guard still passes. That guard can no longer tell a deliberate refinement of this field from real spec drift, but it still catches added, removed and retyped fields. ## Test plan - Android: `:react-native-gesture-handler:compileDebugKotlin` and `:app:assembleDebug` in `apps/basic-example/android` both succeed - Apple: enum values pinned by a compiled assertion (`Touch` 0 … `Key` 3, `OtherPointer` 4); no `switch` over the enum exists, so no `-Wswitch` fallout - `yarn ts-check` clean (both passes), `yarn test` 115/115, `yarn lint:js` 0 errors - The iOS app build was not run — `pod install` fails on this machine for reasons unrelated to the change (rvm `libruby.2.7.dylib` mismatch) --- .../java/com/swmansion/gesturehandler/core/GestureHandler.kt | 3 ++- .../apple/RNGestureHandlerPointerType.h | 1 + .../react-native-gesture-handler/src/v3/types/EventTypes.ts | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt index 45af12e6a9..ad3fd26c2e 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt @@ -1087,7 +1087,8 @@ open class GestureHandler { const val POINTER_TYPE_TOUCH = 0 const val POINTER_TYPE_STYLUS = 1 const val POINTER_TYPE_MOUSE = 2 - const val POINTER_TYPE_OTHER = 3 + const val POINTER_TYPE_KEY = 3 + const val POINTER_TYPE_OTHER = 4 private const val MAX_POINTERS_COUNT = 17 private lateinit var pointerProps: Array private lateinit var pointerCoords: Array diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerPointerType.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerPointerType.h index 90179d2613..e41df538fb 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerPointerType.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerPointerType.h @@ -4,5 +4,6 @@ typedef NS_ENUM(NSInteger, RNGestureHandlerPointerType) { RNGestureHandlerTouch = 0, RNGestureHandlerStylus, RNGestureHandlerMouse, + RNGestureHandlerKey, RNGestureHandlerOtherPointer, }; diff --git a/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts b/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts index a3de449c6c..3273fffd11 100644 --- a/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts +++ b/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts @@ -16,7 +16,7 @@ export type ButtonEvent = Readonly<{ absoluteX: number; absoluteY: number; numberOfPointers: number; - pointerType: number; + pointerType: PointerType; }>; type EventPayload = {