Bug 599145 - Fix double tap radius calculation [r=stechz]
authorMatt Brubeck <mbrubeck@mozilla.com>
Thu, 23 Sep 2010 16:20:55 -0700
changeset 2061 d389eb72c4a00238eb891f3202ffda88c62d95e4
parent 2060 450b16d94ac9599ec58b937dc066bb4564b19c84
child 2062 e382aca88005250cb9ae9d0d8894c1bbd6d95edc
push id1745
push usermbrubeck@mozilla.com
push dateThu, 23 Sep 2010 23:21:19 +0000
reviewersstechz
bugs599145
Bug 599145 - Fix double tap radius calculation [r=stechz]
chrome/content/browser.js
chrome/content/input.js
--- a/chrome/content/browser.js
+++ b/chrome/content/browser.js
@@ -1334,17 +1334,17 @@ const ContentTouchHandler = {
             break;
           case "TapUp":
             this.tapUp(aEvent.clientX, aEvent.clientY);
             break;
           case "TapSingle":
             this.tapSingle(aEvent.clientX, aEvent.clientY, aEvent.modifiers);
             break;
           case "TapDouble":
-            this.tapDouble(aEvent.clientX1, aEvent.clientY1, aEvent.clientX2, aEvent.clientY2);
+            this.tapDouble(aEvent.clientX, aEvent.clientY, aEvent.modifiers);
             break;
           case "TapLong":
             this.tapLong();
             break;
         }
       }
     }
   },
@@ -1418,27 +1418,19 @@ const ContentTouchHandler = {
     TapHighlightHelper.hide(200);
     this._contextMenu = null;
 
     // Cancel the mouse click if we are showing a context menu
     if (!ContextHelper.popupState)
       this._dispatchMouseEvent("Browser:MouseUp", aX, aY, aModifiers);
   },
 
-  tapDouble: function tapDouble(aX1, aY1, aX2, aY2) {
+  tapDouble: function tapDouble(aX, aY, aModifiers) {
     this._clearPendingMessages();
-
-    const kDoubleClickRadius = 100;
-
-    let maxRadius = kDoubleClickRadius * getBrowser().scale;
-    let dx = aX2 - aX1;
-    let dy = aY1 - aY2;
-
-    if (dx*dx + dy*dy < maxRadius*maxRadius)
-      this._dispatchMouseEvent("Browser:ZoomToPoint", aX1, aY1);
+    this._dispatchMouseEvent("Browser:ZoomToPoint", aX, aY);
   },
 
   tapLong: function tapLong() {
     if (this._contextMenu) {
       if (ContextHelper.showPopup(this._contextMenu)) {
         // Stop all input sequences
         let event = document.createEvent("Events");
         event.initEvent("CancelTouchSequence", true, false);
--- a/chrome/content/input.js
+++ b/chrome/content/input.js
@@ -40,23 +40,22 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Maximum delay in ms between the two taps of a double-tap
 const kDoubleClickInterval = 400;
 
+// Maximum distance in screen pixels between the taps of a double-tap
+const kDoubleClickRadius = 100;
+
 // Amount of time to wait before tap becomes long tap
 const kLongTapWait = 500;
 
-// If a tap lasts longer than this duration in ms, treat it as a single-tap
-// immediately instead of waiting for a possible double tap.
-const kDoubleClickThreshold = 200;
-
 // threshold in pixels for sensing a tap as opposed to a pan
 const kTapRadius = Services.prefs.getIntPref("ui.dragThresholdX");
 
 // maximum drag distance in pixels while axis locking can still be reverted
 const kAxisLockRevertThreshold = 200;
 
 // Same as NS_EVENT_STATE_ACTIVE from nsIEventStateManager.h
 const kStateActive = 0x00000001;
@@ -384,48 +383,53 @@ MouseModule.prototype = {
       this._doDoubleClick();
     } else {
       this._singleClickTimeout.once(kDoubleClickInterval);
     }
   },
 
   /** Endpoint of _commitAnotherClick().  Finalize a single tap.  */
   _doSingleClick: function _doSingleClick() {
-    let ev = this._downUpEvents[1];
+    let mouseUp = this._downUpEvents[1];
     this._cleanClickBuffer();
-
-    // borrowed from nsIDOMNSEvent.idl
-    let modifiers =
-      (ev.altKey   ? Ci.nsIDOMNSEvent.ALT_MASK     : 0) |
-      (ev.ctrlKey  ? Ci.nsIDOMNSEvent.CONTROL_MASK : 0) |
-      (ev.shiftKey ? Ci.nsIDOMNSEvent.SHIFT_MASK   : 0) |
-      (ev.metaKey  ? Ci.nsIDOMNSEvent.META_MASK    : 0);
-
-    let event = document.createEvent("Events");
-    event.initEvent("TapSingle", true, false);
-    event.clientX = ev.clientX;
-    event.clientY = ev.clientY;
-    event.modifiers = modifiers;
-    ev.target.dispatchEvent(event);
+    this._dispatchTap("TapSingle", mouseUp);
   },
 
   /** Endpoint of _commitAnotherClick().  Finalize a double tap.  */
   _doDoubleClick: function _doDoubleClick() {
     let mouseUp1 = this._downUpEvents[1];
     // sometimes the second press event is not dispatched at all
     let mouseUp2 = this._downUpEvents[Math.min(3, this._downUpEvents.length - 1)];
     this._cleanClickBuffer();
 
+    let dx = mouseUp1.clientX - mouseUp2.clientX;
+    let dy = mouseUp1.clientY - mouseUp2.clientY;
+
+    if (dx*dx + dy*dy < kDoubleClickRadius*kDoubleClickRadius) {
+      this._dispatchTap("TapDouble", mouseUp1);
+    } else {
+      this._dispatchTap("TapSingle", mouseUp1);
+      this._dispatchTap("TapSingle", mouseUp2);
+    }
+  },
+
+  _dispatchTap: function _dispatchTap(aType, aMouseUpEvent) {
+    // borrowed from nsIDOMNSEvent.idl
+    let modifiers =
+      (aMouseUpEvent.altKey   ? Ci.nsIDOMNSEvent.ALT_MASK     : 0) |
+      (aMouseUpEvent.ctrlKey  ? Ci.nsIDOMNSEvent.CONTROL_MASK : 0) |
+      (aMouseUpEvent.shiftKey ? Ci.nsIDOMNSEvent.SHIFT_MASK   : 0) |
+      (aMouseUpEvent.metaKey  ? Ci.nsIDOMNSEvent.META_MASK    : 0);
+
     let event = document.createEvent("Events");
-    event.initEvent("TapDouble", true, false);
-    event.clientX1 = mouseUp1.clientX;
-    event.clientY1 = mouseUp1.clientY;
-    event.clientX2 = mouseUp1.clientX;
-    event.clientY2 = mouseUp1.clientY;
-    mouseUp1.target.dispatchEvent(event);
+    event.initEvent(aType, true, false);
+    event.clientX = aMouseUpEvent.clientX;
+    event.clientY = aMouseUpEvent.clientY;
+    event.modifiers = modifiers;
+    aMouseUpEvent.target.dispatchEvent(event);
   },
 
   /**
    * Record a mousedown/mouseup event for later redispatch via
    * _redispatchDownUpEvents()
    */
   _recordEvent: function _recordEvent(aEvent) {
     this._downUpEvents.push(aEvent);