mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Ensure active touches are swept before accepting a child native gesture (#52995)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52995 Fabric retains views by ID when `JSTouchDispatcher` receives a touch event, but does not sweep these same views if a child native gesture is started between the `ACTION_DOWN` and `ACTION_UP` actions of the touch. As a result, we never end up calling into that view's manager's `onDropViewInstance` method and can't perform reliable teardown of the view since it's stuck in this "touched" state. This is change adds a new condition to check if `JSTouchDispatcher` should sweep active touches when a child native gesture is started, and only applies the check to `ReactSurfaceView` to start. The check is also only enabled if the `sweepActiveTouchOnChildNativeGesturesAndroid` flag is set. Changelog: [Internal] Reviewed By: jehartzog Differential Revision: D79230277 fbshipit-source-id: c15b888ec932319f1bda05b8ef5eec39e5d08710
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f2964e17cd
commit
87749470cc
+2
-1
@@ -116,7 +116,8 @@ public class ReactSurfaceView(context: Context?, private val surface: ReactSurfa
|
||||
*/
|
||||
override fun onChildStartedNativeGesture(childView: View?, ev: MotionEvent) {
|
||||
val eventDispatcher = surface.eventDispatcher ?: return
|
||||
jsTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher)
|
||||
jsTouchDispatcher.onChildStartedNativeGesture(
|
||||
ev, eventDispatcher, surface.reactHost?.currentReactContext)
|
||||
childView?.let { jsPointerDispatcher?.onChildStartedNativeGesture(it, ev, eventDispatcher) }
|
||||
}
|
||||
|
||||
|
||||
+18
@@ -13,6 +13,8 @@ import com.facebook.common.logging.FLog
|
||||
import com.facebook.infer.annotation.Assertions
|
||||
import com.facebook.react.bridge.ReactContext
|
||||
import com.facebook.react.common.ReactConstants
|
||||
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
||||
import com.facebook.react.uimanager.common.UIManagerType
|
||||
import com.facebook.react.uimanager.events.EventDispatcher
|
||||
import com.facebook.react.uimanager.events.TouchEvent
|
||||
@@ -33,9 +35,19 @@ public class JSTouchDispatcher(private val viewGroup: ViewGroup) {
|
||||
private val touchEventCoalescingKeyHelper: TouchEventCoalescingKeyHelper =
|
||||
TouchEventCoalescingKeyHelper()
|
||||
|
||||
@OptIn(UnstableReactNativeAPI::class)
|
||||
public fun onChildStartedNativeGesture(
|
||||
androidEvent: MotionEvent,
|
||||
eventDispatcher: EventDispatcher
|
||||
) {
|
||||
onChildStartedNativeGesture(androidEvent, eventDispatcher, null)
|
||||
}
|
||||
|
||||
@UnstableReactNativeAPI
|
||||
public fun onChildStartedNativeGesture(
|
||||
androidEvent: MotionEvent,
|
||||
eventDispatcher: EventDispatcher,
|
||||
reactContext: ReactContext?,
|
||||
) {
|
||||
if (childIsHandlingNativeGesture) {
|
||||
// This means we previously had another child start handling this native gesture and now a
|
||||
@@ -46,6 +58,12 @@ public class JSTouchDispatcher(private val viewGroup: ViewGroup) {
|
||||
|
||||
dispatchCancelEvent(androidEvent, eventDispatcher)
|
||||
childIsHandlingNativeGesture = true
|
||||
|
||||
if (targetTag != -1 && ReactNativeFeatureFlags.sweepActiveTouchOnChildNativeGesturesAndroid()) {
|
||||
val surfaceId = UIManagerHelper.getSurfaceId(viewGroup)
|
||||
sweepActiveTouchForTag(surfaceId, targetTag, reactContext)
|
||||
}
|
||||
|
||||
targetTag = -1
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user