Bug 1637135 - Don't assume visual coordinates in event retargeting helpers. r=tnikkel
authorBotond Ballo <botond@mozilla.com>
Wed, 27 May 2020 06:54:35 +0000
changeset 532319 3999e81acbf79c8d87f0066e8492fa7228f35f7b
parent 532318 1a878a7a1b146abc2e23756d0ea6f519a82958d4
child 532320 d97315ba56440fdfe2bd42ca52214aebabd0344f
push id37454
push userccoroiu@mozilla.com
push dateWed, 27 May 2020 16:14:31 +0000
treeherdermozilla-central@a1dd9afbfdf5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1637135
milestone78.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 1637135 - Don't assume visual coordinates in event retargeting helpers. r=tnikkel Differential Revision: https://phabricator.services.mozilla.com/D76996
layout/base/PositionedEventTargeting.cpp
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -270,21 +270,20 @@ static nscoord AppUnitsFromMM(RelativeTo
   }
   return NSToCoordRound(result);
 }
 
 /**
  * Clip aRect with the bounds of aFrame in the coordinate system of
  * aRootFrame. aRootFrame is an ancestor of aFrame.
  */
-static nsRect ClipToFrame(const nsIFrame* aRootFrame, const nsIFrame* aFrame,
+static nsRect ClipToFrame(RelativeTo aRootFrame, const nsIFrame* aFrame,
                           nsRect& aRect) {
   nsRect bound = nsLayoutUtils::TransformFrameRectToAncestor(
-      aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()),
-      RelativeTo{aRootFrame, ViewportType::Visual});
+      aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()), aRootFrame);
   nsRect result = bound.Intersect(aRect);
   return result;
 }
 
 static nsRect GetTargetRect(RelativeTo aRootFrame,
                             const nsPoint& aPointRelativeToRootFrame,
                             const nsIFrame* aRestrictToDescendants,
                             const EventRadiusPrefs* aPrefs, uint32_t aFlags) {
@@ -293,17 +292,17 @@ static nsRect GetTargetRect(RelativeTo a
              AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[2]),
              AppUnitsFromMM(aRootFrame, aPrefs->mSideRadii[3]));
   nsRect r(aPointRelativeToRootFrame, nsSize(0, 0));
   r.Inflate(m);
   if (!(aFlags & INPUT_IGNORE_ROOT_SCROLL_FRAME)) {
     // 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.mFrame, aRestrictToDescendants, r);
+    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()));
@@ -337,34 +336,33 @@ static void SubtractFromExposedRegion(ns
   // Don't let *aExposedRegion get too complex, but don't let it fluff out to
   // its bounds either. Do let aExposedRegion get more complex if by doing so
   // we reduce its area by at least half.
   if (tmp.GetNumRects() <= 15 || tmp.Area() <= aExposedRegion->Area() / 2) {
     *aExposedRegion = tmp;
   }
 }
 
-static nsIFrame* GetClosest(const nsIFrame* aRoot,
+static nsIFrame* GetClosest(RelativeTo aRoot,
                             const nsPoint& aPointRelativeToRootFrame,
                             const nsRect& aTargetRect,
                             const EventRadiusPrefs* aPrefs,
                             const nsIFrame* aRestrictToDescendants,
                             nsIContent* aClickableAncestor,
                             nsTArray<nsIFrame*>& aCandidates) {
   nsIFrame* bestTarget = nullptr;
   // Lower is better; distance is in appunits
   float bestDistance = 1e6f;
   nsRegion exposedRegion(aTargetRect);
   for (uint32_t i = 0; i < aCandidates.Length(); ++i) {
     nsIFrame* f = aCandidates[i];
 
     bool preservesAxisAlignedRectangles = false;
     nsRect borderBox = nsLayoutUtils::TransformFrameRectToAncestor(
-        f, nsRect(nsPoint(0, 0), f->GetSize()),
-        RelativeTo{aRoot, ViewportType::Visual},
+        f, nsRect(nsPoint(0, 0), f->GetSize()), aRoot,
         &preservesAxisAlignedRectangles);
     PET_LOG("Checking candidate %p with border box %s\n", f,
             mozilla::layers::Stringify(borderBox).c_str());
     nsRegion region;
     region.And(exposedRegion, borderBox);
     if (region.IsEmpty()) {
       PET_LOG("  candidate %p had empty hit region\n", f);
       continue;
@@ -386,23 +384,23 @@ static nsIFrame* GetClosest(const nsIFra
     nsIContent* clickableContent =
         GetClickableAncestor(f, nsGkAtoms::body, &labelTargetId);
     if (!aClickableAncestor && !clickableContent) {
       PET_LOG("  candidate %p was not clickable\n", f);
       continue;
     }
     // If our current closest frame is a descendant of 'f', skip 'f' (prefer
     // the nested frame).
-    if (bestTarget &&
-        nsLayoutUtils::IsProperAncestorFrameCrossDoc(f, bestTarget, aRoot)) {
+    if (bestTarget && nsLayoutUtils::IsProperAncestorFrameCrossDoc(
+                          f, bestTarget, aRoot.mFrame)) {
       PET_LOG("  candidate %p was ancestor for bestTarget %p\n", f, bestTarget);
       continue;
     }
     if (!aClickableAncestor && !nsLayoutUtils::IsAncestorFrameCrossDoc(
-                                   aRestrictToDescendants, f, aRoot)) {
+                                   aRestrictToDescendants, f, aRoot.mFrame)) {
       PET_LOG("  candidate %p was not descendant of restrictroot %p\n", f,
               aRestrictToDescendants);
       continue;
     }
 
     // distance is in appunits
     float distance =
         ComputeDistanceFromRegion(aPointRelativeToRootFrame, region);
@@ -480,18 +478,18 @@ nsIFrame* FindFrameTargetedByInputEvent(
   AutoTArray<nsIFrame*, 8> candidates;
   nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect,
                                                 candidates, options);
   if (NS_FAILED(rv)) {
     return target;
   }
 
   nsIFrame* closestClickable =
-      GetClosest(aRootFrame.mFrame, aPointRelativeToRootFrame, targetRect,
-                 prefs, restrictToDescendants, clickableAncestor, candidates);
+      GetClosest(aRootFrame, aPointRelativeToRootFrame, targetRect, prefs,
+                 restrictToDescendants, clickableAncestor, candidates);
   if (closestClickable) {
     target = closestClickable;
   }
   PET_LOG("Final target is %p\n", target);
 
 #ifdef DEBUG_FRAME_DUMP
   // At verbose logging level, dump the frame tree to help with debugging.
   // Note that dumping the frame tree at the top of the function may flood