Bug 1287576 - Update the touch-behavior notification code to behave like the set-target-apzc notification code. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 22 Jul 2016 13:05:56 -0400
changeset 391389 5f9f82980a2573a7ceac4e147e5f02619bfdba80
parent 391388 e683f020aafa4d67191d189048d202e0b7c0da13
child 526208 cbc1687d4d36bf9fdae7a87f161b7eeaa52a9f8e
push id23893
push userkgupta@mozilla.com
push dateFri, 22 Jul 2016 17:06:40 +0000
reviewersbotond
bugs1287576
milestone50.0a1
Bug 1287576 - Update the touch-behavior notification code to behave like the set-target-apzc notification code. r?botond In particular, this change uses the root frame of the touch target document, so that the correct presShell resolution is used when doing the touch-action hit test. MozReview-Commit-ID: LIHi8J1ZNzw
dom/ipc/TabChild.cpp
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/apz/util/APZCCallbackHelper.h
gfx/layers/apz/util/TouchActionHelper.cpp
gfx/layers/apz/util/TouchActionHelper.h
widget/nsBaseWidget.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2004,21 +2004,21 @@ TabChild::RecvRealTouchEvent(const Widge
 
   WidgetTouchEvent localEvent(aEvent);
   localEvent.mWidget = mPuppetWidget;
 
   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
       mPuppetWidget->GetDefaultScale());
 
   if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
+    nsCOMPtr<nsIDocument> document = GetDocument();
     if (gfxPrefs::TouchActionEnabled()) {
       APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(mPuppetWidget,
-          localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
+          document, localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
     }
-    nsCOMPtr<nsIDocument> document = GetDocument();
     APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
         localEvent, aGuid, aInputBlockId);
   }
 
   // Dispatch event to content (potentially a long-running operation)
   nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
 
   if (!AsyncPanZoomEnabled()) {
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -773,27 +773,34 @@ APZCCallbackHelper::SendSetTargetAPZCNot
       }
     }
   }
 }
 
 void
 APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
         nsIWidget* aWidget,
+        nsIDocument* aDocument,
         const WidgetTouchEvent& aEvent,
         uint64_t aInputBlockId,
         const SetAllowedTouchBehaviorCallback& aCallback)
 {
-  nsTArray<TouchBehaviorFlags> flags;
-  for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
-    flags.AppendElement(
-      TouchActionHelper::GetAllowedTouchBehavior(aWidget,
-        aEvent.mTouches[i]->mRefPoint));
+  if (nsIPresShell* shell = aDocument->GetShell()) {
+    if (nsIFrame* rootFrame = shell->GetRootFrame()) {
+      rootFrame = UpdateRootFrameForTouchTargetDocument(rootFrame);
+
+      nsTArray<TouchBehaviorFlags> flags;
+      for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
+        flags.AppendElement(
+          TouchActionHelper::GetAllowedTouchBehavior(aWidget,
+                rootFrame, aEvent.mTouches[i]->mRefPoint));
+      }
+      aCallback(aInputBlockId, Move(flags));
+    }
   }
-  aCallback(aInputBlockId, Move(flags));
 }
 
 void
 APZCCallbackHelper::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
 {
   nsCOMPtr<nsIContent> targetContent = nsLayoutUtils::FindContentFor(aScrollId);
   if (!targetContent) {
     return;
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -136,16 +136,17 @@ public:
                                               nsIDocument* aDocument,
                                               const WidgetGUIEvent& aEvent,
                                               const ScrollableLayerGuid& aGuid,
                                               uint64_t aInputBlockId);
 
     /* Figure out the allowed touch behaviors of each touch point in |aEvent|
      * and send that information to the provided callback. */
     static void SendSetAllowedTouchBehaviorNotification(nsIWidget* aWidget,
+                                                        nsIDocument* aDocument,
                                                         const WidgetTouchEvent& aEvent,
                                                         uint64_t aInputBlockId,
                                                         const SetAllowedTouchBehaviorCallback& aCallback);
 
     /* Notify content of a mouse scroll testing event. */
     static void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent);
 
     /* Notify content that the repaint flush is complete. */
--- a/gfx/layers/apz/util/TouchActionHelper.cpp
+++ b/gfx/layers/apz/util/TouchActionHelper.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TouchActionHelper.h"
 
 #include "mozilla/layers/APZCTreeManager.h"
 #include "nsContainerFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsLayoutUtils.h"
-#include "nsView.h"
 
 namespace mozilla {
 namespace layers {
 
 void
 TouchActionHelper::UpdateAllowedBehavior(uint32_t aTouchActionValue,
                                          bool aConsiderPanning,
                                          TouchBehaviorFlags& aOutBehavior)
@@ -41,32 +40,26 @@ TouchActionHelper::UpdateAllowedBehavior
     } else if ((aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_Y) && !(aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_X)) {
       aOutBehavior &= ~AllowedTouchBehavior::HORIZONTAL_PAN;
     }
   }
 }
 
 TouchBehaviorFlags
 TouchActionHelper::GetAllowedTouchBehavior(nsIWidget* aWidget,
+                                           nsIFrame* aRootFrame,
                                            const LayoutDeviceIntPoint& aPoint)
 {
-  nsView *view = nsView::GetViewFor(aWidget);
   TouchBehaviorFlags behavior = AllowedTouchBehavior::VERTICAL_PAN | AllowedTouchBehavior::HORIZONTAL_PAN |
                                 AllowedTouchBehavior::PINCH_ZOOM | AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
 
-  if (!view) {
-    return behavior;
-  }
+  nsPoint relativePoint =
+    nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, aRootFrame);
 
-  nsIFrame *viewFrame = view->GetFrame();
-
-  nsPoint relativePoint =
-    nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, viewFrame);
-
-  nsIFrame *target = nsLayoutUtils::GetFrameForPoint(viewFrame, relativePoint, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
+  nsIFrame *target = nsLayoutUtils::GetFrameForPoint(aRootFrame, relativePoint, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
   if (!target) {
     return behavior;
   }
   nsIScrollableFrame *nearestScrollableParent = nsLayoutUtils::GetNearestScrollableFrame(target, 0);
   nsIFrame* nearestScrollableFrame = do_QueryFrame(nearestScrollableParent);
 
   // We're walking up the DOM tree until we meet the element with touch behavior and accumulating
   // touch-action restrictions of all elements in this chain.
--- a/gfx/layers/apz/util/TouchActionHelper.h
+++ b/gfx/layers/apz/util/TouchActionHelper.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __mozilla_layers_TouchActionHelper_h__
 #define __mozilla_layers_TouchActionHelper_h__
 
 #include "mozilla/layers/APZUtils.h" // for TouchBehaviorFlags
 
+class nsIFrame;
 class nsIWidget;
 
 namespace mozilla {
 namespace layers {
 
 /*
  * Helper class to figure out the allowed touch behavior for frames, as per
  * the touch-action spec.
@@ -26,15 +27,16 @@ private:
 
 public:
   /*
    * Performs hit testing on content, finds frame that corresponds to the aPoint and retrieves
    * touch-action css property value from it according the rules specified in the spec:
    * http://www.w3.org/TR/pointerevents/#the-touch-action-css-property.
    */
   static TouchBehaviorFlags GetAllowedTouchBehavior(nsIWidget* aWidget,
+                                                    nsIFrame* aRootFrame,
                                                     const LayoutDeviceIntPoint& aPoint);
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /*__mozilla_layers_TouchActionHelper_h__ */
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1116,17 +1116,17 @@ nsBaseWidget::ProcessUntransformedAPZEve
     // EventStateManager did not route the event into the child process.
     // It's safe to communicate to APZ that the event has been processed.
     // TODO: Eventually we'll be able to move the SendSetTargetAPZCNotification
     // call into APZEventState::Process*Event() as well.
     if (WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent()) {
       if (touchEvent->mMessage == eTouchStart) {
         if (gfxPrefs::TouchActionEnabled()) {
           APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(this,
-              *(original->AsTouchEvent()), aInputBlockId,
+              GetDocument(), *(original->AsTouchEvent()), aInputBlockId,
               mSetAllowedTouchBehaviorCallback);
         }
         APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
             *(original->AsTouchEvent()), aGuid, aInputBlockId);
       }
       mAPZEventState->ProcessTouchEvent(*touchEvent, aGuid, aInputBlockId,
           aApzResponse, status);
     } else if (WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent()) {