Skip to content

Fix onPointerLeave computation by comparing button presses #50402

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Abbondanzo
Copy link
Contributor

Summary:
While investigating pointer events, I noticed that all Android views fire onPointerLeave/onPointerEnter in rapid succession on every button press. This is because Android fires ACTION_HOVER_EXIT on every frame before firing ACTION_DOWN. The logic in JSPointerDispatcher needed to be updated to account for this.

Unfortunately, ACTION_HOVER_EXIT events have no means of distinguishing between whether they were driven by the mouse actually leaving the view's bounds or by a button press. Some OS implementations fire this event on the frame just before leaving the view's boundaries while others fire after, so pure X/Y position isn't helpful enough. The button state property on ACTION_HOVER_EXIT also never gets set in some OS.

To work around this issue, this change posts a callback to the very next frame after receiving ACTION_HOVER_EXIT. If no ACTION_DOWN event was received in the same frame, it calls all the way through the existing logic. But, if an ACTION_DOWN event is received, we compare the event timestamps and if they match we don't post onPointerLeave.

Changelog: [Android][Fixed] - Prevent onPointerLeave from dispatching during button presses

Differential Revision: D72078450

Summary:
While investigating pointer events, I noticed that all Android views fire `onPointerLeave`/`onPointerEnter` in rapid succession on every button press. This is because Android fires `ACTION_HOVER_EXIT` on every frame before firing `ACTION_DOWN`. The logic in JSPointerDispatcher needed to be updated to account for this. 

Unfortunately, `ACTION_HOVER_EXIT` events have no means of distinguishing between whether they were driven by the mouse actually leaving the view's bounds or by a button press. Some OS implementations fire this event on the frame just before leaving the view's boundaries while others fire after, so pure X/Y position isn't helpful enough. The button state property on `ACTION_HOVER_EXIT` also never gets set in some OS.

To work around this issue, this change posts a callback to the very next frame after receiving `ACTION_HOVER_EXIT`. If no `ACTION_DOWN` event was received in the same frame, it calls all the way through the existing logic. But, if an `ACTION_DOWN` event *is* received, we compare the event timestamps and if they match we don't post `onPointerLeave`.

Changelog: [Android][Fixed] - Prevent onPointerLeave from dispatching during button presses

Differential Revision: D72078450
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 31, 2025
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D72078450

@facebook-github-bot
Copy link
Contributor

This pull request has been merged in 833ab6f.

@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @Abbondanzo in 833ab6f

When will my fix make it into a release? | How to file a pick request?

@Abbondanzo Abbondanzo deleted the export-D72078450 branch April 8, 2025 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. p: Facebook Partner: Facebook Partner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants