Commit ad20d368 authored by Tong Mu's avatar Tong Mu Committed by Flutter GitHub Bot

Fix null event crash in TapGestureRecognizer (#45943)

parent a2005eaf
......@@ -398,6 +398,9 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
/// If non-null, the recognizer will call [didExceedDeadline] after this
/// amount of time has elapsed since starting to track the primary pointer.
///
/// The [didExceedDeadline] will not be called if the primary pointer is
/// accepted, rejected, or all pointers are up or canceled before [deadline].
final Duration deadline;
/// The maximum distance in logical pixels the gesture is allowed to drift
......@@ -495,7 +498,10 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
@override
void acceptGesture(int pointer) {
_gestureAccepted = true;
if (pointer == primaryPointer) {
_stopTimer();
_gestureAccepted = true;
}
}
@override
......
......@@ -582,6 +582,51 @@ void main() {
drag.dispose();
});
testGesture('non-primary pointers does not trigger timeout', (GestureTester tester) {
// Regression test for https://github.com/flutter/flutter/issues/43310
// Pointer1 down, pointer2 down, then pointer 1 up, all within the timeout.
// In this way, `BaseTapGestureRecognizer.didExceedDeadline` can be triggered
// after its `_reset`.
final TapGestureRecognizer tap = TapGestureRecognizer();
final List<String> recognized = <String>[];
tap.onTapDown = (_) {
recognized.add('down');
};
tap.onTapUp = (_) {
recognized.add('up');
};
tap.onTap = () {
recognized.add('tap');
};
tap.onTapCancel = () {
recognized.add('cancel');
};
tap.addPointer(down1);
tester.closeArena(down1.pointer);
tap.addPointer(down2);
tester.closeArena(down2.pointer);
expect(recognized, isEmpty);
tester.route(up1);
GestureBinding.instance.gestureArena.sweep(down1.pointer);
expect(recognized, <String>['down', 'up', 'tap']);
recognized.clear();
// If regression happens, the following step will throw error
tester.async.elapse(const Duration(milliseconds: 200));
expect(recognized, isEmpty);
tester.route(up2);
GestureBinding.instance.gestureArena.sweep(down2.pointer);
expect(recognized, isEmpty);
tap.dispose();
});
group('Enforce consistent-button restriction:', () {
// Change buttons during down-up sequence 1
const PointerMoveEvent move1lr = PointerMoveEvent(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment