Bug 1421384 - Inherit touch-action flags down in the compositor hit-test infos. r=miko
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 11 Jun 2018 08:29:24 -0400
changeset 479110 6659f392f4af0cef3cb4a5e19eef7e0e1b045f37
parent 479109 82c23620795156dd9bc070659ac8a42f91bd378a
child 479111 5182bca90d0609f182d5a7b6b48ed2ffbbce32c2
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiko
bugs1421384
milestone62.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 1421384 - Inherit touch-action flags down in the compositor hit-test infos. r=miko Per the touch-action spec, the effective touch-action on an element includes touch-action restrictions from ancestor elements up to and including the element that has the "default action". This patch implements that behaviour so that WebRender gets correct touch-action values on its display items. MozReview-Commit-ID: Cw5uqAsE9qm
gfx/layers/apz/test/mochitest/mochitest.ini
layout/generic/nsFrame.cpp
layout/painting/nsDisplayList.h
--- a/gfx/layers/apz/test/mochitest/mochitest.ini
+++ b/gfx/layers/apz/test/mochitest/mochitest.ini
@@ -64,17 +64,17 @@
 [test_bug1464568.html]
   skip-if = (toolkit == 'android') # setAsyncScrollOffset doesn't work on mobile
 [test_frame_reconstruction.html]
 [test_group_mouseevents.html]
   skip-if = (toolkit == 'android') # mouse events not supported on mobile
 [test_group_pointerevents.html]
   skip-if = os == 'win' && os_version == '10.0' # Bug 1404836
 [test_group_touchevents.html]
-  skip-if = webrender || (verify && debug && (os == 'win')) # bug 1424752
+  skip-if = (verify && debug && (os == 'win'))
 [test_group_wheelevents.html]
   skip-if = (toolkit == 'android') # wheel events not supported on mobile
 [test_group_zoom.html]
   skip-if = (toolkit != 'android') # only android supports zoom
 [test_interrupted_reflow.html]
 [test_group_keyboard.html]
 [test_layerization.html]
   skip-if = (os == 'android') # wheel events not supported on mobile
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -11258,20 +11258,41 @@ nsIFrame::GetCompositorHitTestInfo(nsDis
     // If the frame is a plugin frame and wants to handle wheel events as
     // default action, we should add the frame to dispatch-to-content region.
     nsPluginFrame* pluginFrame = do_QueryFrame(this);
     if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
       result |= CompositorHitTestInfo::eDispatchToContent;
     }
   }
 
+  // Inherit the touch-action flags from the parent, if there is one. We do this
+  // because of how the touch-action on a frame combines the touch-action from
+  // ancestor DOM elements. Refer to the documentation in TouchActionHelper.cpp
+  // for details; this code is meant to be equivalent to that code, but woven
+  // into the top-down recursive display list building process.
+  CompositorHitTestInfo inheritedTouchAction = CompositorHitTestInfo::eInvisibleToHitTest;
+  if (nsDisplayCompositorHitTestInfo* parentInfo = aBuilder->GetCompositorHitTestInfo()) {
+    inheritedTouchAction = (parentInfo->HitTestInfo() & CompositorHitTestInfo::eTouchActionMask);
+  }
+
   nsIFrame* touchActionFrame = this;
   if (nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this)) {
     touchActionFrame = do_QueryFrame(scrollFrame);
-  }
+    // On scrollframes, stop inheriting the pan-x and pan-y flags; instead,
+    // reset them back to zero to allow panning on the scrollframe unless we
+    // encounter an element that disables it that's inside the scrollframe.
+    // This is equivalent to the |considerPanning| variable in
+    // TouchActionHelper.cpp, but for a top-down traversal.
+    CompositorHitTestInfo panMask = CompositorHitTestInfo::eTouchActionPanXDisabled
+                                  | CompositorHitTestInfo::eTouchActionPanYDisabled;
+    inheritedTouchAction &= ~panMask;
+  }
+
+  result |= inheritedTouchAction;
+
   const uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(touchActionFrame);
   // The CSS allows the syntax auto | none | [pan-x || pan-y] | manipulation
   // so we can eliminate some combinations of things.
   if (touchAction == NS_STYLE_TOUCH_ACTION_AUTO) {
     // nothing to do
   } else if (touchAction & NS_STYLE_TOUCH_ACTION_MANIPULATION) {
     result |= CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
   } else {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -729,16 +729,20 @@ public:
    * Sets the current compositor hit test info to |aHitTestInfo|.
    * This is used during display list building to determine if the parent frame
    * hit test info contains the same information that child frame needs.
    */
   void SetCompositorHitTestInfo(nsDisplayCompositorHitTestInfo* aHitTestInfo)
   {
     mCompositorHitTestInfo = aHitTestInfo;
   }
+  nsDisplayCompositorHitTestInfo* GetCompositorHitTestInfo() const
+  {
+    return mCompositorHitTestInfo;
+  }
 
   /**
    * Builds a new nsDisplayCompositorHitTestInfo for the frame |aFrame| if
    * needed, and adds it to the top of |aList|. If |aBuildNew| is true, the
    * previous hit test info will not be reused.
    */
   void BuildCompositorHitTestInfoIfNeeded(nsIFrame* aFrame,
                                           nsDisplayList* aList,