Skip to content
Draft
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Implement onPressOut event emission in TextInput fabric component",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,22 @@ void WindowsTextInputComponentView::OnPointerReleased(
auto hr = m_textServices->TxSendMessage(msg, static_cast<WPARAM>(wParam), static_cast<LPARAM>(lParam), &lresult);
args.Handled(hr != S_FALSE);
}

// Emits the OnPressOut event
if (m_eventEmitter && !m_comingFromJS) {
auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
float offsetX = position.X - m_layoutMetrics.frame.origin.x;
float offsetY = position.Y - m_layoutMetrics.frame.origin.y;

Comment on lines +764 to +766
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing this to the OnPressIn event up at lines 698-715 I see this local variable initialized:

    float neutralX = m_layoutMetrics.frame.origin.x;
    float neutralY = m_layoutMetrics.frame.origin.y;

But it doesn't appear to be used. If that's dead code, can you clean it up as part of this PR, to keep the In/Out methods consistent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the unused neutralX and neutralY variables from the OnPressIn method to keep both In/Out methods consistent. The variables were indeed dead code that was not being used anywhere in the event structure. Fixed in e8b9967.

facebook::react::GestureResponderEvent pressOutArgs;
pressOutArgs.target = m_tag;
pressOutArgs.pagePoint = {position.X, position.Y};
pressOutArgs.offsetPoint = {offsetX, offsetY};
pressOutArgs.timestamp = static_cast<double>(pp.Timestamp()) / 1000.0;
pressOutArgs.identifier = pp.PointerId();

emitter->onPressOut(pressOutArgs);
}
}

void WindowsTextInputComponentView::OnPointerMoved(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ void WindowsTextInputEventEmitter::onPressIn(GestureResponderEvent event) const
});
}

void WindowsTextInputEventEmitter::onPressOut(GestureResponderEvent event) const {
dispatchEvent("textInputPressOut", [event = std::move(event)](jsi::Runtime &runtime) {
auto payload = jsi::Object(runtime);
auto nativeEvent = jsi::Object(runtime);
nativeEvent.setProperty(runtime, "target", static_cast<double>(event.target));
nativeEvent.setProperty(runtime, "pageX", event.pagePoint.x);
nativeEvent.setProperty(runtime, "pageY", event.pagePoint.y);
nativeEvent.setProperty(runtime, "locationX", event.offsetPoint.x);
nativeEvent.setProperty(runtime, "locationY", event.offsetPoint.y);
nativeEvent.setProperty(runtime, "timestamp", event.timestamp);
nativeEvent.setProperty(runtime, "identifier", static_cast<double>(event.identifier));
payload.setProperty(runtime, "nativeEvent", nativeEvent);
return payload;
});
}

void WindowsTextInputEventEmitter::onEndEditing(OnEndEditing event) const {
dispatchEvent("textInputEndEditing", [event = std::move(event)](jsi::Runtime &runtime) {
auto payload = jsi::Object(runtime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class WindowsTextInputEventEmitter : public ViewEventEmitter {
void onKeyPress(OnKeyPress value) const;
void onContentSizeChange(OnContentSizeChange value) const;
void onPressIn(GestureResponderEvent event) const override;
void onPressOut(GestureResponderEvent event) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the lack of override on this method. I guess onPressOut isn't a virtual on ViewEventEmitter? Is it supposed to be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct that onPressOut doesn't have override and onPressIn does. Looking at the base class HostPlatformViewEventEmitter, only onPressIn is declared as virtual - there's no onPressOut method there at all.

So the current implementation is correct: onPressOut should NOT have override since it's not overriding a virtual method from the base class.

For consistency, onPressOut probably should be added as a virtual method to the base class alongside onPressIn, but that would be a larger architectural change beyond the scope of this TextInput-specific fix.

void onEndEditing(OnEndEditing value) const;
};

Expand Down
Loading