diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java index 48319952d1e..434ebe0fe19 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java @@ -128,7 +128,11 @@ public class JSPointerDispatcher { if (listeningForDown) { eventDispatcher.dispatchEvent( PointerEvent.obtain( - PointerEventHelper.POINTER_DOWN, surfaceId, activeTargetTag, motionEvent)); + PointerEventHelper.POINTER_DOWN, + surfaceId, + activeTargetTag, + motionEvent, + mTargetCoordinates)); } return; @@ -149,7 +153,11 @@ public class JSPointerDispatcher { if (listeningForDown) { eventDispatcher.dispatchEvent( PointerEvent.obtain( - PointerEventHelper.POINTER_DOWN, surfaceId, activeTargetTag, motionEvent)); + PointerEventHelper.POINTER_DOWN, + surfaceId, + activeTargetTag, + motionEvent, + mTargetCoordinates)); } return; @@ -167,6 +175,7 @@ public class JSPointerDispatcher { surfaceId, activeTargetTag, motionEvent, + mTargetCoordinates, coalescingKey)); } @@ -182,7 +191,11 @@ public class JSPointerDispatcher { if (listeningForUp) { eventDispatcher.dispatchEvent( PointerEvent.obtain( - PointerEventHelper.POINTER_UP, surfaceId, activeTargetTag, motionEvent)); + PointerEventHelper.POINTER_UP, + surfaceId, + activeTargetTag, + motionEvent, + mTargetCoordinates)); } return; @@ -200,7 +213,11 @@ public class JSPointerDispatcher { if (listeningForUp) { eventDispatcher.dispatchEvent( PointerEvent.obtain( - PointerEventHelper.POINTER_UP, surfaceId, activeTargetTag, motionEvent)); + PointerEventHelper.POINTER_UP, + surfaceId, + activeTargetTag, + motionEvent, + mTargetCoordinates)); } if (!supportsHover) { @@ -279,7 +296,7 @@ public class JSPointerDispatcher { return dispatchableViewTargets; } - private static void dispatchEventForViewTargets( + private void dispatchEventForViewTargets( String eventName, List viewTargets, EventDispatcher dispatcher, @@ -288,7 +305,8 @@ public class JSPointerDispatcher { for (ViewTarget viewTarget : viewTargets) { int viewId = viewTarget.getViewId(); - dispatcher.dispatchEvent(PointerEvent.obtain(eventName, surfaceId, viewId, motionEvent)); + dispatcher.dispatchEvent( + PointerEvent.obtain(eventName, surfaceId, viewId, motionEvent, mTargetCoordinates)); } } @@ -416,7 +434,12 @@ public class JSPointerDispatcher { if (listeningToMove) { eventDispatcher.dispatchEvent( PointerEvent.obtain( - PointerEventHelper.POINTER_MOVE, surfaceId, targetTag, motionEvent, coalescingKey)); + PointerEventHelper.POINTER_MOVE, + surfaceId, + targetTag, + motionEvent, + mTargetCoordinates, + coalescingKey)); } mLastHitPath = hitPath; @@ -443,7 +466,11 @@ public class JSPointerDispatcher { Assertions.assertNotNull(eventDispatcher) .dispatchEvent( PointerEvent.obtain( - PointerEventHelper.POINTER_CANCEL, surfaceId, targetTag, motionEvent)); + PointerEventHelper.POINTER_CANCEL, + surfaceId, + targetTag, + motionEvent, + mTargetCoordinates)); } List leaveViewTargets = diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java index 031522bf979..d577163b56a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java @@ -14,6 +14,7 @@ import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactSoftExceptionLogger; import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.PixelUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -26,12 +27,22 @@ public class PointerEvent extends Event { private static final int UNSET_COALESCING_KEY = -1; public static PointerEvent obtain( - String eventName, int surfaceId, int viewTag, MotionEvent motionEventToCopy) { + String eventName, + int surfaceId, + int viewTag, + MotionEvent motionEventToCopy, + float[] offsetCoords) { PointerEvent event = EVENTS_POOL.acquire(); if (event == null) { event = new PointerEvent(); } - event.init(eventName, surfaceId, viewTag, Assertions.assertNotNull(motionEventToCopy), 0); + event.init( + eventName, + surfaceId, + viewTag, + Assertions.assertNotNull(motionEventToCopy), + offsetCoords, + 0); return event; } @@ -40,30 +51,42 @@ public class PointerEvent extends Event { int surfaceId, int viewTag, MotionEvent motionEventToCopy, + float[] offsetCoords, int coalescingKey) { PointerEvent event = EVENTS_POOL.acquire(); if (event == null) { event = new PointerEvent(); } event.init( - eventName, surfaceId, viewTag, Assertions.assertNotNull(motionEventToCopy), coalescingKey); + eventName, + surfaceId, + viewTag, + Assertions.assertNotNull(motionEventToCopy), + offsetCoords, + coalescingKey); return event; } private @Nullable MotionEvent mMotionEvent; private @Nullable String mEventName; private int mCoalescingKey = UNSET_COALESCING_KEY; + private float mOffsetX; + private float mOffsetY; private void init( String eventName, int surfaceId, int viewTag, MotionEvent motionEventToCopy, + float[] offsetCoords, int coalescingKey) { + super.init(surfaceId, viewTag, motionEventToCopy.getEventTime()); mEventName = eventName; mMotionEvent = MotionEvent.obtain(motionEventToCopy); mCoalescingKey = coalescingKey; + mOffsetX = offsetCoords[0]; + mOffsetY = offsetCoords[1]; } private PointerEvent() {} @@ -126,6 +149,10 @@ public class PointerEvent extends Event { pointerEvent.putDouble("clientX", mMotionEvent.getX(index)); pointerEvent.putDouble("clientY", mMotionEvent.getY(index)); + // Offset refers to upper left edge of the target view + pointerEvent.putDouble("offsetX", PixelUtil.toDIPFromPixel(mOffsetX)); + pointerEvent.putDouble("offsetY", PixelUtil.toDIPFromPixel(mOffsetY)); + pointerEvent.putInt("target", this.getViewTag()); pointerEvent.putDouble("timestamp", this.getTimestampMs()); return pointerEvent; diff --git a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js index 020e563bc3a..08f3cba81cb 100644 --- a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js @@ -57,10 +57,13 @@ function EventfulView(props: {| } = props; const [tag, setTag] = React.useState(''); - const eventLog = (eventName: string) => (event: PointerEvent) => { - // $FlowFixMe Using private property - log(`${name} - ${eventName} - target: ${event.target._nativeTag}`); - }; + const eventLog = + (eventName: string, handler: ?(e: PointerEvent) => void) => + (event: PointerEvent) => { + // $FlowFixMe Using private property + log(`${name} - ${eventName} - target: ${event.target._nativeTag}`); + handler?.(event); + }; const listeners = { onPointerUp: onUp ? eventLog('up') : null, @@ -75,7 +78,7 @@ function EventfulView(props: {| onPointerMoveCapture: onMoveCapture ? eventLog('move capture') : null, }; - let listeningTo = Object.keys(listeners) + const listeningTo = Object.keys(listeners) .filter(listenerName => listeners[listenerName] != null) .join(', ');