Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const UIView = {
mouseDownCanMoveWindow: true,
enableFocusRing: true,
focusable: true,
onAuxClick: true,
onMouseEnter: true,
onMouseLeave: true,
onDoubleClick: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ type MouseEventProps = $ReadOnly<{

// Experimental/Work in Progress Pointer Event Callbacks (not yet ready for use)
type PointerEventProps = $ReadOnly<{
onAuxClick?: ?(event: PointerEvent) => void,
onAuxClickCapture?: ?(event: PointerEvent) => void,
onClick?: ?(event: PointerEvent) => void,
onClickCapture?: ?(event: PointerEvent) => void,
onPointerEnter?: ?(event: PointerEvent) => void,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ const bubblingEventTypes = {
},

// Experimental/Work in Progress Pointer Events (not yet ready for use)
topAuxClick: {
phasedRegistrationNames: {
captured: 'onAuxClickCapture',
bubbled: 'onAuxClick',
},
},
topClick: {
phasedRegistrationNames: {
captured: 'onClickCapture',
Expand Down Expand Up @@ -394,6 +400,8 @@ const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({
onTouchCancel: true,

// Pointer events
onAuxClick: true,
onAuxClickCapture: true,
onClick: true,
onClickCapture: true,
onPointerUp: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,14 @@ export default class Pressability {
return;
}

// [macOS Only fire onPress for primary (left) mouse button clicks.
// Non-primary buttons (right, middle) should not trigger onPress.
const button = event?.nativeEvent?.button;
if (button != null && button !== 0) {
return;
}
// macOS]

// for non-pointer click events (e.g. accessibility clicks), we should only dispatch when we're the "real" target
// in particular, we shouldn't respond to clicks from nested pressables
if (event?.currentTarget !== event?.target) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2032,9 +2032,10 @@ - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
MouseEnter,
MouseLeave,
DoubleClick,
AuxClick,
};

- (void)emitMouseEvent:(MouseEventType)eventType
- (void)emitMouseEvent:(MouseEventType)eventType button:(int)button
{
if (!_eventEmitter) {
return;
Expand All @@ -2054,6 +2055,7 @@ - (void)emitMouseEvent:(MouseEventType)eventType
.ctrlKey = static_cast<bool>(modifierFlags & NSEventModifierFlagControl),
.shiftKey = static_cast<bool>(modifierFlags & NSEventModifierFlagShift),
.metaKey = static_cast<bool>(modifierFlags & NSEventModifierFlagCommand),
.button = button,
};

switch (eventType) {
Expand All @@ -2068,9 +2070,18 @@ - (void)emitMouseEvent:(MouseEventType)eventType
case DoubleClick:
_eventEmitter->onDoubleClick(mouseEvent);
break;

case AuxClick:
_eventEmitter->onAuxClick(mouseEvent);
break;
}
}

- (void)emitMouseEvent:(MouseEventType)eventType
{
[self emitMouseEvent:eventType button:0];
}

- (void)updateMouseOverIfNeeded
{
// When an enclosing scrollview is scrolled using the scrollWheel or trackpad,
Expand Down Expand Up @@ -2191,6 +2202,16 @@ - (void)mouseUp:(NSEvent *)event
[super mouseUp:event];
}
}

- (void)rightMouseUp:(NSEvent *)event
{
BOOL hasAuxClickEventHandler = _props->hostPlatformEvents[HostPlatformViewEvents::Offset::AuxClick];
if (hasAuxClickEventHandler) {
[self emitMouseEvent:AuxClick button:2];
} else {
[super rightMouseUp:event];
}
}
#endif // macOS]

- (SharedTouchEventEmitter)touchEventEmitterAtPoint:(CGPoint)point
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,8 +703,12 @@ - (void)_dispatchActivePointers:(std::vector<ActivePointer>)activePointers event
}
case RCTPointerEventTypeEnd: {
eventEmitter->onPointerUp(pointerEvent);
if (pointerEvent.isPrimary && pointerEvent.button == 0 && IsPointerWithinInitialTree(activePointer)) {
eventEmitter->onClick(std::move(pointerEvent));
if (pointerEvent.isPrimary && pointerEvent.button == 0) {
if (IsPointerWithinInitialTree(activePointer)) {
eventEmitter->onClick(std::move(pointerEvent));
}
} else if (IsPointerWithinInitialTree(activePointer)) {
eventEmitter->onAuxClick(std::move(pointerEvent));
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ void TouchEventEmitter::onTouchCancel(TouchEvent event) const {
"touchCancel", std::move(event), RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onAuxClick(PointerEvent event) const {
dispatchPointerEvent("auxClick", std::move(event), RawEvent::Category::Discrete);
}

void TouchEventEmitter::onClick(PointerEvent event) const {
dispatchPointerEvent("click", std::move(event), RawEvent::Category::Discrete);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class TouchEventEmitter : public EventEmitter {
void onTouchEnd(TouchEvent event) const;
void onTouchCancel(TouchEvent event) const;

void onAuxClick(PointerEvent event) const;
void onClick(PointerEvent event) const;
void onPointerCancel(PointerEvent event) const;
void onPointerDown(PointerEvent event) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static jsi::Object mouseEventPayload(jsi::Runtime& runtime, const MouseEvent& ev
payload.setProperty(runtime, "ctrlKey", event.ctrlKey);
payload.setProperty(runtime, "shiftKey", event.shiftKey);
payload.setProperty(runtime, "metaKey", event.metaKey);
payload.setProperty(runtime, "button", event.button);
return payload;
};

Expand All @@ -84,6 +85,12 @@ void HostPlatformViewEventEmitter::onDoubleClick(const MouseEvent& mouseEvent) c
});
}

void HostPlatformViewEventEmitter::onAuxClick(const MouseEvent& mouseEvent) const {
dispatchEvent("auxClick", [mouseEvent](jsi::Runtime& runtime) {
return mouseEventPayload(runtime, mouseEvent);
});
}

#pragma mark - Drag and Drop Events

jsi::Value HostPlatformViewEventEmitter::dataTransferPayload(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class HostPlatformViewEventEmitter : public BaseViewEventEmitter {
void onMouseEnter(MouseEvent const& mouseEvent) const;
void onMouseLeave(MouseEvent const& mouseEvent) const;
void onDoubleClick(MouseEvent const& mouseEvent) const;
void onAuxClick(MouseEvent const& mouseEvent) const;

#pragma mark - Drag and Drop Events

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct HostPlatformViewEvents {
MouseEnter = 4,
MouseLeave = 5,
DoubleClick = 6,
AuxClick = 7,
};

constexpr bool operator[](const Offset offset) const {
Expand Down Expand Up @@ -74,6 +75,8 @@ static inline HostPlatformViewEvents convertRawProp(
convertRawProp(context, rawProps, "onMouseLeave", sourceValue[Offset::MouseLeave], defaultValue[Offset::MouseLeave]);
result[Offset::DoubleClick] =
convertRawProp(context, rawProps, "onDoubleClick", sourceValue[Offset::DoubleClick], defaultValue[Offset::DoubleClick]);
result[Offset::AuxClick] =
convertRawProp(context, rawProps, "onAuxClick", sourceValue[Offset::AuxClick], defaultValue[Offset::AuxClick]);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ struct MouseEvent {
* A flag indicating if the meta key is pressed.
*/
bool metaKey{false};

/**
* The button number that was pressed when the mouse event was fired:
* 0 = primary button (usually the left button)
* 1 = auxiliary button (usually the middle/wheel button)
* 2 = secondary button (usually the right button)
*/
int button{0};
};

struct DataTransferFile {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ struct ViewEvents {
PointerDownCapture = 35,
PointerUp = 36,
PointerUpCapture = 37,
AuxClick = 38,
AuxClickCapture = 39,
};

constexpr bool operator[](const Offset offset) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,10 @@ static inline ViewEvents convertRawProp(
"onPointerOutCapture",
sourceValue[Offset::PointerOutCapture],
defaultValue[Offset::PointerOutCapture]);
result[Offset::AuxClick] =
convertRawProp(context, rawProps, "onAuxClick", sourceValue[Offset::AuxClick], defaultValue[Offset::AuxClick]);
result[Offset::AuxClickCapture] = convertRawProp(
context, rawProps, "onAuxClickCapture", sourceValue[Offset::AuxClickCapture], defaultValue[Offset::AuxClickCapture]);
result[Offset::Click] = convertRawProp(
context,
rawProps,
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native/ReactNativeApi.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3676,6 +3676,8 @@ declare type PlatformType =
| WindowsPlatform
declare type PointerEvent = NativeSyntheticEvent<NativePointerEvent>
declare type PointerEventProps = {
readonly onAuxClick?: (event: PointerEvent) => void
readonly onAuxClickCapture?: (event: PointerEvent) => void
readonly onClick?: (event: PointerEvent) => void
readonly onClickCapture?: (event: PointerEvent) => void
readonly onGotPointerCapture?: (e: PointerEvent) => void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ function PressableFeedbackEvents() {
onDragLeave={() => appendEvent('dragLeave')}
onDrop={() => appendEvent('drop')}
draggedTypes={'fileUrl'}
onAuxClick={() => appendEvent('auxClick')}
onDoubleClick={() => appendEvent('doubleClick')}
// macOS]
onPress={() => appendEvent('press')}
Expand Down
Loading