Skip to content

Commit

Permalink
Add iOS implementation of the button property of the PointerEvent object
Browse files Browse the repository at this point in the history
Summary:
Changelog: [iOS][Internal] - Add iOS implementation of the button property of the PointerEvent object

This implements the `button` property on the PointerEvent object by storing the button which caused the down event in the `ActiveTouch` and reporting that button through `pointerdown` and `pointerup` events and -1 on all others. This diff also includes a small fix to the `pressure` property which was introduced due to `button` being correctly implemented.

Reviewed By: yungsters

Differential Revision: D38632543

fbshipit-source-id: 9dbbb23a9251f2e661faf37fdf206b9f0b26bc5f
  • Loading branch information
vincentriemer authored and pull[bot] committed Jan 15, 2024
1 parent 2ccd7d6 commit 8824198
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
37 changes: 36 additions & 1 deletion React/Fabric/RCTSurfaceTouchHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
*/
bool isPrimary;

/*
* The button number that was pressed (if applicable) when the event was fired.
*/
int button;

/*
* A component view on which the touch was begun.
*/
Expand Down Expand Up @@ -168,6 +173,16 @@ static int ButtonMaskToButtons(UIEventButtonMask buttonMask)
return 0;
}

static int ButtonMaskToButton(UIEventButtonMask buttonMask)
{
if (@available(iOS 13.4, *)) {
if ((buttonMask & UIEventButtonMaskSecondary) > 0) {
return 2;
}
}
return 0;
}

static void UpdateActiveTouchWithUITouch(
ActiveTouch &activeTouch,
UITouch *uiTouch,
Expand Down Expand Up @@ -291,12 +306,20 @@ static PointerEvent CreatePointerEventFromActiveTouch(ActiveTouch activeTouch, R

PointerEvent event = {};
event.pointerId = touch.identifier;
event.pressure = touch.force;
event.pointerType = PointerTypeCStringFromUITouchType(activeTouch.touchType);
event.clientPoint = touch.pagePoint;
event.screenPoint = touch.screenPoint;
event.offsetPoint = touch.offsetPoint;

event.pressure = touch.force;
if (@available(iOS 13.4, *)) {
if (activeTouch.touchType == UITouchTypeIndirectPointer) {
// pointer events with a mouse button pressed should report a pressure of 0.5
// when the touch is down and 0.0 when it is lifted regardless of how it is reported by the OS
event.pressure = eventType != RCTTouchEventTypeTouchEnd ? 0.5 : 0.0;
}
}

CGFloat pointerSize = activeTouch.majorRadius * 2.0;
if (@available(iOS 13.4, *)) {
if (activeTouch.touchType == UITouchTypeIndirectPointer) {
Expand All @@ -313,6 +336,11 @@ static PointerEvent CreatePointerEventFromActiveTouch(ActiveTouch activeTouch, R

event.detail = 0;

event.button = -1;
if (eventType == RCTTouchEventTypeTouchStart || eventType == RCTTouchEventTypeTouchEnd) {
event.button = activeTouch.button;
}

event.buttons = ButtonMaskToButtons(activeTouch.buttonMask);
UpdatePointerEventModifierFlags(event, activeTouch.modifierFlags);

Expand Down Expand Up @@ -351,11 +379,13 @@ static PointerEvent CreatePointerEventFromIncompleteHoverData(
event.tiltX = 0;
event.tiltY = 0;
event.detail = 0;
event.button = -1;
event.buttons = 0;
UpdatePointerEventModifierFlags(event, modifierFlags);
event.tangentialPressure = 0.0;
event.twist = 0;
event.isPrimary = true;

return event;
}

Expand Down Expand Up @@ -511,13 +541,18 @@ - (void)_registerTouches:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
}
break;
}

activeTouch.button = ButtonMaskToButton(event.buttonMask);
} else {
activeTouch.touch.identifier = _identifierPool.dequeue();
if (_primaryTouchPointerId == -1) {
_primaryTouchPointerId = activeTouch.touch.identifier;
activeTouch.isPrimary = true;
}

activeTouch.button = 0;
}

_activeTouches.emplace(touch, activeTouch);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ std::vector<DebugStringConvertibleObject> getDebugProps(
{"altKey", getDebugDescription(pointerEvent.altKey, options)},
{"metaKey", getDebugDescription(pointerEvent.metaKey, options)},
{"isPrimary", getDebugDescription(pointerEvent.isPrimary, options)},
{"button", getDebugDescription(pointerEvent.button, options)},
};
}

Expand Down
5 changes: 5 additions & 0 deletions ReactCommon/react/renderer/components/view/PointerEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ struct PointerEvent {
* type.
*/
bool isPrimary;
/*
* The button number that was pressed (if applicable) when the pointer event
* was fired.
*/
int button;
};

#if RN_DEBUG_STRING_CONVERTIBLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ static jsi::Value pointerEventPayload(
object.setProperty(runtime, "altKey", event.altKey);
object.setProperty(runtime, "metaKey", event.metaKey);
object.setProperty(runtime, "isPrimary", event.isPrimary);
object.setProperty(runtime, "button", event.button);
return object;
}

Expand Down

0 comments on commit 8824198

Please sign in to comment.