Skip to content

Commit

Permalink
W3CPointerEvents: include screen coordinates in pointer events (#38222)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #38222

Changelog: [Android] [Fixed] - W3CPointerEvents: include screen coordinates in pointer events

The [spec](https://www.w3.org/TR/uievents/#idl-mouseevent) says there should be properties on mouse events (and hence pointer events) indicating the screen coordinates of the event (i.e. coords relative to screen of the device).

This change adds those properties.

Reviewed By: javache

Differential Revision: D47162962

fbshipit-source-id: 5bb9780882459b3550bbac792b7d7cf9f5c10860
  • Loading branch information
Alex Danoff authored and facebook-github-bot committed Jul 6, 2023
1 parent 5a57c0b commit 3460ff5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class JSPointerDispatcher {
private int mLastButtonState = 0;
private final ViewGroup mRootViewGroup;

private static final int[] sRootScreenCoords = {0, 0};

// Set globally for hover interactions, referenced for coalescing hover events

public JSPointerDispatcher(ViewGroup viewGroup) {
Expand Down Expand Up @@ -255,10 +257,21 @@ private void onDown(
}
}

private float[] eventCoordsToScreenCoords(float[] eventCoords) {
float[] screenCoords = new float[2];
mRootViewGroup.getLocationOnScreen(sRootScreenCoords);

screenCoords[0] = eventCoords[0] + sRootScreenCoords[0];
screenCoords[1] = eventCoords[1] + sRootScreenCoords[1];

return screenCoords;
}

private PointerEventState createEventState(int activePointerId, MotionEvent motionEvent) {
Map<Integer, float[]> offsetByPointerId = new HashMap<Integer, float[]>();
Map<Integer, List<ViewTarget>> hitPathByPointerId = new HashMap<Integer, List<ViewTarget>>();
Map<Integer, float[]> eventCoordinatesByPointerId = new HashMap<Integer, float[]>();
Map<Integer, float[]> screenCoordinatesByPointerId = new HashMap<Integer, float[]>();
for (int index = 0; index < motionEvent.getPointerCount(); index++) {
float[] offsetCoordinates = new float[2];
float[] eventCoordinates = new float[] {motionEvent.getX(index), motionEvent.getY(index)};
Expand All @@ -270,6 +283,7 @@ private PointerEventState createEventState(int activePointerId, MotionEvent moti
offsetByPointerId.put(pointerId, offsetCoordinates);
hitPathByPointerId.put(pointerId, hitPath);
eventCoordinatesByPointerId.put(pointerId, eventCoordinates);
screenCoordinatesByPointerId.put(pointerId, eventCoordsToScreenCoords(eventCoordinates));
}

int surfaceId = UIManagerHelper.getSurfaceId(mRootViewGroup);
Expand All @@ -282,6 +296,7 @@ private PointerEventState createEventState(int activePointerId, MotionEvent moti
offsetByPointerId,
hitPathByPointerId,
eventCoordinatesByPointerId,
screenCoordinatesByPointerId,
mHoveringPointerIds); // Creates a copy of hovering pointer ids, as they may be updated
}

Expand Down Expand Up @@ -673,6 +688,8 @@ private int[] getChildOffsetRelativeToRoot(View childView) {
private PointerEventState normalizeToRoot(PointerEventState original, float rootX, float rootY) {
Map<Integer, float[]> newOffsets = new HashMap<>(original.getOffsetByPointerId());
Map<Integer, float[]> newEventCoords = new HashMap<>(original.getEventCoordinatesByPointerId());
Map<Integer, float[]> newScreenCoords =
new HashMap<>(original.getScreenCoordinatesByPointerId());

float[] rootOffset = {rootX, rootY};
for (Map.Entry<Integer, float[]> offsetEntry : newOffsets.entrySet()) {
Expand All @@ -684,6 +701,11 @@ private PointerEventState normalizeToRoot(PointerEventState original, float root
eventCoordsEntry.setValue(zeroOffset);
}

float[] screenCoords = eventCoordsToScreenCoords(rootOffset);
for (Map.Entry<Integer, float[]> screenCoordsEntry : newScreenCoords.entrySet()) {
screenCoordsEntry.setValue(screenCoords);
}

return new PointerEventState(
original.getPrimaryPointerId(),
original.getActivePointerId(),
Expand All @@ -692,6 +714,7 @@ private PointerEventState normalizeToRoot(PointerEventState original, float root
newOffsets,
new HashMap<>(original.getHitPathByPointerId()),
newEventCoords,
newScreenCoords,
new HashSet<>(original.getHoveringPointerIds()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ private WritableMap createW3CPointerEvent(int index) {
pointerEvent.putDouble("clientX", clientX);
pointerEvent.putDouble("clientY", clientY);

float[] screenCoords = mEventState.getScreenCoordinatesByPointerId().get(pointerId);
double screenX = PixelUtil.toDIPFromPixel(screenCoords[0]);
double screenY = PixelUtil.toDIPFromPixel(screenCoords[1]);
pointerEvent.putDouble("screenX", screenX);
pointerEvent.putDouble("screenY", screenY);

// x,y values are aliases of clientX, clientY
pointerEvent.putDouble("x", clientX);
pointerEvent.putDouble("y", clientY);
Expand Down Expand Up @@ -338,6 +344,7 @@ public static class PointerEventState {
private Map<Integer, float[]> mOffsetByPointerId;
private Map<Integer, List<TouchTargetHelper.ViewTarget>> mHitPathByPointerId;
private Map<Integer, float[]> mEventCoordinatesByPointerId;
private Map<Integer, float[]> mScreenCoordinatesByPointerId;
private Set<Integer> mHoveringPointerIds;

public PointerEventState(
Expand All @@ -348,6 +355,7 @@ public PointerEventState(
Map<Integer, float[]> offsetByPointerId,
Map<Integer, List<TouchTargetHelper.ViewTarget>> hitPathByPointerId,
Map<Integer, float[]> eventCoordinatesByPointerId,
Map<Integer, float[]> screenCoordinatesByPointerId,
Set<Integer> hoveringPointerIds) {
mPrimaryPointerId = primaryPointerId;
mActivePointerId = activePointerId;
Expand All @@ -356,6 +364,7 @@ public PointerEventState(
mOffsetByPointerId = offsetByPointerId;
mHitPathByPointerId = hitPathByPointerId;
mEventCoordinatesByPointerId = eventCoordinatesByPointerId;
mScreenCoordinatesByPointerId = screenCoordinatesByPointerId;
mHoveringPointerIds = new HashSet<>(hoveringPointerIds);
}

Expand Down Expand Up @@ -395,6 +404,10 @@ public final Map<Integer, float[]> getEventCoordinatesByPointerId() {
return mEventCoordinatesByPointerId;
}

public final Map<Integer, float[]> getScreenCoordinatesByPointerId() {
return mScreenCoordinatesByPointerId;
}

public final List<TouchTargetHelper.ViewTarget> getHitPathForActivePointer() {
return mHitPathByPointerId.get(mActivePointerId);
}
Expand Down

0 comments on commit 3460ff5

Please sign in to comment.