Skip to content

Commit 0bd09c0

Browse files
ryancatfacebook-github-bot
authored andcommittedDec 17, 2021
Change touch target lookup to exclude overflow hidden view group
Summary: In D30104853 (facebook@e35a963), we added fix to the issue where touches on the child view that is outside of its parent view's boundary are not registered. The only exception to that is if the parent view has overflow style `overflow: hidden`. In that case, touches happen outside of the parent view should be ignored. {F686521911} That fix works, but it increases the complexity for the DFS algorithm used to find the touch target in two ways: 1. Before we only traverse views that contain the touch event point. If the touch event point is outside of the view, we won't step in and traverse that part of the tree. This is actually what caused the initial problem. The fix removed that boundary check (where `isTransformedTouchPointInView` used to do) and push it later. This increases the number of tree traversal a lot. 2. The check for `overflow: hidden` is happened after we find a potential target view, which means we've spent time to find the target view before we decide if the target view is even a candidate. This diff aims to update for the #2 item above. Since we are checking the style of the parent view, not the target view, it's not necessary to check that after we find the target view. We could check the parent view and if it has `overflow: hidden` on it, any pointer event that are not in the boundary can be ignored already. Changelog: [Internal][Android] Reviewed By: mdvacca, ShikaSD Differential Revision: D33079157 fbshipit-source-id: c79c2b38b8affb9ea0fd25b5e880b22466ab7ed9
1 parent 41cad35 commit 0bd09c0

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed
 

‎ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java

+11-16
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@ private static View findTouchTargetView(
178178
// We prefer returning a child, so we check for a child that can handle the touch first
179179
if (allowReturnTouchTargetTypes.contains(TouchTargetReturnType.CHILD)
180180
&& view instanceof ViewGroup) {
181+
// We don't allow touches on views that are outside the bounds of an `overflow: hidden` and
182+
// `overflow: scroll` View.
183+
if (view instanceof ReactOverflowView) {
184+
@Nullable String overflow = ((ReactOverflowView) view).getOverflow();
185+
if ((ViewProps.HIDDEN.equals(overflow) || ViewProps.SCROLL.equals(overflow))
186+
&& !isTouchPointInView(eventCoords[0], eventCoords[1], view)) {
187+
return null;
188+
}
189+
}
190+
181191
ViewGroup viewGroup = (ViewGroup) view;
182192
int childrenCount = viewGroup.getChildCount();
183193
// Consider z-index when determining the touch target.
@@ -198,22 +208,7 @@ private static View findTouchTargetView(
198208
eventCoords[1] = childPoint.y;
199209
View targetView = findTouchTargetViewWithPointerEvents(eventCoords, child, pathAccumulator);
200210
if (targetView != null) {
201-
// We don't allow touches on views that are outside the bounds of an `overflow: hidden`
202-
// View
203-
boolean inOverflowBounds = true;
204-
if (viewGroup instanceof ReactOverflowView) {
205-
@Nullable String overflow = ((ReactOverflowView) viewGroup).getOverflow();
206-
if ((ViewProps.HIDDEN.equals(overflow) || ViewProps.SCROLL.equals(overflow))
207-
&& !isTouchPointInView(restoreX, restoreY, view)) {
208-
inOverflowBounds = false;
209-
}
210-
}
211-
if (inOverflowBounds) {
212-
return targetView;
213-
} else if (pathAccumulator != null) {
214-
// Not a hit, reset the path found so far
215-
pathAccumulator.clear();
216-
}
211+
return targetView;
217212
}
218213
eventCoords[0] = restoreX;
219214
eventCoords[1] = restoreY;

0 commit comments

Comments
 (0)
Please sign in to comment.