Fix tapcancel on slop.

Make sure to send tapcancel when the primary pointer fails because of
slop, even if the gesture won by default.

Also, minor cleanup and clarification of an invariant.
This commit is contained in:
Ian Hickson 2015-11-06 22:48:25 -08:00
parent 4e329a6731
commit c40cb176e3
4 changed files with 21 additions and 4 deletions

View File

@ -146,8 +146,7 @@ class GestureArena {
} else {
assert(disposition == GestureDisposition.accepted);
if (state.isOpen) {
if (state.eagerWinner == null)
state.eagerWinner = member;
state.eagerWinner ??= member;
} else {
_resolveInFavorOf(key, state, member);
}
@ -166,4 +165,4 @@ class GestureArena {
}
member.acceptGesture(key);
}
}
}

View File

@ -112,7 +112,7 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
// TODO(abarth): Maybe factor the slop handling out into a separate class?
if (event.type == 'pointermove' && _getDistance(event) > kTouchSlop) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(event.pointer);
stopTrackingPointer(primaryPointer);
} else {
handlePrimaryPointer(event);
}

View File

@ -43,6 +43,15 @@ class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
}
}
void resolve(GestureDisposition disposition) {
if (_wonArena && disposition == GestureDisposition.rejected) {
if (onTapCancel != null)
onTapCancel();
_reset();
}
super.resolve(disposition);
}
void didExceedDeadline() {
_checkDown();
}

View File

@ -161,19 +161,28 @@ void main() {
tap.onTap = () {
tapRecognized = true;
};
bool tapCanceled = false;
tap.onTapCancel = () {
tapCanceled = true;
};
tap.addPointer(down3);
GestureArena.instance.close(3);
expect(tapRecognized, isFalse);
expect(tapCanceled, isFalse);
router.route(down3);
expect(tapRecognized, isFalse);
expect(tapCanceled, isFalse);
router.route(move3);
expect(tapRecognized, isFalse);
expect(tapCanceled, isTrue);
router.route(up3);
expect(tapRecognized, isFalse);
expect(tapCanceled, isTrue);
GestureArena.instance.sweep(3);
expect(tapRecognized, isFalse);
expect(tapCanceled, isTrue);
tap.dispose();
});