Bug 758620 - Layout fixed-position frames to the set scroll-port. r=roc
authorChris Lord <chrislord.net@gmail.com>
Tue, 26 Jun 2012 14:42:57 +0100
changeset 97691 03efce5856692f8b2573ed134d775d49db3d75fe
parent 97690 c707e4f15fd41182e2aea567e4fa96fe6a3f0ce6
child 97692 9b952d9249536576a90b41b95bc60ab367607b97
push id22993
push useremorley@mozilla.com
push dateWed, 27 Jun 2012 10:31:27 +0000
treeherdermozilla-central@1a56f1f011c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs758620
milestone16.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 758620 - Layout fixed-position frames to the set scroll-port. r=roc If a scroll position clamping scroll-port size has been set, layout fixed position frames with respect to this instead of the calculated containing block size.
layout/base/nsPresShell.cpp
layout/generic/nsViewportFrame.cpp
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -8960,19 +8960,33 @@ PresShell::SizeOfTextRuns(nsMallocSizeOf
   // collect the total memory in use for textruns
   return nsLayoutUtils::SizeOfTextRunsForFrames(rootFrame, aMallocSizeOf,
                                                 /* clear = */false);
 }
 
 void
 nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight)
 {
-  mScrollPositionClampingScrollPortSizeSet = true;
-  mScrollPositionClampingScrollPortSize.width = aWidth;
-  mScrollPositionClampingScrollPortSize.height = aHeight;
+  if (!mScrollPositionClampingScrollPortSizeSet ||
+      mScrollPositionClampingScrollPortSize.width != aWidth ||
+      mScrollPositionClampingScrollPortSize.height != aHeight) {
+    mScrollPositionClampingScrollPortSizeSet = true;
+    mScrollPositionClampingScrollPortSize.width = aWidth;
+    mScrollPositionClampingScrollPortSize.height = aHeight;
+
+    // Reflow fixed position children.
+    nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
+    if (rootFrame) {
+      const nsFrameList& childList = rootFrame->GetChildList(nsIFrame::kFixedList);
+      for (nsIFrame* child = childList.FirstChild(); child;
+           child = child->GetNextSibling()) {
+        FrameNeedsReflow(child, eResize, NS_FRAME_IS_DIRTY);
+      }
+    }
+  }
 }
 
 void
 PresShell::SetupFontInflation()
 {
   mFontSizeInflationEmPerLine = nsLayoutUtils::FontSizeInflationEmPerLine();
   mFontSizeInflationMinTwips = nsLayoutUtils::FontSizeInflationMinTwips();
   mFontSizeInflationLineThreshold = nsLayoutUtils::FontSizeInflationLineThreshold();
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -229,20 +229,30 @@ ViewportFrame::Reflow(nsPresContext*    
   nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
 
   if (IsAbsoluteContainer()) {
     NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
                  (offset.x == 0 && offset.y == 0),
                  "We don't handle correct positioning of fixed frames with "
                  "scrollbars in odd positions");
 
+    // If a scroll position clamping scroll-port size has been set, layout
+    // fixed position elements to this size instead of the computed size.
+    nscoord width = reflowState.ComputedWidth();
+    nscoord height = reflowState.ComputedHeight();
+    if (aPresContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) {
+      nsSize size = aPresContext->PresShell()->
+        GetScrollPositionClampingScrollPortSize();
+      width = size.width;
+      height = size.height;
+    }
+
     // Just reflow all the fixed-pos frames.
     rv = GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus,
-                                              reflowState.ComputedWidth(),
-                                              reflowState.ComputedHeight(),
+                                              width, height,
                                               false, true, true, // XXX could be optimized
                                               &aDesiredSize.mOverflowAreas);
   }
 
   // If we were dirty then do a repaint
   if (GetStateBits() & NS_FRAME_IS_DIRTY) {
     nsRect damageRect(0, 0, aDesiredSize.width, aDesiredSize.height);
     Invalidate(damageRect);