Bug 1075253 - Consecutive taps should only emit one gesture. r=yzen

This commit is contained in:
Eitan Isaacson 2014-10-15 14:55:30 -07:00
parent 9b0f8d2661
commit baf4b2c65c
3 changed files with 49 additions and 20 deletions

View File

@ -7,15 +7,15 @@
/******************************************************************************
All gestures have the following pathways when being resolved(v)/rejected(x):
Tap -> DoubleTap (v)
Tap -> DoubleTap (x)
-> Dwell (x)
-> Swipe (x)
AndroidTap -> TripleTap (v)
AndroidTap -> TripleTap (x)
-> TapHold (x)
-> Swipe (x)
DoubleTap -> TripleTap (v)
DoubleTap -> TripleTap (x)
-> TapHold (x)
-> Explore (x)
@ -360,6 +360,7 @@ Gesture.prototype = {
* Clear the existing timer.
*/
clearTimer: function Gesture_clearTimer() {
Logger.gesture('clearTimeout', this.type);
clearTimeout(this._timer);
delete this._timer;
},
@ -370,9 +371,11 @@ Gesture.prototype = {
* started the gesture resolution sequence.
*/
startTimer: function Gesture_startTimer(aTimeStamp) {
Logger.gesture('startTimer', this.type);
this.clearTimer();
let delay = this._getDelay(aTimeStamp);
let handler = () => {
Logger.gesture('timer handler');
delete this._timer;
if (!this._inProgress) {
this._deferred.reject();
@ -672,14 +675,17 @@ DoubleTapHoldEnd.prototype.type = 'doubletapholdend';
* the gesture resolution sequence.
* @param {Object} aPoints An existing set of points (from previous events).
* @param {?String} aLastEvent Last pointer event type.
* @param {Function} aRejectTo A constructor for the next gesture to reject to
* in case no pointermove or pointerup happens within the
* @param {Function} aRejectToOnWait A constructor for the next gesture to
* reject to in case no pointermove or pointerup happens within the
* GestureSettings.dwellThreshold.
* @param {Function} aRejectToOnPointerDown A constructor for the gesture to
* reject to if a finger comes down immediately after the tap.
* @param {Function} aTravelTo An optional constuctor for the next gesture to
* reject to in case the the TravelGesture test fails.
*/
function TapGesture(aTimeStamp, aPoints, aLastEvent, aRejectTo, aTravelTo) {
this._rejectToOnWait = aRejectTo;
function TapGesture(aTimeStamp, aPoints, aLastEvent, aRejectToOnWait, aTravelTo, aRejectToOnPointerDown) {
this._rejectToOnWait = aRejectToOnWait;
this._rejectToOnPointerDown = aRejectToOnPointerDown;
// If the pointer travels, reject to aTravelTo.
TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent, aTravelTo,
TAP_MAX_RADIUS);
@ -693,6 +699,31 @@ TapGesture.prototype._getDelay = function TapGesture__getDelay() {
return GestureSettings.dwellThreshold;
};
TapGesture.prototype.pointerup = function TapGesture_pointerup(aPoints) {
if (this._rejectToOnPointerDown) {
let complete = this._update(aPoints, 'pointerup', false, true);
if (complete) {
this.clearTimer();
this._pointerUpTimer = setTimeout(() => {
delete this._pointerUpTimer;
this._deferred.resolve();
}, GestureSettings.maxConsecutiveGestureDelay);
}
} else {
TravelGesture.prototype.pointerup.call(this, aPoints);
}
};
TapGesture.prototype.pointerdown = function TapGesture_pointerdown(aPoints, aTimeStamp) {
TravelGesture.prototype.pointerdown.call(this, aPoints, aTimeStamp);
if (this._pointerUpTimer) {
clearTimeout(this._pointerUpTimer);
delete this._pointerUpTimer;
this._deferred.reject(this._rejectToOnPointerDown);
}
};
/**
* Tap gesture.
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
@ -702,12 +733,11 @@ TapGesture.prototype._getDelay = function TapGesture__getDelay() {
*/
function Tap(aTimeStamp, aPoints, aLastEvent) {
// If the pointer travels, reject to Swipe.
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, Dwell, Swipe);
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, Dwell, Swipe, DoubleTap);
}
Tap.prototype = Object.create(TapGesture.prototype);
Tap.prototype.type = 'tap';
Tap.prototype.resolveTo = DoubleTap;
/**
* Tap (multi) gesture on Android.
@ -719,12 +749,11 @@ Tap.prototype.resolveTo = DoubleTap;
function AndroidTap(aTimeStamp, aPoints, aLastEvent) {
// If the pointer travels, reject to Swipe. On dwell threshold reject to
// TapHold.
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, Swipe);
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, Swipe, TripleTap);
}
AndroidTap.prototype = Object.create(TapGesture.prototype);
// Android double taps are translated to single taps.
AndroidTap.prototype.type = 'doubletap';
AndroidTap.prototype.resolveTo = TripleTap;
/**
* Clear the pointerup handler timer in case of the 3 pointer swipe.
@ -767,12 +796,12 @@ AndroidTap.prototype.pointerup = function AndroidTap_pointerup(aPoints) {
* @param {?String} aLastEvent Last pointer event type.
*/
function DoubleTap(aTimeStamp, aPoints, aLastEvent) {
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold);
this._inProgress = true;
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, null, TripleTap);
}
DoubleTap.prototype = Object.create(TapGesture.prototype);
DoubleTap.prototype.type = 'doubletap';
DoubleTap.prototype.resolveTo = TripleTap;
/**
* Triple Tap gesture.
@ -782,6 +811,7 @@ DoubleTap.prototype.resolveTo = TripleTap;
* @param {?String} aLastEvent Last pointer event type.
*/
function TripleTap(aTimeStamp, aPoints, aLastEvent) {
this._inProgress = true;
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, DoubleTapHold);
}

View File

@ -117,7 +117,7 @@ function testMozAccessFuGesture(aExpectedGestures) {
return;
}
is(!!aEvent.detail.edge, !!types[0].edge);
ok(true, 'Received correct mozAccessFuGesture: ' + types.shift() + '.');
ok(true, 'Received correct mozAccessFuGesture: ' + JSON.stringify(types.shift()) + '.');
if (types.length === 0) {
win.removeEventListener('mozAccessFuGesture', handleGesture);
if (AccessFuTest.sequenceCleanup) {

View File

@ -36,7 +36,7 @@
{"type": "pointerup",
"points": [{"x": 0.97, "y": 1.01, "identifier": 1}]}
],
"expectedGestures": [{ "type": "tap" }, { "type": "doubletap" }]
"expectedGestures": [{ "type": "doubletap" }]
},
{
"events": [
@ -47,7 +47,7 @@
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
],
"expectedGestures": [{ "type": "tap" }, { "type": "doubletap" }, { "type": "tripletap" }]
"expectedGestures": [{ "type": "tripletap" }]
},
{
"events": [
@ -59,8 +59,8 @@
"removeDwellThreshold": true},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
],
"expectedGestures": [{ "type": "tap" }, { "type": "doubletap" },
{ "type": "doubletaphold" }, { "type": "doubletapholdend" }]
"expectedGestures": [{ "type": "doubletaphold" },
{ "type": "doubletapholdend" }]
},
{
"events": [
@ -70,8 +70,7 @@
"removeDwellThreshold": true},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
],
"expectedGestures": [{ "type": "tap" }, { "type": "taphold" },
{ "type": "tapholdend" }]
"expectedGestures": [{ "type": "taphold" }, { "type": "tapholdend" }]
},
{
"events": [