Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions packages/react-native/React/Base/RCTTouchHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,9 @@ - (void)_recordNewTouches:(NSSet *)touches
#else // [macOS
// -[NSView hitTest:] takes coordinates in a view's superview coordinate system.
// The assumption here is that a RCTUIView/RCTSurfaceView will always have a superview.
CGPoint touchLocation = [self.view.superview convertPoint:touch.locationInWindow fromView:nil];
NSView *targetView = [self.view hitTest:touchLocation];
NSView *superview = [[self view] superview];
const CGPoint touchLocationInSuperview = [superview convertPoint:touch.locationInWindow fromView:nil];
NSView *targetView = [self.view hitTest:touchLocationInSuperview];
// Don't record clicks on scrollbars.
if ([targetView isKindOfClass:[NSScroller class]]) {
continue;
Expand All @@ -148,8 +149,7 @@ - (void)_recordNewTouches:(NSSet *)touches
} else {
_shouldSendMouseUpOnSystemBehalf = NO;
}
touchLocation = [targetView convertPoint:touchLocation fromView:self.view.superview];


while (targetView) {
BOOL isUserInteractionEnabled = NO;
if ([((RCTUIView*)targetView) respondsToSelector:@selector(isUserInteractionEnabled)]) { // [macOS]
Expand All @@ -161,7 +161,8 @@ - (void)_recordNewTouches:(NSSet *)touches
targetView = targetView.superview;
}

NSNumber *reactTag = [targetView reactTagAtPoint:touchLocation];
const CGPoint touchLocationInSelf = [targetView convertPoint:touchLocationInSuperview fromView:self.view.superview];
NSNumber *reactTag = [targetView reactTagAtPoint:touchLocationInSelf];
BOOL isUserInteractionEnabled = NO;
if ([((RCTUIView*)targetView) respondsToSelector:@selector(isUserInteractionEnabled)]) { // [macOS]
isUserInteractionEnabled = ((RCTUIView*)targetView).isUserInteractionEnabled; // [macOS]
Expand Down
5 changes: 4 additions & 1 deletion packages/react-native/React/Base/RCTUIKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,10 @@ CGPathRef UIBezierPathCreateCGPathRef(UIBezierPath *path);

NS_INLINE RCTPlatformView *RCTUIViewHitTestWithEvent(RCTPlatformView *view, CGPoint point, __unused UIEvent *__nullable event)
{
return [view hitTest:point];
// [macOS IMPORTANT -- point is in local coordinate space, but OSX expects super coordinate space for hitTest:
NSView *superview = [view superview];
NSPoint pointInSuperview = superview != nil ? [view convertPoint:point toView:superview] : point;
return [view hitTest:pointInSuperview];
}

BOOL RCTUIViewSetClipsToBounds(RCTPlatformView *view);
Expand Down
11 changes: 9 additions & 2 deletions packages/react-native/React/Base/macOS/RCTUIKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,10 @@ - (void)setTransform:(CGAffineTransform)transform

- (NSView *)hitTest:(NSPoint)point
{
return [self hitTest:NSPointToCGPoint(point) withEvent:nil];
// IMPORTANT point is passed in super coordinates by OSX, but expected to be passed in local coordinates
NSView *superview = [self superview];
NSPoint pointInSelf = superview != nil ? [self convertPoint:point fromView:superview] : point;
return [self hitTest:pointInSelf withEvent:nil];
}

- (BOOL)wantsUpdateLayer
Expand Down Expand Up @@ -505,7 +508,11 @@ - (BOOL)becomeFirstResponder

- (NSView *)hitTest:(CGPoint)point withEvent:(__unused UIEvent *)event
{
return self.userInteractionEnabled ? [super hitTest:NSPointFromCGPoint(point)] : nil;
// [macOS
// IMPORTANT point is expected to be passed in local coordinates, but OSX expects point to be super
NSView *superview = [self superview];
NSPoint pointInSuperview = superview != nil ? [self convertPoint:point toView:superview] : point;
return self.userInteractionEnabled ? [super hitTest:pointInSuperview] : nil;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(__unused UIEvent *)event
Expand Down
13 changes: 2 additions & 11 deletions packages/react-native/React/Views/RCTView.m
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,8 @@ - (RCTPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event // [macOS
// of the hit view will return YES from -pointInside:withEvent:). See:
// - https://developer.apple.com/library/ios/qa/qa2013/qa1812.html
for (RCTUIView *subview in [sortedSubviews reverseObjectEnumerator]) { // [macOS]
CGPoint pointForHitTest = CGPointZero; // [macOS
#if !TARGET_OS_OSX // [macOS]
pointForHitTest = [subview convertPoint:point fromView:self];
#else // [macOS
if ([subview isKindOfClass:[RCTView class]]) {
pointForHitTest = [subview convertPoint:point fromView:self];
} else {
pointForHitTest = point;
}
#endif // macOS]
hitSubview = RCTUIViewHitTestWithEvent(subview, pointForHitTest, event); // macOS]
CGPoint pointForHitTest = [subview convertPoint:point fromView:self];
hitSubview = RCTUIViewHitTestWithEvent(subview, pointForHitTest, event); // [macOS]
if (hitSubview != nil) {
break;
}
Expand Down
7 changes: 5 additions & 2 deletions packages/react-native/React/Views/UIView+React.m
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,13 @@ - (NSString *)react_recursiveDescription

// [macOS
#pragma mark - Hit testing
#if TARGET_OS_OSX
#if TARGET_OS_OSX
// IMPORTANT -- point is in local coordinate space, unlike the hitTest: version from OSX which is in super's coordinate space
- (RCTPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return [self hitTest:point];
NSView *superview = [self superview];
NSPoint pointInSuper = superview != nil ? [self convertPoint:point toView:superview] : point;
return [self hitTest:pointInSuper];
}
#endif // macOS]

Expand Down