From 16efba0a1500f66144e1c500dcd6bcdbde7c591b Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Thu, 10 Apr 2008 04:39:42 +0000 Subject: [PATCH] Bug 425253. Propagate reflow-depth tracking through XUL box layout. r+sr=dbaron,a=damon git-svn-id: svn://10.0.0.236/trunk@249966 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/forms/nsComboboxControlFrame.cpp | 10 +++++----- mozilla/layout/forms/nsListControlFrame.cpp | 8 +++----- mozilla/layout/forms/nsTextControlFrame.cpp | 4 ++-- mozilla/layout/generic/nsBlockFrame.cpp | 7 +++---- mozilla/layout/generic/nsFrame.cpp | 1 + mozilla/layout/generic/nsGfxScrollFrame.cpp | 8 ++++++-- mozilla/layout/generic/nsGfxScrollFrame.h | 11 +++++++++++ mozilla/layout/generic/nsIScrollableFrame.h | 4 +++- mozilla/layout/xul/base/src/nsBoxFrame.cpp | 3 ++- mozilla/layout/xul/base/src/nsBoxLayoutState.cpp | 5 ++++- mozilla/layout/xul/base/src/nsBoxLayoutState.h | 12 ++++++++---- 11 files changed, 48 insertions(+), 25 deletions(-) diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index 1486fbc72be..5f2e41f4812 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -88,7 +88,6 @@ #include "nsContentCreatorFunctions.h" #include "nsLayoutUtils.h" #include "nsDisplayList.h" -#include "nsBoxLayoutState.h" #include "nsITheme.h" #include "nsThemeConstants.h" @@ -574,8 +573,8 @@ nsComboboxControlFrame::GetIntrinsicWidth(nsIRenderingContext* aRenderingContext nsIScrollableFrame* scrollable; CallQueryInterface(mListControlFrame, &scrollable); NS_ASSERTION(scrollable, "List must be a scrollable frame"); - nsBoxLayoutState bls(presContext, aRenderingContext); - scrollbarWidth = scrollable->GetDesiredScrollbarSizes(&bls).LeftRight(); + scrollbarWidth = + scrollable->GetDesiredScrollbarSizes(presContext, aRenderingContext).LeftRight(); } nscoord displayWidth = 0; @@ -680,8 +679,9 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, nsIScrollableFrame* scrollable; CallQueryInterface(mListControlFrame, &scrollable); NS_ASSERTION(scrollable, "List must be a scrollable frame"); - nsBoxLayoutState bls(PresContext(), aReflowState.rendContext); - buttonWidth = scrollable->GetDesiredScrollbarSizes(&bls).LeftRight(); + buttonWidth = + scrollable->GetDesiredScrollbarSizes(PresContext(), + aReflowState.rendContext).LeftRight(); if (buttonWidth > aReflowState.ComputedWidth()) { buttonWidth = 0; } diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index b86dfe9c4f9..b3c0b9f5599 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -90,7 +90,6 @@ #include "nsIDOMKeyListener.h" #include "nsLayoutUtils.h" #include "nsDisplayList.h" -#include "nsBoxLayoutState.h" // Constants const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers @@ -535,8 +534,8 @@ nsListControlFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext) // content. Combobox frames depend on this happening in the dropdown, // and standalone listboxes are overflow:scroll so they need it too. result = GetScrolledFrame()->GetPrefWidth(aRenderingContext); - nsBoxLayoutState bls(PresContext(), aRenderingContext); - result = NSCoordSaturatingAdd(result, GetDesiredScrollbarSizes(&bls).LeftRight()); + result = NSCoordSaturatingAdd(result, + GetDesiredScrollbarSizes(PresContext(), aRenderingContext).LeftRight()); return result; } @@ -551,8 +550,7 @@ nsListControlFrame::GetMinWidth(nsIRenderingContext *aRenderingContext) // content. Combobox frames depend on this happening in the dropdown, // and standalone listboxes are overflow:scroll so they need it too. result = GetScrolledFrame()->GetMinWidth(aRenderingContext); - nsBoxLayoutState bls(PresContext(), aRenderingContext); - result += GetDesiredScrollbarSizes(&bls).LeftRight(); + result += GetDesiredScrollbarSizes(PresContext(), aRenderingContext).LeftRight(); return result; } diff --git a/mozilla/layout/forms/nsTextControlFrame.cpp b/mozilla/layout/forms/nsTextControlFrame.cpp index 99842207169..a9507d8f723 100644 --- a/mozilla/layout/forms/nsTextControlFrame.cpp +++ b/mozilla/layout/forms/nsTextControlFrame.cpp @@ -1383,8 +1383,8 @@ nsTextControlFrame::CalcIntrinsicSize(nsIRenderingContext* aRenderingContext, CallQueryInterface(first, &scrollableFrame); NS_ASSERTION(scrollableFrame, "Child must be scrollable"); - nsBoxLayoutState bls(PresContext(), aRenderingContext); - nsMargin scrollbarSizes = scrollableFrame->GetDesiredScrollbarSizes(&bls); + nsMargin scrollbarSizes = + scrollableFrame->GetDesiredScrollbarSizes(PresContext(), aRenderingContext); aIntrinsicSize.width += scrollbarSizes.LeftRight(); diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index a164a333094..9c3e5f10014 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -84,7 +84,6 @@ #include "nsIAccessibilityService.h" #endif #include "nsLayoutUtils.h" -#include "nsBoxLayoutState.h" #include "nsDisplayList.h" #include "nsContentErrors.h" #include "nsCSSAnonBoxes.h" @@ -822,9 +821,9 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState, CallQueryInterface(aLastRS->frame, &scrollFrame); nsMargin scrollbars(0,0,0,0); if (scrollFrame) { - nsBoxLayoutState dummyState(aLastRS->frame->PresContext(), - aLastRS->rendContext); - scrollbars = scrollFrame->GetDesiredScrollbarSizes(&dummyState); + scrollbars = + scrollFrame->GetDesiredScrollbarSizes(aLastRS->frame->PresContext(), + aLastRS->rendContext); if (!lastButOneRS->mFlags.mAssumingHScrollbar) { scrollbars.top = scrollbars.bottom = 0; } diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index d2e50fc8f1b..4b3b418c649 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -6198,6 +6198,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState, // messes up dimensions. reflowState.parentReflowState = &parentReflowState; reflowState.mCBReflowState = &parentReflowState; + reflowState.mReflowDepth = aState.GetReflowDepth(); // mComputedWidth and mComputedHeight are content-box, not // border-box diff --git a/mozilla/layout/generic/nsGfxScrollFrame.cpp b/mozilla/layout/generic/nsGfxScrollFrame.cpp index 504abedbb91..7eab73d562d 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.cpp +++ b/mozilla/layout/generic/nsGfxScrollFrame.cpp @@ -253,7 +253,9 @@ struct ScrollReflowState { ScrollReflowState(nsIScrollableFrame* aFrame, const nsHTMLReflowState& aState) : mReflowState(aState), - mBoxState(aState.frame->PresContext(), aState.rendContext), + // mBoxState is just used for scrollbars so we don't need to + // worry about the reflow depth here + mBoxState(aState.frame->PresContext(), aState.rendContext, 0), mStyles(aFrame->GetScrollbarStyles()) { } }; @@ -706,7 +708,9 @@ nsHTMLScrollFrame::GetIntrinsicVScrollbarWidth(nsIRenderingContext *aRenderingCo if (ss.mVertical != NS_STYLE_OVERFLOW_SCROLL || !mInner.mVScrollbarBox) return 0; - nsBoxLayoutState bls(PresContext(), aRenderingContext); + // Don't need to worry about reflow depth here since it's + // just for scrollbars + nsBoxLayoutState bls(PresContext(), aRenderingContext, 0); nsSize vScrollbarPrefSize(0, 0); GetScrollbarMetrics(bls, mInner.mVScrollbarBox, nsnull, &vScrollbarPrefSize, PR_TRUE); diff --git a/mozilla/layout/generic/nsGfxScrollFrame.h b/mozilla/layout/generic/nsGfxScrollFrame.h index 210cfd58a4d..a0e0a1cd497 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.h +++ b/mozilla/layout/generic/nsGfxScrollFrame.h @@ -51,6 +51,7 @@ #include "nsIScrollableView.h" #include "nsIView.h" #include "nsIReflowCallback.h" +#include "nsBoxLayoutState.h" class nsPresContext; class nsIPresShell; @@ -364,6 +365,11 @@ public: return mInner.GetActualScrollbarSizes(); } virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); + virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, + nsIRenderingContext* aRC) { + nsBoxLayoutState bls(aPresContext, aRC, 0); + return GetDesiredScrollbarSizes(&bls); + } virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; /** @@ -561,6 +567,11 @@ public: return mInner.GetActualScrollbarSizes(); } virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); + virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, + nsIRenderingContext* aRC) { + nsBoxLayoutState bls(aPresContext, aRC, 0); + return GetDesiredScrollbarSizes(&bls); + } virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; /** diff --git a/mozilla/layout/generic/nsIScrollableFrame.h b/mozilla/layout/generic/nsIScrollableFrame.h index 115bbc4bd9c..a78d1037be4 100644 --- a/mozilla/layout/generic/nsIScrollableFrame.h +++ b/mozilla/layout/generic/nsIScrollableFrame.h @@ -85,7 +85,9 @@ public: * be visible due to overflowing content, are. */ virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0; - + virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, + nsIRenderingContext* aRC) = 0; + /** * Get the position of the scrolled view. */ diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.cpp b/mozilla/layout/xul/base/src/nsBoxFrame.cpp index 9a29bfaf0e0..5e716d6353e 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsBoxFrame.cpp @@ -705,7 +705,8 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; // create the layout state - nsBoxLayoutState state(aPresContext, aReflowState.rendContext); + nsBoxLayoutState state(aPresContext, aReflowState.rendContext, + aReflowState.mReflowDepth); nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight()); diff --git a/mozilla/layout/xul/base/src/nsBoxLayoutState.cpp b/mozilla/layout/xul/base/src/nsBoxLayoutState.cpp index c123a019ee4..76a3e1fc7a4 100644 --- a/mozilla/layout/xul/base/src/nsBoxLayoutState.cpp +++ b/mozilla/layout/xul/base/src/nsBoxLayoutState.cpp @@ -45,10 +45,12 @@ #include "nsBoxLayoutState.h" nsBoxLayoutState::nsBoxLayoutState(nsPresContext* aPresContext, - nsIRenderingContext* aRenderingContext) + nsIRenderingContext* aRenderingContext, + PRUint16 aReflowDepth) : mPresContext(aPresContext) , mRenderingContext(aRenderingContext) , mLayoutFlags(0) + , mReflowDepth(aReflowDepth) , mPaintingDisabled(PR_FALSE) { NS_ASSERTION(mPresContext, "PresContext must be non-null"); @@ -58,6 +60,7 @@ nsBoxLayoutState::nsBoxLayoutState(const nsBoxLayoutState& aState) : mPresContext(aState.mPresContext) , mRenderingContext(aState.mRenderingContext) , mLayoutFlags(aState.mLayoutFlags) + , mReflowDepth(aState.mReflowDepth + 1) , mPaintingDisabled(aState.mPaintingDisabled) { NS_ASSERTION(mPresContext, "PresContext must be non-null"); diff --git a/mozilla/layout/xul/base/src/nsBoxLayoutState.h b/mozilla/layout/xul/base/src/nsBoxLayoutState.h index 8ff62e28dac..8000a763a88 100644 --- a/mozilla/layout/xul/base/src/nsBoxLayoutState.h +++ b/mozilla/layout/xul/base/src/nsBoxLayoutState.h @@ -59,7 +59,8 @@ class nsHTMLReflowCommand; class nsBoxLayoutState { public: - nsBoxLayoutState(nsPresContext* aPresContext, nsIRenderingContext* aRenderingContext = nsnull) NS_HIDDEN; + nsBoxLayoutState(nsPresContext* aPresContext, nsIRenderingContext* aRenderingContext = nsnull, + PRUint16 aReflowDepth = 0) NS_HIDDEN; nsBoxLayoutState(const nsBoxLayoutState& aState) NS_HIDDEN; nsPresContext* PresContext() const { return mPresContext; } @@ -78,16 +79,19 @@ public: // doing box layout or intrinsic size calculation will cause bugs. nsIRenderingContext* GetRenderingContext() const { return mRenderingContext; } - void PushStackMemory() { PresShell()->PushStackMemory(); } - void PopStackMemory() { PresShell()->PopStackMemory(); } + void PushStackMemory() { PresShell()->PushStackMemory(); ++mReflowDepth; } + void PopStackMemory() { PresShell()->PopStackMemory(); --mReflowDepth; } void* AllocateStackMemory(size_t aSize) { return PresShell()->AllocateStackMemory(aSize); } + PRUint16 GetReflowDepth() { return mReflowDepth; } + private: nsCOMPtr mPresContext; nsIRenderingContext *mRenderingContext; PRUint32 mLayoutFlags; - PRBool mPaintingDisabled; + PRUint16 mReflowDepth; + PRPackedBool mPaintingDisabled; }; #endif