From 6b2d5a637a1de2f3333f272b297da1f3b80d4685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Fri, 13 Mar 2026 10:20:15 +0100 Subject: [PATCH 1/4] Add numberOfPointers --- .../apple/Handlers/RNNativeViewHandler.mm | 29 ++++++++++++++----- .../apple/RNGestureHandlerEvents.h | 4 ++- .../apple/RNGestureHandlerEvents.mm | 11 +++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index 9573850b6a..dd9251c267 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -186,21 +186,27 @@ - (void)handleTouchDown:(UIView *)sender forEvent:(UIEvent *)event [self sendEventsInState:RNGestureHandlerStateActive forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (void)handleTouchUpOutside:(UIView *)sender forEvent:(UIEvent *)event { [self sendEventsInState:RNGestureHandlerStateEnd forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (void)handleTouchUpInside:(UIView *)sender forEvent:(UIEvent *)event { [self sendEventsInState:RNGestureHandlerStateEnd forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (void)handleDragExit:(UIView *)sender forEvent:(UIEvent *)event @@ -211,11 +217,15 @@ - (void)handleDragExit:(UIView *)sender forEvent:(UIEvent *)event [control cancelTrackingWithEvent:event]; [self sendEventsInState:RNGestureHandlerStateEnd forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } else { [self sendEventsInState:RNGestureHandlerStateActive forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } } @@ -223,14 +233,18 @@ - (void)handleDragEnter:(UIView *)sender forEvent:(UIEvent *)event { [self sendEventsInState:RNGestureHandlerStateActive forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (void)handleTouchCancel:(UIView *)sender forEvent:(UIEvent *)event { [self sendEventsInState:RNGestureHandlerStateCancelled forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (BOOL)wantsToAttachDirectlyToView @@ -243,6 +257,7 @@ - (BOOL)wantsToAttachDirectlyToView - (RNGestureHandlerEventExtraData *)eventExtraData:(RNDummyGestureRecognizer *)recognizer { return [RNGestureHandlerEventExtraData forPointerInside:[self containsPointInView] + withNumberOfTouches:1 withPointerType:RNGestureHandlerMouse]; } diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.h index 84c2f6c0c0..755bf76bfa 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.h @@ -54,7 +54,9 @@ withAllPointers:(NSArray *)allPointers withNumberOfTouches:(NSUInteger)numberOfTouches withPointerType:(NSInteger)pointerType; -+ (RNGestureHandlerEventExtraData *)forPointerInside:(BOOL)pointerInside withPointerType:(NSInteger)pointerType; ++ (RNGestureHandlerEventExtraData *)forPointerInside:(BOOL)pointerInside + withNumberOfTouches:(NSUInteger)numberOfTouches + withPointerType:(NSInteger)pointerType; @end @interface RNGestureHandlerEvent : NSObject diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.mm index f5a3d6a14f..899cdbab9a 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerEvents.mm @@ -156,10 +156,15 @@ + (RNGestureHandlerEventExtraData *)forEventType:(RNGHTouchEventType)eventType }]; } -+ (RNGestureHandlerEventExtraData *)forPointerInside:(BOOL)pointerInside withPointerType:(NSInteger)pointerType ++ (RNGestureHandlerEventExtraData *)forPointerInside:(BOOL)pointerInside + withNumberOfTouches:(NSUInteger)numberOfTouches + withPointerType:(NSInteger)pointerType { - return [[RNGestureHandlerEventExtraData alloc] - initWithData:@{@"pointerInside" : @(pointerInside), @"pointerType" : @(pointerType)}]; + return [[RNGestureHandlerEventExtraData alloc] initWithData:@{ + @"pointerInside" : @(pointerInside), + @"numberOfPointers" : @(numberOfTouches), + @"pointerType" : @(pointerType) + }]; } @end From 6f7d02e40ca20f1461907bbcbfeba0999be6acfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Fri, 13 Mar 2026 12:35:43 +0100 Subject: [PATCH 2/4] Update hover --- .../apple/Handlers/RNHoverHandler.m | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m b/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m index 905d1c5359..fb063a5194 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m +++ b/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m @@ -220,21 +220,29 @@ - (void)mouseEntered:(NSEvent *)event { [self sendEventsInState:RNGestureHandlerStateBegan forViewWithTag:_view.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:1 + withPointerType:_pointerType]]; [self sendEventsInState:RNGestureHandlerStateActive forViewWithTag:_view.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:1 + withPointerType:_pointerType]]; } - (void)mouseExited:(NSEvent *)theEvent { [self sendEventsInState:RNGestureHandlerStateEnd forViewWithTag:_view.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:1 + withPointerType:_pointerType]]; [self sendEventsInState:RNGestureHandlerStateUndetermined forViewWithTag:_view.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withPointerType:_pointerType]]; + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:1 + withPointerType:_pointerType]]; } @end From 795fd92bcc3fbca8bd93c3676a9e18f25febec88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Fri, 13 Mar 2026 12:37:34 +0100 Subject: [PATCH 3/4] Format --- .../apple/Handlers/RNLongPressHandler.m | 12 +++++++++--- .../apple/Handlers/RNPinchHandler.m | 4 +++- .../apple/Handlers/RNRotationHandler.m | 4 +++- .../apple/RNGestureHandler.h | 10 +++++++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNLongPressHandler.m b/packages/react-native-gesture-handler/apple/Handlers/RNLongPressHandler.m index 77d98fa588..ae8ec2953e 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNLongPressHandler.m +++ b/packages/react-native-gesture-handler/apple/Handlers/RNLongPressHandler.m @@ -34,10 +34,14 @@ - (NSUInteger)getDuration; #if !TARGET_OS_OSX - (void)handleGesture:(UIGestureRecognizer *)recognizer; -- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange; +- (void)handleGesture:(UIGestureRecognizer *)recognizer + fromReset:(BOOL)fromReset + fromManualStateChange:(BOOL)fromManualStateChange; #else - (void)handleGesture:(NSGestureRecognizer *)recognizer; -- (void)handleGesture:(NSGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange; +- (void)handleGesture:(NSGestureRecognizer *)recognizer + fromReset:(BOOL)fromReset + fromManualStateChange:(BOOL)fromManualStateChange; #endif @end @@ -60,7 +64,9 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer [self handleGesture:recognizer fromReset:NO fromManualStateChange:NO]; } -- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange +- (void)handleGesture:(UIGestureRecognizer *)recognizer + fromReset:(BOOL)fromReset + fromManualStateChange:(BOOL)fromManualStateChange { previousTime = CACurrentMediaTime(); [_gestureHandler handleGesture:recognizer fromReset:fromReset fromManualStateChange:fromManualStateChange]; diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNPinchHandler.m b/packages/react-native-gesture-handler/apple/Handlers/RNPinchHandler.m index f258367ed4..96de2d9830 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNPinchHandler.m +++ b/packages/react-native-gesture-handler/apple/Handlers/RNPinchHandler.m @@ -48,7 +48,9 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer [self handleGesture:recognizer fromReset:NO fromManualStateChange:NO]; } -- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange +- (void)handleGesture:(UIGestureRecognizer *)recognizer + fromReset:(BOOL)fromReset + fromManualStateChange:(BOOL)fromManualStateChange { if (self.state == UIGestureRecognizerStateBegan) { #if TARGET_OS_OSX diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNRotationHandler.m b/packages/react-native-gesture-handler/apple/Handlers/RNRotationHandler.m index 0329ad3b4b..85c2be9aca 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNRotationHandler.m +++ b/packages/react-native-gesture-handler/apple/Handlers/RNRotationHandler.m @@ -46,7 +46,9 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer [self handleGesture:recognizer fromReset:NO fromManualStateChange:NO]; } -- (void)handleGesture:(UIGestureRecognizer *)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange +- (void)handleGesture:(UIGestureRecognizer *)recognizer + fromReset:(BOOL)fromReset + fromManualStateChange:(BOOL)fromManualStateChange { if (self.state == UIGestureRecognizerStateBegan) { self.rotation = 0; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.h b/packages/react-native-gesture-handler/apple/RNGestureHandler.h index 349c8ffd21..9ab60f35bf 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.h @@ -97,9 +97,13 @@ - (void)updateRelations:(nonnull NSDictionary *)relations; - (void)handleGesture:(nonnull id)recognizer; - (void)handleGesture:(nonnull id)recognizer fromReset:(BOOL)fromReset; -- (void)handleGesture:(nonnull id)recognizer fromReset:(BOOL)fromReset fromManualStateChange:(BOOL)fromManualStateChange; +- (void)handleGesture:(nonnull id)recognizer + fromReset:(BOOL)fromReset + fromManualStateChange:(BOOL)fromManualStateChange; - (void)handleGesture:(nonnull id)recognizer inState:(RNGestureHandlerState)state; -- (void)handleGesture:(nonnull id)recognizer inState:(RNGestureHandlerState)state fromManualStateChange:(BOOL)fromManualStateChange; +- (void)handleGesture:(nonnull id)recognizer + inState:(RNGestureHandlerState)state + fromManualStateChange:(BOOL)fromManualStateChange; - (BOOL)containsPointInView; - (RNGestureHandlerState)state; - (nullable RNGestureHandlerEventExtraData *)eventExtraData:(nonnull id)recognizer; @@ -112,7 +116,7 @@ - (void)sendEventsInState:(RNGestureHandlerState)state forViewWithTag:(nonnull NSNumber *)reactTag withExtraData:(nonnull RNGestureHandlerEventExtraData *)extraData - fromManualStateChange:(BOOL)fromManualStateChange; + fromManualStateChange:(BOOL)fromManualStateChange; - (void)sendEvent:(nonnull RNGestureHandlerStateChange *)event; - (void)sendTouchEventInState:(RNGestureHandlerState)state forViewWithTag:(nonnull NSNumber *)reactTag; - (nullable RNGHUIScrollView *)retrieveScrollView:(nonnull RNGHUIView *)view; From 950e6c87e545f38c95ec324747cbe125947d7b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= <63123542+m-bert@users.noreply.github.com> Date: Fri, 13 Mar 2026 12:46:41 +0100 Subject: [PATCH 4/4] Use correct `pointerInside` value Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../apple/Handlers/RNHoverHandler.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m b/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m index fb063a5194..a95541e805 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m +++ b/packages/react-native-gesture-handler/apple/Handlers/RNHoverHandler.m @@ -234,13 +234,13 @@ - (void)mouseExited:(NSEvent *)theEvent { [self sendEventsInState:RNGestureHandlerStateEnd forViewWithTag:_view.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO withNumberOfTouches:1 withPointerType:_pointerType]]; [self sendEventsInState:RNGestureHandlerStateUndetermined forViewWithTag:_view.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO withNumberOfTouches:1 withPointerType:_pointerType]]; }