Skip to content

Commit 966f800

Browse files
vincentriemerfacebook-github-bot
authored andcommitted
Add key modifier properties to the PointerEvent interface
Summary: Changelog: [iOS][Internal] - Add key modifier properties to the PointerEvent interface This diff adds implementations of the `ctrlKey`, `shiftKey`, `altKey`, and `metaKey` properties on the PointerEvent interface for iOS. Reviewed By: lunaleaps Differential Revision: D37869377 fbshipit-source-id: b187bae93fbfc97b6ca1d8d9786ad85343484b3d
1 parent f3db6cc commit 966f800

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

React/Fabric/RCTSurfaceTouchHandler.mm

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
8383
*/
8484
UIEventButtonMask buttonMask;
8585

86+
/*
87+
* The bit mask of modifier flags in the gesture represented by the receiver.
88+
*/
89+
UIKeyModifierFlags modifierFlags;
90+
8691
/*
8792
* A component view on which the touch was begun.
8893
*/
@@ -178,8 +183,10 @@ static void UpdateActiveTouchWithUITouch(
178183
activeTouch.azimuthAngle = [uiTouch azimuthAngleInView:nil];
179184
if (@available(iOS 13.4, *)) {
180185
activeTouch.buttonMask = uiEvent.buttonMask;
186+
activeTouch.modifierFlags = uiEvent.modifierFlags;
181187
} else {
182188
activeTouch.buttonMask = 0;
189+
activeTouch.modifierFlags = 0;
183190
}
184191
}
185192

@@ -248,6 +255,21 @@ static SharedTouchEventEmitter GetTouchEmitterFromView(UIView *componentView, CG
248255
}
249256
}
250257

258+
static void UpdatePointerEventModifierFlags(PointerEvent &event, UIKeyModifierFlags flags)
259+
{
260+
if (@available(iOS 13.4, *)) {
261+
event.ctrlKey = (flags & UIKeyModifierControl) != 0;
262+
event.shiftKey = (flags & UIKeyModifierShift) != 0;
263+
event.altKey = (flags & UIKeyModifierAlternate) != 0;
264+
event.metaKey = (flags & UIKeyModifierCommand) != 0;
265+
} else {
266+
event.ctrlKey = false;
267+
event.shiftKey = false;
268+
event.altKey = false;
269+
event.metaKey = false;
270+
}
271+
}
272+
251273
static PointerEvent CreatePointerEventFromActiveTouch(ActiveTouch activeTouch, RCTTouchEventType eventType)
252274
{
253275
Touch touch = activeTouch.touch;
@@ -277,6 +299,8 @@ static PointerEvent CreatePointerEventFromActiveTouch(ActiveTouch activeTouch, R
277299
event.detail = 0;
278300

279301
event.buttons = ButtonMaskToButtons(activeTouch.buttonMask);
302+
UpdatePointerEventModifierFlags(event, activeTouch.modifierFlags);
303+
280304
// UIEvent's button mask for touch end events still marks the button as down
281305
// so this ensures it's set to 0 as per the pointer event spec
282306
if (eventType == RCTTouchEventTypeTouchEnd) {
@@ -294,7 +318,7 @@ static PointerEvent CreatePointerEventFromIncompleteHoverData(
294318
CGPoint clientLocation,
295319
CGPoint screenLocation,
296320
CGPoint offsetLocation,
297-
NSTimeInterval timestamp)
321+
UIKeyModifierFlags modifierFlags)
298322
{
299323
PointerEvent event = {};
300324
// "touch" events produced from a mouse cursor on iOS always have the ID 0 so
@@ -312,6 +336,7 @@ static PointerEvent CreatePointerEventFromIncompleteHoverData(
312336
event.tiltY = 0;
313337
event.detail = 0;
314338
event.buttons = 0;
339+
UpdatePointerEventModifierFlags(event, modifierFlags);
315340
event.tangentialPressure = 0.0;
316341
event.twist = 0;
317342
return event;
@@ -695,9 +720,14 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0))
695720

696721
CGPoint offsetLocation = [recognizer locationInView:targetView];
697722

698-
NSOrderedSet *eventPathViews = GetTouchableViewsInPathToRoot(targetView);
723+
UIKeyModifierFlags modifierFlags;
724+
if (@available(iOS 13.4, *)) {
725+
modifierFlags = recognizer.modifierFlags;
726+
} else {
727+
modifierFlags = 0;
728+
}
699729

700-
NSTimeInterval timestamp = CACurrentMediaTime();
730+
NSOrderedSet *eventPathViews = GetTouchableViewsInPathToRoot(targetView);
701731

702732
BOOL hasMoveListenerInEventPath = NO;
703733

@@ -707,7 +737,7 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0))
707737
SharedTouchEventEmitter eventEmitter = GetTouchEmitterFromView(targetView, [recognizer locationInView:targetView]);
708738
if (shouldEmitOverEvent && eventEmitter != nil) {
709739
PointerEvent event = CreatePointerEventFromIncompleteHoverData(
710-
targetView, clientLocation, screenLocation, offsetLocation, timestamp);
740+
targetView, clientLocation, screenLocation, offsetLocation, modifierFlags);
711741
eventEmitter->onPointerOver(event);
712742
}
713743
}
@@ -730,7 +760,7 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0))
730760
GetTouchEmitterFromView(componentView, [recognizer locationInView:componentView]);
731761
if (eventEmitter != nil) {
732762
PointerEvent event = CreatePointerEventFromIncompleteHoverData(
733-
componentView, clientLocation, screenLocation, offsetLocation, timestamp);
763+
componentView, clientLocation, screenLocation, offsetLocation, modifierFlags);
734764
eventEmitter->onPointerEnter(event);
735765
}
736766
}
@@ -749,7 +779,7 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0))
749779
SharedTouchEventEmitter eventEmitter = GetTouchEmitterFromView(targetView, [recognizer locationInView:targetView]);
750780
if (eventEmitter != nil) {
751781
PointerEvent event = CreatePointerEventFromIncompleteHoverData(
752-
targetView, clientLocation, screenLocation, offsetLocation, timestamp);
782+
targetView, clientLocation, screenLocation, offsetLocation, modifierFlags);
753783
eventEmitter->onPointerMove(event);
754784
}
755785
}
@@ -761,7 +791,7 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0))
761791
GetTouchEmitterFromView(prevTargetView, [recognizer locationInView:prevTargetView]);
762792
if (shouldEmitOutEvent && eventEmitter != nil) {
763793
PointerEvent event = CreatePointerEventFromIncompleteHoverData(
764-
prevTargetView, clientLocation, screenLocation, offsetLocation, timestamp);
794+
prevTargetView, clientLocation, screenLocation, offsetLocation, modifierFlags);
765795
eventEmitter->onPointerOut(event);
766796
}
767797
}
@@ -793,7 +823,7 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0))
793823
GetTouchEmitterFromView(componentView, [recognizer locationInView:componentView]);
794824
if (eventEmitter != nil) {
795825
PointerEvent event = CreatePointerEventFromIncompleteHoverData(
796-
componentView, clientLocation, screenLocation, offsetLocation, timestamp);
826+
componentView, clientLocation, screenLocation, offsetLocation, modifierFlags);
797827
eventEmitter->onPointerLeave(event);
798828
}
799829
}

ReactCommon/react/renderer/components/view/PointerEvent.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ std::vector<DebugStringConvertibleObject> getDebugProps(
3535
{"tangentialPressure",
3636
getDebugDescription(pointerEvent.tangentialPressure, options)},
3737
{"twist", getDebugDescription(pointerEvent.twist, options)},
38+
{"ctrlKey", getDebugDescription(pointerEvent.ctrlKey, options)},
39+
{"shiftKey", getDebugDescription(pointerEvent.shiftKey, options)},
40+
{"altKey", getDebugDescription(pointerEvent.altKey, options)},
41+
{"metaKey", getDebugDescription(pointerEvent.metaKey, options)},
3842
};
3943
}
4044

ReactCommon/react/renderer/components/view/PointerEvent.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ struct PointerEvent {
8484
* axis in degrees, with a value in the range 0 to 359.
8585
*/
8686
int twist;
87+
/*
88+
* Returns true if the control key was down when the event was fired.
89+
*/
90+
bool ctrlKey;
91+
/*
92+
* Returns true if the shift key was down when the event was fired.
93+
*/
94+
bool shiftKey;
95+
/*
96+
* Returns true if the alt key was down when the event was fired.
97+
*/
98+
bool altKey;
99+
/*
100+
* Returns true if the meta key was down when the event was fired.
101+
*/
102+
bool metaKey;
87103
};
88104

89105
#if RN_DEBUG_STRING_CONVERTIBLE

ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ static jsi::Value pointerEventPayload(
8787
object.setProperty(runtime, "buttons", event.buttons);
8888
object.setProperty(runtime, "tangentialPressure", event.tangentialPressure);
8989
object.setProperty(runtime, "twist", event.twist);
90+
object.setProperty(runtime, "ctrlKey", event.ctrlKey);
91+
object.setProperty(runtime, "shiftKey", event.shiftKey);
92+
object.setProperty(runtime, "altKey", event.altKey);
93+
object.setProperty(runtime, "metaKey", event.metaKey);
9094
return object;
9195
}
9296

0 commit comments

Comments
 (0)