Bug 940420 - It's nearly impossible to close browser app tabs with edge gestures enabled. r=smaug
authorVivien Nicolas <21@vingtetun.org>
Tue, 03 Dec 2013 16:10:47 +0100
changeset 173454 4771c427c785c88d0f1950ad3303a125d1028069
parent 173453 d1689276f1188d5518837e8c2e732ccdd4b40572
child 173455 f33904f2323d941e52ef3f8fa7a67410fafde16c
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs940420
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 940420 - It's nearly impossible to close browser app tabs with edge gestures enabled. r=smaug
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDOMWindowUtils.h
dom/browser-element/BrowserElementChildPreload.js
dom/interfaces/base/nsIDOMWindowUtils.idl
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -851,16 +851,55 @@ nsDOMWindowUtils::SendTouchEvent(const n
                                  uint32_t *aRys,
                                  float *aRotationAngles,
                                  float *aForces,
                                  uint32_t aCount,
                                  int32_t aModifiers,
                                  bool aIgnoreRootScrollFrame,
                                  bool *aPreventDefault)
 {
+  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
+                              aRotationAngles, aForces, aCount, aModifiers,
+                              aIgnoreRootScrollFrame, false, aPreventDefault);
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
+                                         uint32_t* aIdentifiers,
+                                         int32_t* aXs,
+                                         int32_t* aYs,
+                                         uint32_t* aRxs,
+                                         uint32_t* aRys,
+                                         float* aRotationAngles,
+                                         float* aForces,
+                                         uint32_t aCount,
+                                         int32_t aModifiers,
+                                         bool aIgnoreRootScrollFrame,
+                                         bool* aPreventDefault)
+{
+  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
+                              aRotationAngles, aForces, aCount, aModifiers,
+                              aIgnoreRootScrollFrame, true, aPreventDefault);
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
+                                       uint32_t* aIdentifiers,
+                                       int32_t* aXs,
+                                       int32_t* aYs,
+                                       uint32_t* aRxs,
+                                       uint32_t* aRys,
+                                       float* aRotationAngles,
+                                       float* aForces,
+                                       uint32_t aCount,
+                                       int32_t aModifiers,
+                                       bool aIgnoreRootScrollFrame,
+                                       bool aToWindow,
+                                       bool* aPreventDefault)
+{
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // get the widget to send the event to
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   if (!widget) {
@@ -895,16 +934,37 @@ nsDOMWindowUtils::SendTouchEvent(const n
                                   LayoutDeviceIntPoint::ToUntyped(pt),
                                   nsIntPoint(aRxs[i], aRys[i]),
                                   aRotationAngles[i],
                                   aForces[i]);
     event.touches.AppendElement(t);
   }
 
   nsEventStatus status;
+  if (aToWindow) {
+    nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
+    if (!presShell) {
+      return NS_ERROR_FAILURE;
+    }
+
+    nsViewManager* viewManager = presShell->GetViewManager();
+    if (!viewManager) {
+      return NS_ERROR_FAILURE;
+    }
+
+    nsView* view = viewManager->GetRootView();
+    if (!view) {
+      return NS_ERROR_FAILURE;
+    }
+
+    status = nsEventStatus_eIgnore;
+    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
+    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
+  }
+
   nsresult rv = widget->DispatchEvent(&event, status);
   *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
   return rv;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
                                int32_t aKeyCode,
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -43,12 +43,27 @@ protected:
                                   int32_t aClickCount,
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   float aPressure,
                                   unsigned short aInputSourceArg,
                                   bool aToWindow,
                                   bool *aPreventDefault);
 
+  NS_IMETHOD SendTouchEventCommon(const nsAString& aType,
+                                  uint32_t* aIdentifiers,
+                                  int32_t* aXs,
+                                  int32_t* aYs,
+                                  uint32_t* aRxs,
+                                  uint32_t* aRys,
+                                  float* aRotationAngles,
+                                  float* aForces,
+                                  uint32_t aCount,
+                                  int32_t aModifiers,
+                                  bool aIgnoreRootScrollFrame,
+                                  bool aToWindow,
+                                  bool* aPreventDefault);
+
+
   static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers);
 };
 
 #endif
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -834,28 +834,28 @@ BrowserElementChild.prototype = {
       sendAsyncMsg('visibilitychange', {visible: visible});
     }
   },
 
   _recvSendMouseEvent: function(data) {
     let json = data.json;
     let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils);
-    utils.sendMouseEvent(json.type, json.x, json.y, json.button,
-                         json.clickCount, json.modifiers);
+    utils.sendMouseEventToWindow(json.type, json.x, json.y, json.button,
+                                 json.clickCount, json.modifiers);
   },
 
   _recvSendTouchEvent: function(data) {
     let json = data.json;
     let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils);
-    utils.sendTouchEvent(json.type, json.identifiers, json.touchesX,
-                         json.touchesY, json.radiisX, json.radiisY,
-                         json.rotationAngles, json.forces, json.count,
-                         json.modifiers);
+    utils.sendTouchEventToWindow(json.type, json.identifiers, json.touchesX,
+                                 json.touchesY, json.radiisX, json.radiisY,
+                                 json.rotationAngles, json.forces, json.count,
+                                 json.modifiers);
   },
 
   _recvCanGoBack: function(data) {
     var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
     sendAsyncMsg('got-can-go-back', {
       id: data.json.id,
       successRv: webNav.canGoBack
     });
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -38,17 +38,17 @@ interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 
-[scriptable, uuid(3772df78-905f-40cf-952f-e4954c63d0ec)]
+[scriptable, uuid(3d9bf70c-5b83-11e3-9090-3c970e9f4238)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -308,16 +308,31 @@ interface nsIDOMWindowUtils : nsISupport
                               in float aY,
                               in long aButton,
                               in long aClickCount,
                               in long aModifiers,
                               [optional] in boolean aIgnoreRootScrollFrame,
                               [optional] in float aPressure,
                               [optional] in unsigned short aInputSourceArg);
 
+  /** The same as sendTouchEvent but ensures that the event is dispatched to
+   *  this DOM window or one of its children.
+   */
+  boolean sendTouchEventToWindow(in AString aType,
+                                 [array, size_is(count)] in uint32_t aIdentifiers,
+                                 [array, size_is(count)] in int32_t aXs,
+                                 [array, size_is(count)] in int32_t aYs,
+                                 [array, size_is(count)] in uint32_t aRxs,
+                                 [array, size_is(count)] in uint32_t aRys,
+                                 [array, size_is(count)] in float aRotationAngles,
+                                 [array, size_is(count)] in float aForces,
+                                 in uint32_t count,
+                                 in long aModifiers,
+                                 [optional] in boolean aIgnoreRootScrollFrame);
+
   /** Synthesize a wheel event for a window. The event types supported is only
    *  wheel.
    *
    * Events are sent in coordinates offset by aX and aY from the window.
    *
    * Cannot be accessed from unprivileged context (not content-accessible)
    * Will throw a DOM security error if called without chrome privileges.
    *