Bug 1092139 - Make the PositionedEventTargeting code respect the flag to ignore root scroll frames. r=roc
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 03 Nov 2014 09:43:52 -0500
changeset 213681 c3c317bd388f954cd93953eb9d0041b1c473a4a8
parent 213680 3789bf7f0e60f2c3e091474ea4fe1e3a4f1f46ce
child 213682 0e314ec744bea4fe2cb9128bfcea0290ab3fedab
push id51287
push userkgupta@mozilla.com
push dateMon, 03 Nov 2014 14:44:23 +0000
treeherdermozilla-inbound@c3c317bd388f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 1092139 - Make the PositionedEventTargeting code respect the flag to ignore root scroll frames. r=roc The ignore-root-scroll-frame flag is used on mobile platforms in order to allow hit-testing outside the viewport area. This is needed because the user can zoom out and make visible an area larger than the viewport (i.e. the displayport) but layout generally restricts hit-testing to the viewport. The code to retarget events to nearby clickable elements also needs to respect this flag, otherwise the retargeting fails to work outside the viewport area.
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -238,25 +238,32 @@ ClipToFrame(nsIFrame* aRootFrame, nsIFra
   nsRect bound = nsLayoutUtils::TransformFrameRectToAncestor(
     aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()), aRootFrame);
   nsRect result = bound.Intersect(aRect);
   return result;
 static nsRect
 GetTargetRect(nsIFrame* aRootFrame, const nsPoint& aPointRelativeToRootFrame,
-              nsIFrame* aRestrictToDescendants, const EventRadiusPrefs* aPrefs)
+              nsIFrame* aRestrictToDescendants, const EventRadiusPrefs* aPrefs,
+              uint32_t aFlags)
   nsMargin m(AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[0], true),
              AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[1], false),
              AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[2], true),
              AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[3], false));
   nsRect r(aPointRelativeToRootFrame, nsSize(0,0));
-  return ClipToFrame(aRootFrame, aRestrictToDescendants, r);
+    // Don't clip this rect to the root scroll frame if the flag to ignore the
+    // root scroll frame is set. Note that the GetClosest code will still enforce
+    // that the target found is a descendant of aRestrictToDescendants.
+    r = ClipToFrame(aRootFrame, aRestrictToDescendants, r);
+  }
+  return r;
 static float
 ComputeDistanceFromRect(const nsPoint& aPoint, const nsRect& aRect)
   nscoord dx = std::max(0, std::max(aRect.x - aPoint.x, aPoint.x - aRect.XMost()));
   nscoord dy = std::max(0, std::max(aRect.y - aPoint.y, aPoint.y - aRect.YMost()));
   return float(NS_hypot(dx, dy));
@@ -381,17 +388,17 @@ FindFrameTargetedByInputEvent(const Widg
   // document as the exact target. Otherwise, if an ancestor document has
   // a mouse event handler for example, targets that are !IsElementClickable can
   // never be targeted --- something nsSubDocumentFrame in an ancestor document
   // would be targeted instead.
   nsIFrame* restrictToDescendants = target ?
     target->PresContext()->PresShell()->GetRootFrame() : aRootFrame;
   nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame,
-                                    restrictToDescendants, prefs);
+                                    restrictToDescendants, prefs, aFlags);
   nsAutoTArray<nsIFrame*,8> candidates;
   nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect, candidates, flags);
   if (NS_FAILED(rv)) {
     return target;
   nsIFrame* closestClickable =
     GetClosest(aRootFrame, aPointRelativeToRootFrame, targetRect, prefs,