Skip to content

Commit

Permalink
Back out "PointerEvents: Don't dispatch when no listeners for hover e…
Browse files Browse the repository at this point in the history
…vents" because hover events stopped working in felios apps in headsets

Summary:
Changelog: [Internal][Changed]

The diff I'm backing out accidentally made Hover events in Felios apps that use RN under the hood stopped working in headsets (Oculus, Arcata). So we can't test our apps properly without these events.

We, with the diff author Luna tried to fix that but it turned out to be not easy so we decided to revert the commit in order to unblock experiences teams.

Original commit changeset: d6b5c32ae50b

Original Phabricator Diff: D36601638 (40769f2)

(Note: this ignores all push blocking failures!)

Reviewed By: arhelmus

Differential Revision: D37135208

fbshipit-source-id: 4f7d5f168b795690e951ce7063ae3feec3338772
  • Loading branch information
Artem Goncharov authored and facebook-github-bot committed Jun 14, 2022
1 parent 5471afe commit bcc69df
Showing 1 changed file with 41 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,7 @@ public void handleMotionEvent(MotionEvent motionEvent, EventDispatcher eventDisp

if (!supportsHover) {
dispatchNonBubblingEventForPathWhenListened(
EVENT.ENTER,
EVENT.ENTER_CAPTURE,
hitPath,
eventDispatcher,
surfaceId,
motionEvent,
false);
EVENT.ENTER, EVENT.ENTER_CAPTURE, hitPath, eventDispatcher, surfaceId, motionEvent);
}

boolean listeningForDown =
Expand Down Expand Up @@ -202,13 +196,7 @@ public void handleMotionEvent(MotionEvent motionEvent, EventDispatcher eventDisp

if (!supportsHover) {
dispatchNonBubblingEventForPathWhenListened(
EVENT.LEAVE,
EVENT.LEAVE_CAPTURE,
hitPath,
eventDispatcher,
surfaceId,
motionEvent,
false);
EVENT.LEAVE, EVENT.LEAVE_CAPTURE, hitPath, eventDispatcher, surfaceId, motionEvent);
}
return;
}
Expand Down Expand Up @@ -239,28 +227,22 @@ private static boolean isAnyoneListeningForBubblingEvent(
return false;
}

/**
* Dispatch event only if ancestor is listening to relevant capture event. This should only be
* relevant for ENTER/LEAVE events that need to be dispatched along every relevant view in the hit
* path.
*
* @param pointerEventType - Should only be ENTER/LEAVE events
* @param hitPath - ViewTargets ordered from target -> root
* @param dispatcher
* @param surfaceId
* @param motionEvent
* @param forceDispatch - Ignore if ancestor is listening and force the event to be dispatched
/*
Dispatch event only if ancestor is listening to relevant event.
This should only be relevant for ENTER/LEAVE events.
@param hitPath - ordered from inner target to root
*/

/** Dispatch non-bubbling event along the hit path only when relevant listeners */
private static void dispatchNonBubblingEventForPathWhenListened(
EVENT event,
EVENT captureEvent,
List<ViewTarget> hitPath,
EventDispatcher dispatcher,
int surfaceId,
MotionEvent motionEvent,
boolean forceDispatch) {
MotionEvent motionEvent) {

boolean ancestorListening = forceDispatch;
boolean ancestorListening = false;
String eventName = PointerEventHelper.getDispatchableEventName(event);
if (eventName == null) {
return;
Expand Down Expand Up @@ -330,72 +312,54 @@ private void handleHoverEvent(
// hitState is list ordered from inner child -> parent tag
// Traverse hitState back-to-front to find the first divergence with mLastHitState
// FIXME: this may generate incorrect events when view collapsing changes the hierarchy
boolean nonDivergentListeningToEnter = false;
boolean nonDivergentListeningToLeave = false;
int firstDivergentIndexFromBack = 0;
while (firstDivergentIndexFromBack < Math.min(hitPath.size(), mLastHitPath.size())
int firstDivergentIndex = 0;
while (firstDivergentIndex < Math.min(hitPath.size(), mLastHitPath.size())
&& hitPath
.get(hitPath.size() - 1 - firstDivergentIndexFromBack)
.equals(mLastHitPath.get(mLastHitPath.size() - 1 - firstDivergentIndexFromBack))) {

// Track if any non-diverging views are listening to enter/leave
View nonDivergentViewTargetView =
hitPath.get(hitPath.size() - 1 - firstDivergentIndexFromBack).getView();
if (!nonDivergentListeningToEnter
&& PointerEventHelper.isListening(nonDivergentViewTargetView, EVENT.ENTER_CAPTURE)) {
nonDivergentListeningToEnter = true;
}
if (!nonDivergentListeningToLeave
&& PointerEventHelper.isListening(nonDivergentViewTargetView, EVENT.LEAVE_CAPTURE)) {
nonDivergentListeningToLeave = true;
}

firstDivergentIndexFromBack++;
.get(hitPath.size() - 1 - firstDivergentIndex)
.equals(mLastHitPath.get(mLastHitPath.size() - 1 - firstDivergentIndex))) {
firstDivergentIndex++;
}

boolean hasDiverged =
firstDivergentIndexFromBack < Math.max(hitPath.size(), mLastHitPath.size());
boolean hasDiverged = firstDivergentIndex < Math.max(hitPath.size(), mLastHitPath.size());

// Fire all relevant enter events
if (hasDiverged) {
// If something has changed in either enter/exit, let's start a new coalescing key
mTouchEventCoalescingKeyHelper.incrementCoalescingKey(mHoverInteractionKey);

List<ViewTarget> enterViewTargets =
hitPath.subList(0, hitPath.size() - firstDivergentIndexFromBack);
List<ViewTarget> enterViewTargets = hitPath.subList(0, hitPath.size() - firstDivergentIndex);
if (enterViewTargets.size() > 0) {
dispatchNonBubblingEventForPathWhenListened(
EVENT.ENTER,
EVENT.ENTER_CAPTURE,
enterViewTargets,
eventDispatcher,
surfaceId,
motionEvent,
nonDivergentListeningToEnter);
// root -> child
for (int i = enterViewTargets.size(); i-- > 0; ) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_ENTER,
surfaceId,
enterViewTargets.get(i).getViewId(),
motionEvent));
}
}

// Fire all relevant exit events
List<ViewTarget> exitViewTargets =
mLastHitPath.subList(0, mLastHitPath.size() - firstDivergentIndexFromBack);
mLastHitPath.subList(0, mLastHitPath.size() - firstDivergentIndex);
if (exitViewTargets.size() > 0) {
// child -> root
dispatchNonBubblingEventForPathWhenListened(
EVENT.LEAVE,
EVENT.LEAVE_CAPTURE,
enterViewTargets,
eventDispatcher,
surfaceId,
motionEvent,
nonDivergentListeningToLeave);
for (ViewTarget exitViewTarget : exitViewTargets) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_LEAVE,
surfaceId,
exitViewTarget.getViewId(),
motionEvent));
}
}
}

int coalescingKey = mTouchEventCoalescingKeyHelper.getCoalescingKey(mHoverInteractionKey);
boolean listeningToMove =
isAnyoneListeningForBubblingEvent(hitPath, EVENT.MOVE, EVENT.MOVE_CAPTURE);
if (listeningToMove) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_MOVE, surfaceId, targetTag, motionEvent, coalescingKey));
}
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_MOVE, surfaceId, targetTag, motionEvent, coalescingKey));

mLastHitPath = hitPath;
mLastEventCoordinates[0] = x;
Expand Down Expand Up @@ -425,13 +389,7 @@ private void dispatchCancelEvent(
}

dispatchNonBubblingEventForPathWhenListened(
EVENT.LEAVE,
EVENT.LEAVE_CAPTURE,
hitPath,
eventDispatcher,
surfaceId,
motionEvent,
false);
EVENT.LEAVE, EVENT.LEAVE_CAPTURE, hitPath, eventDispatcher, surfaceId, motionEvent);

mTouchEventCoalescingKeyHelper.removeCoalescingKey(mDownStartTime);
mDownStartTime = TouchEvent.UNSET;
Expand Down

0 comments on commit bcc69df

Please sign in to comment.