Bug 1261671 - ContentEventHandler::ConvertToRootRelativeOffset() should return the root-relative result in the frame's own appUnits, not the root's appUnits in the case when they're different. r=masayuki a=ritu
authorJonathan Kew <jkew@mozilla.com>
Tue, 12 Apr 2016 07:06:38 +0100
changeset 325829 27aca73b0ff73eecbad93123eb50ce19c01afbef
parent 325828 aa74410e52f0ff645a328a6e5a0928d2ba0b46c5
child 325830 976db6fcfed77d4ac4626ab8cbb6a25213232711
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, ritu
bugs1261671
milestone47.0a2
Bug 1261671 - ContentEventHandler::ConvertToRootRelativeOffset() should return the root-relative result in the frame's own appUnits, not the root's appUnits in the case when they're different. r=masayuki a=ritu
dom/events/ContentEventHandler.cpp
dom/events/ContentEventHandler.h
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -1914,26 +1914,34 @@ ContentEventHandler::GetStartFrameAndOff
 }
 
 nsresult
 ContentEventHandler::ConvertToRootRelativeOffset(nsIFrame* aFrame,
                                                  nsRect& aRect)
 {
   NS_ASSERTION(aFrame, "aFrame must not be null");
 
-  nsPresContext* rootPresContext = aFrame->PresContext()->GetRootPresContext();
-  if (NS_WARN_IF(!rootPresContext)) {
+  nsPresContext* thisPC = aFrame->PresContext();
+  nsPresContext* rootPC = thisPC->GetRootPresContext();
+  if (NS_WARN_IF(!rootPC)) {
     return NS_ERROR_FAILURE;
   }
-  nsIFrame* rootFrame = rootPresContext->PresShell()->GetRootFrame();
+  nsIFrame* rootFrame = rootPC->PresShell()->GetRootFrame();
   if (NS_WARN_IF(!rootFrame)) {
     return NS_ERROR_FAILURE;
   }
 
   aRect = nsLayoutUtils::TransformFrameRectToAncestor(aFrame, aRect, rootFrame);
+
+  // TransformFrameRectToAncestor returned the rect in the ancestor's appUnits,
+  // but we want it in aFrame's units (in case of different full-zoom factors),
+  // so convert back.
+  aRect = aRect.ScaleToOtherAppUnitsRoundOut(rootPC->AppUnitsPerDevPixel(),
+                                             thisPC->AppUnitsPerDevPixel());
+
   return NS_OK;
 }
 
 static void AdjustRangeForSelection(nsIContent* aRoot,
                                     nsINode** aNode,
                                     int32_t* aNodeOffset)
 {
   nsINode* node = *aNode;
--- a/dom/events/ContentEventHandler.h
+++ b/dom/events/ContentEventHandler.h
@@ -259,18 +259,18 @@ protected:
                                       uint32_t* aNewOffset = nullptr);
   // If the aRange isn't in text node but next to a text node, this method
   // modifies it in the text node.  Otherwise, not modified.
   nsresult AdjustCollapsedRangeMaybeIntoTextNode(nsRange* aCollapsedRange);
   // Find the first frame for the range and get the start offset in it.
   nsresult GetStartFrameAndOffset(const nsRange* aRange,
                                   nsIFrame*& aFrame,
                                   int32_t& aOffsetInFrame);
-  // Convert the frame relative offset to the root frame of the root presContext
-  // relative offset.
+  // Convert the frame relative offset to be relative to the root frame of the
+  // root presContext (but still measured in appUnits of aFrame's presContext).
   nsresult ConvertToRootRelativeOffset(nsIFrame* aFrame,
                                        nsRect& aRect);
   // Expand aXPOffset to the nearest offset in cluster boundary. aForward is
   // true, it is expanded to forward.
   nsresult ExpandToClusterBoundary(nsIContent* aContent, bool aForward,
                                    uint32_t* aXPOffset);
 
   typedef nsTArray<mozilla::FontRange> FontRangeArray;