You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: cancel zombie touch state on ScrollView pointer capture loss (#3) (#16100)
When a touch-screen user scrolls a ScrollView, the OS redirects the
pointer to the InteractionTracker via TryRedirectForManipulation and
fires PointerCaptureLost. The existing handler only cleaned up touches
when JS-level CapturePointer was active (m_pointerCapturingComponentTag
!= -1), which ScrollView never uses. This left a zombie entry in
m_activeTouches that kept Pressables visually stuck in a pressed state
and caused subsequent taps to replay events against the original target.
Three changes:
1. Extend onPointerCaptureLost to unconditionally cancel the active
touch for the specific pointer that lost capture, regardless of
whether JS-level CapturePointer was ever issued.
2. Remove the always-true fallback in IsPointerWithinInitialTree that
walked from activeTouch.touch.target (always the initial view) back
to initialTag, returning true on iteration 1 and bypassing the
correct W3C hit-test check. This caused onClick to fire even when
the pointer was released over a different target.
3. Scope per-pointer event dispatch in DispatchTouchEvent to only the
pointer that actually changed, instead of iterating every entry in
m_activeTouches. The old loop fired onPointerDown/Move/Up/Cancel
for all active touches, producing duplicated events in multi-touch
scenarios and replaying events on zombie targets.
"comment": "fix: cancel zombie touch state when ScrollView redirects pointer for manipulation, scope per-pointer events to the changed pointer, and remove always-true IsPointerWithinInitialTree fallback",
0 commit comments