Bug 1516722 - Also scroll the visual viewport in ScrollToShowRect() if necessary. r=kats
authorBotond Ballo <botond@mozilla.com>
Tue, 07 May 2019 03:03:34 +0000
changeset 531645 6348ca2145d91a6cd468877ce2940c5a1cb466ce
parent 531644 52da0d93fe09c1bf8ed98f3e690b258ca80661ec
child 531646 5e9833abf18153254ee72738e525c22af77435c8
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1516722
milestone68.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 1516722 - Also scroll the visual viewport in ScrollToShowRect() if necessary. r=kats Differential Revision: https://phabricator.services.mozilla.com/D29079
layout/base/PresShell.cpp
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -3306,17 +3306,18 @@ static nscoord ComputeWhereToScroll(Wher
  * This needs to work even if aRect has a width or height of zero.
  *
  * Note that, since we are performing a layout scroll, it's possible that
  * this fnction will sometimes be unsuccessful; the content will move as
  * fast as it can on the screen using layout viewport scrolling, and then
  * stop there, even if it could get closer to the desired position by
  * moving the visual viewport within the layout viewport.
  */
-static void ScrollToShowRect(nsIScrollableFrame* aFrameAsScrollable,
+static void ScrollToShowRect(PresShell* aPresShell,
+                             nsIScrollableFrame* aFrameAsScrollable,
                              const nsRect& aRect, ScrollAxis aVertical,
                              ScrollAxis aHorizontal, ScrollFlags aScrollFlags) {
   nsPoint scrollPt = aFrameAsScrollable->GetVisualViewportOffset();
   nsRect visibleRect(scrollPt, aFrameAsScrollable->GetVisualViewportSize());
 
   nsSize lineSize;
   // Don't call GetLineScrollAmount unless we actually need it. Not only
   // does this save time, but it's not safe to call GetLineScrollAmount
@@ -3372,20 +3373,35 @@ static void ScrollToShowRect(nsIScrollab
         (aFrameAsScrollable->GetScrollStyles().mScrollBehavior ==
          NS_STYLE_SCROLL_BEHAVIOR_SMOOTH);
     bool smoothScroll = (aScrollFlags & ScrollFlags::ScrollSmooth) ||
                         ((aScrollFlags & ScrollFlags::ScrollSmoothAuto) &&
                          autoBehaviorIsSmooth);
     if (gfxPrefs::ScrollBehaviorEnabled() && smoothScroll) {
       scrollMode = ScrollMode::SmoothMsd;
     }
+    nsIFrame* frame = do_QueryFrame(aFrameAsScrollable);
+    AutoWeakFrame weakFrame(frame);
     aFrameAsScrollable->ScrollTo(scrollPt, scrollMode, &allowedRange,
                                  aScrollFlags & ScrollFlags::ScrollSnap
                                      ? nsIScrollbarMediator::ENABLE_SNAP
                                      : nsIScrollbarMediator::DISABLE_SNAP);
+    if (!weakFrame.IsAlive()) {
+      return;
+    }
+
+    // If this is the RCD-RSF, also call ScrollToVisual() since we want to
+    // scroll the rect into view visually, and that may require scrolling
+    // the visual viewport in scenarios where there is not enough layout
+    // scroll range.
+    if (aFrameAsScrollable->IsRootScrollFrameOfDocument() &&
+        aPresShell->GetPresContext()->IsRootContentDocument()) {
+      aPresShell->ScrollToVisual(scrollPt, FrameMetrics::eMainThread,
+                                 scrollMode);
+    }
   }
 }
 
 nsresult PresShell::ScrollContentIntoView(nsIContent* aContent,
                                           ScrollAxis aVertical,
                                           ScrollAxis aHorizontal,
                                           ScrollFlags aScrollFlags) {
   NS_ENSURE_TRUE(aContent, NS_ERROR_NULL_POINTER);
@@ -3540,17 +3556,18 @@ bool PresShell::ScrollFrameRectIntoView(
 
       targetRect -= sf->GetScrolledFrame()->GetPosition();
       if (!(aScrollFlags & ScrollFlags::IgnoreMarginAndPadding)) {
         nsMargin scrollPadding = sf->GetScrollPadding();
         targetRect.Inflate(scrollPadding);
         targetRect = targetRect.Intersect(sf->GetScrolledRect());
       }
 
-      ScrollToShowRect(sf, targetRect, aVertical, aHorizontal, aScrollFlags);
+      ScrollToShowRect(this, sf, targetRect, aVertical, aHorizontal,
+                       aScrollFlags);
 
       nsPoint newPosition = sf->LastScrollDestination();
       // If the scroll position increased, that means our content moved up,
       // so our rect's offset should decrease
       rect += oldPosition - newPosition;
 
       if (oldPosition != newPosition) {
         didScroll = true;