From 99a9e5db92ca5bba36693ba2007caf0f4f5a0acd Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Thu, 26 Apr 2007 02:29:21 +0000 Subject: [PATCH] Fix the vertical scrollbar guessing in nsHTMLScrollFrame to do better for an initial reflow if we're doing that initial reflow a ways into the document load. Bug 378480, r+sr=roc --- content/base/src/nsContentSink.cpp | 5 +++++ layout/base/nsIPresShell.h | 11 +++++++++++ layout/generic/nsGfxScrollFrame.cpp | 17 ++++++++++++++--- layout/generic/nsGfxScrollFrame.h | 4 ++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/content/base/src/nsContentSink.cpp b/content/base/src/nsContentSink.cpp index 35215cdfe34..ea9f4ea1714 100644 --- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -892,6 +892,8 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets) // Nothing to do here return; } + + PRBool deferredStart = mDeferredLayoutStart; mDeferredLayoutStart = PR_TRUE; @@ -930,9 +932,12 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets) // Make shell an observer for next time shell->BeginObservingDocument(); + PRBool oldInEagerStartLayout = shell->IsInEagerStartLayout(); + shell->SetInEagerStartLayout(!deferredStart); // Resize-reflow this time nsRect r = shell->GetPresContext()->GetVisibleArea(); nsresult rv = shell->InitialReflow(r.width, r.height); + shell->SetInEagerStartLayout(oldInEagerStartLayout); if (NS_FAILED(rv)) { return; } diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 473a1f9ccc0..05d509f1753 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -720,6 +720,13 @@ public: void AddWeakFrame(nsWeakFrame* aWeakFrame); void RemoveWeakFrame(nsWeakFrame* aWeakFrame); + void SetInEagerStartLayout(PRBool aInEagerStartLayout) { + mInEagerStartLayout = aInEagerStartLayout; + } + PRBool IsInEagerStartLayout() const { + return mInEagerStartLayout; + } + #ifdef NS_DEBUG nsIFrame* GetDrawEventTargetFrame() { return mDrawEventTargetFrame; } #endif @@ -760,6 +767,10 @@ protected: // the dom/layout trees PRPackedBool mIsAccessibilityActive; + // True if we're under an "eager" (that is, called before there is + // much content in the document) StartLayout call. + PRPackedBool mInEagerStartLayout; + // A list of weak frames. This is a pointer to the last item in the list. nsWeakFrame* mWeakFrames; }; diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 68148cec77a..196857f3880 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -493,7 +493,7 @@ nsHTMLScrollFrame::GuessVScrollbarNeeded(const ScrollReflowState& aState) // If this is the initial reflow, guess PR_FALSE because usually // we have very little content by then. - if (GetStateBits() & NS_FRAME_FIRST_REFLOW) + if (InInitialReflow()) return PR_FALSE; if (mInner.mIsRoot) { @@ -517,6 +517,18 @@ nsHTMLScrollFrame::GuessVScrollbarNeeded(const ScrollReflowState& aState) return PR_FALSE; } +PRBool +nsHTMLScrollFrame::InInitialReflow() const +{ + // We're in an initial reflow if NS_FRAME_FIRST_REFLOW is set, unless we're a + // root scrollframe during a non-eager StartLayout call on the presshell. In + // that case we want to skip this clause altogether. + return + (GetStateBits() & NS_FRAME_FIRST_REFLOW) && + (!mInner.mIsRoot || + PresContext()->PresShell()->IsInEagerStartLayout()); +} + nsresult nsHTMLScrollFrame::ReflowContents(ScrollReflowState* aState, const nsHTMLReflowMetrics& aDesiredSize) @@ -782,8 +794,7 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext, aDesiredSize.mOverflowArea = nsRect(0, 0, aDesiredSize.width, aDesiredSize.height); FinishAndStoreOverflow(&aDesiredSize); - if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW) && - !mInner.mHadNonInitialReflow) { + if (!InInitialReflow() && !mInner.mHadNonInitialReflow) { mInner.mHadNonInitialReflow = PR_TRUE; if (mInner.mIsRoot) { // For viewports, record whether we needed a vertical scrollbar diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 48df9fba2eb..1c6cfb0ebe9 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -397,6 +397,10 @@ protected: PRBool IsScrollbarUpdateSuppressed() const { return mInner.mSupppressScrollbarUpdate; } + + // Return whether we're in an "initial" reflow. Some reflows with + // NS_FRAME_FIRST_REFLOW set are NOT "initial" as far as we're concerned. + PRBool InInitialReflow() const; private: friend class nsGfxScrollFrameInner;