Bug Description
When a GestureArenaMember calls resolve(GestureDisposition.accepted) while the arena is open, it becomes the eagerWinner via state.eagerWinner ??= member. If that same member subsequently calls resolve(GestureDisposition.rejected) while the arena is still open, _resolve removes the member from state.members but never clears state.eagerWinner. This leaves a dangling reference to an already-rejected-and-removed member.
When the arena later closes, _tryToResolveArena checks state.eagerWinner != null and delegates to _resolveInFavorOf with the stale member. This causes:
- The stale member to receive
acceptGesture despite having already been rejected (assertion failure in debug mode via _CombiningGestureArenaMember._close)
- All remaining legitimate members to be incorrectly rejected
Steps to Reproduce
- Add 3 members (A, B, C) to a gesture arena
- Member A calls
resolve(accepted) → becomes eagerWinner
- Member A calls
resolve(rejected) → removed from members, but eagerWinner still points to A
- Close the arena → stale eagerWinner (A) incorrectly wins, B and C are rejected
Expected Behavior
When a rejected member was the eagerWinner, eagerWinner should be cleared so the arena resolves normally among remaining members.
Fix
PR: #187008
Clear state.eagerWinner in the rejected case when the rejected member matches the current eagerWinner:
case GestureDisposition.rejected:
if (state.eagerWinner == member) {
state.eagerWinner = null;
}
state.members.remove(member);
Bug Description
When a
GestureArenaMembercallsresolve(GestureDisposition.accepted)while the arena is open, it becomes theeagerWinnerviastate.eagerWinner ??= member. If that same member subsequently callsresolve(GestureDisposition.rejected)while the arena is still open,_resolveremoves the member fromstate.membersbut never clearsstate.eagerWinner. This leaves a dangling reference to an already-rejected-and-removed member.When the arena later closes,
_tryToResolveArenachecksstate.eagerWinner != nulland delegates to_resolveInFavorOfwith the stale member. This causes:acceptGesturedespite having already been rejected (assertion failure in debug mode via_CombiningGestureArenaMember._close)Steps to Reproduce
resolve(accepted)→ becomes eagerWinnerresolve(rejected)→ removed from members, but eagerWinner still points to AExpected Behavior
When a rejected member was the eagerWinner,
eagerWinnershould be cleared so the arena resolves normally among remaining members.Fix
PR: #187008
Clear
state.eagerWinnerin the rejected case when the rejected member matches the current eagerWinner: