Fix the vertical scrollbar guessing in nsHTMLScrollFrame to do better for aninitial reflow if we're doing that initial reflow a ways into the documentload. Bug 378480, r+sr=roc

This commit is contained in:
bzbarsky@mit.edu 2007-04-25 19:29:21 -07:00
parent c77758b510
commit 24c328d268
4 changed files with 34 additions and 3 deletions

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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;