Drag gesture recognizer accepts all pointers when any pointer is accepted (#82786)
This commit is contained in:
parent
8f536ec17b
commit
4c1709642a
@ -365,6 +365,10 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
|
||||
localPosition: correctedPosition.local,
|
||||
);
|
||||
}
|
||||
// This acceptGesture might have been called only for one pointer, instead
|
||||
// of all pointers. Resolve all pointers to `accepted`. This won't cause
|
||||
// infinite recursion because an accepted pointer won't be accepted again.
|
||||
resolve(GestureDisposition.accepted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1440,4 +1440,48 @@ void main() {
|
||||
logs.clear();
|
||||
},
|
||||
);
|
||||
|
||||
testGesture('Does not crash when one of the 2 pointers wins by default and is then released', (GestureTester tester) {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/82784
|
||||
|
||||
bool didStartDrag = false;
|
||||
final HorizontalDragGestureRecognizer drag = HorizontalDragGestureRecognizer()
|
||||
..onStart = (_) { didStartDrag = true; }
|
||||
..onEnd = (DragEndDetails details) {} // Crash triggers at onEnd.
|
||||
..dragStartBehavior = DragStartBehavior.down;
|
||||
final TapGestureRecognizer tap = TapGestureRecognizer()..onTap = () {};
|
||||
final TapGestureRecognizer tap2 = TapGestureRecognizer()..onTap = () {};
|
||||
|
||||
// The pointer1 is caught by drag and tap.
|
||||
final TestPointer pointer1 = TestPointer(5);
|
||||
final PointerDownEvent down1 = pointer1.down(const Offset(10.0, 10.0));
|
||||
drag.addPointer(down1);
|
||||
tap.addPointer(down1);
|
||||
tester.closeArena(pointer1.pointer);
|
||||
tester.route(down1);
|
||||
|
||||
// The pointer2 is caught by drag and tap2.
|
||||
final TestPointer pointer2 = TestPointer(6);
|
||||
final PointerDownEvent down2 = pointer2.down(const Offset(10.0, 10.0));
|
||||
drag.addPointer(down2);
|
||||
tap2.addPointer(down2);
|
||||
tester.closeArena(pointer2.pointer);
|
||||
tester.route(down2);
|
||||
|
||||
// The tap is disposed, leaving drag the default winner.
|
||||
tap.dispose();
|
||||
|
||||
// Wait for microtasks to finish, during which drag claims victory.
|
||||
tester.async.flushMicrotasks();
|
||||
expect(didStartDrag, true);
|
||||
|
||||
// The pointer1 is released, leaving pointer2 drag's only pointer.
|
||||
tester.route(pointer1.up());
|
||||
|
||||
drag.dispose();
|
||||
|
||||
// Passes if no crashes here.
|
||||
|
||||
tap2.dispose();
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user