Fix null event crash in TapGestureRecognizer (#45943)
This commit is contained in:
parent
a2005eaf9a
commit
ad20d368ff
@ -398,6 +398,9 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
|
|||||||
|
|
||||||
/// If non-null, the recognizer will call [didExceedDeadline] after this
|
/// If non-null, the recognizer will call [didExceedDeadline] after this
|
||||||
/// amount of time has elapsed since starting to track the primary pointer.
|
/// 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;
|
final Duration deadline;
|
||||||
|
|
||||||
/// The maximum distance in logical pixels the gesture is allowed to drift
|
/// The maximum distance in logical pixels the gesture is allowed to drift
|
||||||
@ -495,8 +498,11 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void acceptGesture(int pointer) {
|
void acceptGesture(int pointer) {
|
||||||
|
if (pointer == primaryPointer) {
|
||||||
|
_stopTimer();
|
||||||
_gestureAccepted = true;
|
_gestureAccepted = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void rejectGesture(int pointer) {
|
void rejectGesture(int pointer) {
|
||||||
|
@ -582,6 +582,51 @@ void main() {
|
|||||||
drag.dispose();
|
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:', () {
|
group('Enforce consistent-button restriction:', () {
|
||||||
// Change buttons during down-up sequence 1
|
// Change buttons during down-up sequence 1
|
||||||
const PointerMoveEvent move1lr = PointerMoveEvent(
|
const PointerMoveEvent move1lr = PointerMoveEvent(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user