From e3bc7ee7fdd6e129fe5a86483f34321ffaf61317 Mon Sep 17 00:00:00 2001 From: "dbaron%fas.harvard.edu" Date: Thu, 7 Mar 2002 23:48:26 +0000 Subject: [PATCH] Fix top theme switching crash by clearing the outliner's style caches from DidSetStyleContext instead of FlushMiscWidgetInfo. b=116038 sr=hyatt r=bzbarsky a=asa --- content/base/src/nsStyleSet.cpp | 6 ++ layout/base/nsPresShell.cpp | 14 ++--- layout/html/base/src/nsPresShell.cpp | 14 ++--- layout/style/nsStyleSet.cpp | 6 ++ .../outliner/public/nsIOutlinerBoxObject.idl | 5 -- .../src/outliner/src/nsOutlinerBodyFrame.cpp | 61 +++++++++++-------- .../src/outliner/src/nsOutlinerBodyFrame.h | 6 ++ .../src/outliner/src/nsOutlinerBoxObject.cpp | 8 --- .../base/src/tree/public/nsITreeBoxObject.idl | 5 -- .../xul/base/src/tree/src/nsTreeBodyFrame.cpp | 61 +++++++++++-------- .../xul/base/src/tree/src/nsTreeBodyFrame.h | 6 ++ .../xul/base/src/tree/src/nsTreeBoxObject.cpp | 8 --- 12 files changed, 108 insertions(+), 92 deletions(-) diff --git a/content/base/src/nsStyleSet.cpp b/content/base/src/nsStyleSet.cpp index bb5d829263fe..694bffd8c6f1 100644 --- a/content/base/src/nsStyleSet.cpp +++ b/content/base/src/nsStyleSet.cpp @@ -888,6 +888,12 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData) return PR_TRUE; } +/** + * |GetContext| implements sharing of style contexts (not just the data + * on the rule nodes) between siblings and cousins of the same + * generation. (It works for cousins of the same generation since + * |aParentContext| could itself be a shared context.) + */ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, nsIStyleContext* aParentContext, nsIAtom* aPseudoTag, diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index bdeed8803e7a..b1600fa6f434 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -5213,6 +5213,11 @@ PresShell::ReconstructFrames(void) return rv; } +/* + * It's better to add stuff to the |DidSetStyleContext| method of the + * relevant frames than adding it here. This method should (ideally, + * anyway) go away. + */ static nsresult FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext, nsIFrame* aFrame) { @@ -5249,12 +5254,7 @@ FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext return NS_OK; } - // Outliners have a special style cache that needs to be flushed when - // the theme changes. - nsCOMPtr outlinerBox(do_QueryInterface(aFrame)); - if (outlinerBox) - outlinerBox->ClearStyleAndImageCaches(); - + // Perhaps this should move to the appropriate |DidSetStyleContext|? nsCOMPtr menuFrame(do_QueryInterface(aFrame)); if (menuFrame) { menuFrame->UngenerateMenu(); // We deliberately don't re-resolve style on @@ -5275,7 +5275,7 @@ FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext while (child) { nsFrameState state; child->GetFrameState(&state); - if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) { + if (!(state & NS_FRAME_OUT_OF_FLOW)) { // only do frames that are in flow nsCOMPtr frameType; child->GetFrameType(getter_AddRefs(frameType)); diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index bdeed8803e7a..b1600fa6f434 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -5213,6 +5213,11 @@ PresShell::ReconstructFrames(void) return rv; } +/* + * It's better to add stuff to the |DidSetStyleContext| method of the + * relevant frames than adding it here. This method should (ideally, + * anyway) go away. + */ static nsresult FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext, nsIFrame* aFrame) { @@ -5249,12 +5254,7 @@ FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext return NS_OK; } - // Outliners have a special style cache that needs to be flushed when - // the theme changes. - nsCOMPtr outlinerBox(do_QueryInterface(aFrame)); - if (outlinerBox) - outlinerBox->ClearStyleAndImageCaches(); - + // Perhaps this should move to the appropriate |DidSetStyleContext|? nsCOMPtr menuFrame(do_QueryInterface(aFrame)); if (menuFrame) { menuFrame->UngenerateMenu(); // We deliberately don't re-resolve style on @@ -5275,7 +5275,7 @@ FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext while (child) { nsFrameState state; child->GetFrameState(&state); - if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) { + if (!(state & NS_FRAME_OUT_OF_FLOW)) { // only do frames that are in flow nsCOMPtr frameType; child->GetFrameType(getter_AddRefs(frameType)); diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index bb5d829263fe..694bffd8c6f1 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -888,6 +888,12 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData) return PR_TRUE; } +/** + * |GetContext| implements sharing of style contexts (not just the data + * on the rule nodes) between siblings and cousins of the same + * generation. (It works for cousins of the same generation since + * |aParentContext| could itself be a shared context.) + */ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, nsIStyleContext* aParentContext, nsIAtom* aPseudoTag, diff --git a/layout/xul/base/src/outliner/public/nsIOutlinerBoxObject.idl b/layout/xul/base/src/outliner/public/nsIOutlinerBoxObject.idl index 6e3c022a8819..be8f62d413ab 100644 --- a/layout/xul/base/src/outliner/public/nsIOutlinerBoxObject.idl +++ b/layout/xul/base/src/outliner/public/nsIOutlinerBoxObject.idl @@ -164,11 +164,6 @@ interface nsIOutlinerBoxObject : nsISupports void onDragExit ( in nsIDOMEvent event ) ; void onDragOver ( in nsIDOMEvent event) ; void onDragDrop ( in nsIDOMEvent event ) ; - - /** - * Called on a theme switch to flush out the outliner's style and image caches. - */ - void clearStyleAndImageCaches(); }; %{C++ diff --git a/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.cpp b/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.cpp index c34c6ca54b1c..2e1b15dd262e 100644 --- a/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.cpp +++ b/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.cpp @@ -848,14 +848,32 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd) return NS_OK; } +nsIFrame* +nsOutlinerBodyFrame::EnsureScrollbar() +{ + if (!mScrollbar) { + // Try to find it. + nsCOMPtr parContent; + GetBaseElement(getter_AddRefs(parContent)); + nsCOMPtr shell; + mPresContext->GetShell(getter_AddRefs(shell)); + nsIFrame* outlinerFrame; + shell->GetPrimaryFrameFor(parContent, &outlinerFrame); + if (outlinerFrame) + mScrollbar = InitScrollbarFrame(mPresContext, outlinerFrame, this); + } + + NS_ASSERTION(mScrollbar, "no scroll bar"); + return mScrollbar; +} + void nsOutlinerBodyFrame::UpdateScrollbar() { // Update the scrollbar. - nsCOMPtr scrollbarContent; - NS_ASSERTION(mScrollbar, "no scroll bar"); - if (!mScrollbar) + if (!EnsureScrollbar()) return; + nsCOMPtr scrollbarContent; mScrollbar->GetContent(getter_AddRefs(scrollbarContent)); float t2p; mPresContext->GetTwipsToPixels(&t2p); @@ -906,20 +924,7 @@ nsresult nsOutlinerBodyFrame::CheckVerticalOverflow(PRBool aInReflow) NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar() { - if (!mScrollbar) { - // Try to find it. - nsCOMPtr parContent; - GetBaseElement(getter_AddRefs(parContent)); - nsCOMPtr shell; - mPresContext->GetShell(getter_AddRefs(shell)); - nsIFrame* outlinerFrame; - shell->GetPrimaryFrameFor(parContent, &outlinerFrame); - if (outlinerFrame) - mScrollbar = InitScrollbarFrame(mPresContext, outlinerFrame, this); - } - - NS_ASSERTION(mScrollbar, "no scroll bar"); - if (!mScrollbar || !mView) + if (!EnsureScrollbar() || !mView) return NS_OK; PRInt32 rowCount = 0; @@ -1842,6 +1847,16 @@ nsLineStyle nsOutlinerBodyFrame::ConvertBorderStyleToLineStyle(PRUint8 aBorderSt } } +NS_IMETHODIMP +nsOutlinerBodyFrame::DidSetStyleContext(nsIPresContext* aPresContext) +{ + mStyleCache.Clear(); + mImageCache = nsnull; + mScrollbar = nsnull; + + return nsLeafBoxFrame::DidSetStyleContext(aPresContext); +} + // Painting routines NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -2976,8 +2991,10 @@ nsOutlinerBodyFrame::ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex NS_IMETHODIMP nsOutlinerBodyFrame::PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex) { + if (!mRowHeight || !EnsureScrollbar()) + return NS_ERROR_UNEXPECTED; + float t2p; - if (!mRowHeight) return NS_ERROR_UNEXPECTED; mPresContext->GetTwipsToPixels(&t2p); nscoord rh = NSToCoordRound((float)mRowHeight*t2p); @@ -3129,14 +3146,6 @@ nsOutlinerBodyFrame::GetBaseElement(nsIContent** aContent) return NS_OK; } -NS_IMETHODIMP nsOutlinerBodyFrame::ClearStyleAndImageCaches() -{ - mStyleCache.Clear(); - mImageCache = nsnull; - mScrollbar = nsnull; - return NS_OK; -} - #ifdef XP_MAC #pragma mark - #endif diff --git a/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h b/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h index 58392fc67ad0..ba6a7076d608 100644 --- a/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h +++ b/layout/xul/base/src/outliner/src/nsOutlinerBodyFrame.h @@ -252,6 +252,9 @@ public: nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow); NS_IMETHOD Destroy(nsIPresContext* aPresContext); + // Overridden nsIFrame method to clear style cache + NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext); + // Painting methods. // Paint is the generic nsIFrame paint method. We override this method // to paint our contents (our rows and cells). @@ -378,6 +381,9 @@ protected: // Builds our cache of column info. void EnsureColumns(); + // Makes |mScrollbar| non-null if at all possible, and returns it. + nsIFrame* EnsureScrollbar(); + // Update the curpos of the scrollbar. void UpdateScrollbar(); diff --git a/layout/xul/base/src/outliner/src/nsOutlinerBoxObject.cpp b/layout/xul/base/src/outliner/src/nsOutlinerBoxObject.cpp index 0a166e02776e..a54633ec65ac 100644 --- a/layout/xul/base/src/outliner/src/nsOutlinerBoxObject.cpp +++ b/layout/xul/base/src/outliner/src/nsOutlinerBoxObject.cpp @@ -426,14 +426,6 @@ NS_IMETHODIMP nsOutlinerBoxObject::OnDragDrop(nsIDOMEvent* inEvent) return NS_OK; } -NS_IMETHODIMP nsOutlinerBoxObject::ClearStyleAndImageCaches() -{ - nsIOutlinerBoxObject* body = GetOutlinerBody(); - if (body) - return body->ClearStyleAndImageCaches(); - return NS_OK; -} - // Creation Routine /////////////////////////////////////////////////////////////////////// nsresult diff --git a/layout/xul/base/src/tree/public/nsITreeBoxObject.idl b/layout/xul/base/src/tree/public/nsITreeBoxObject.idl index 6e3c022a8819..be8f62d413ab 100644 --- a/layout/xul/base/src/tree/public/nsITreeBoxObject.idl +++ b/layout/xul/base/src/tree/public/nsITreeBoxObject.idl @@ -164,11 +164,6 @@ interface nsIOutlinerBoxObject : nsISupports void onDragExit ( in nsIDOMEvent event ) ; void onDragOver ( in nsIDOMEvent event) ; void onDragDrop ( in nsIDOMEvent event ) ; - - /** - * Called on a theme switch to flush out the outliner's style and image caches. - */ - void clearStyleAndImageCaches(); }; %{C++ diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index c34c6ca54b1c..2e1b15dd262e 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -848,14 +848,32 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd) return NS_OK; } +nsIFrame* +nsOutlinerBodyFrame::EnsureScrollbar() +{ + if (!mScrollbar) { + // Try to find it. + nsCOMPtr parContent; + GetBaseElement(getter_AddRefs(parContent)); + nsCOMPtr shell; + mPresContext->GetShell(getter_AddRefs(shell)); + nsIFrame* outlinerFrame; + shell->GetPrimaryFrameFor(parContent, &outlinerFrame); + if (outlinerFrame) + mScrollbar = InitScrollbarFrame(mPresContext, outlinerFrame, this); + } + + NS_ASSERTION(mScrollbar, "no scroll bar"); + return mScrollbar; +} + void nsOutlinerBodyFrame::UpdateScrollbar() { // Update the scrollbar. - nsCOMPtr scrollbarContent; - NS_ASSERTION(mScrollbar, "no scroll bar"); - if (!mScrollbar) + if (!EnsureScrollbar()) return; + nsCOMPtr scrollbarContent; mScrollbar->GetContent(getter_AddRefs(scrollbarContent)); float t2p; mPresContext->GetTwipsToPixels(&t2p); @@ -906,20 +924,7 @@ nsresult nsOutlinerBodyFrame::CheckVerticalOverflow(PRBool aInReflow) NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar() { - if (!mScrollbar) { - // Try to find it. - nsCOMPtr parContent; - GetBaseElement(getter_AddRefs(parContent)); - nsCOMPtr shell; - mPresContext->GetShell(getter_AddRefs(shell)); - nsIFrame* outlinerFrame; - shell->GetPrimaryFrameFor(parContent, &outlinerFrame); - if (outlinerFrame) - mScrollbar = InitScrollbarFrame(mPresContext, outlinerFrame, this); - } - - NS_ASSERTION(mScrollbar, "no scroll bar"); - if (!mScrollbar || !mView) + if (!EnsureScrollbar() || !mView) return NS_OK; PRInt32 rowCount = 0; @@ -1842,6 +1847,16 @@ nsLineStyle nsOutlinerBodyFrame::ConvertBorderStyleToLineStyle(PRUint8 aBorderSt } } +NS_IMETHODIMP +nsOutlinerBodyFrame::DidSetStyleContext(nsIPresContext* aPresContext) +{ + mStyleCache.Clear(); + mImageCache = nsnull; + mScrollbar = nsnull; + + return nsLeafBoxFrame::DidSetStyleContext(aPresContext); +} + // Painting routines NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -2976,8 +2991,10 @@ nsOutlinerBodyFrame::ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex NS_IMETHODIMP nsOutlinerBodyFrame::PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex) { + if (!mRowHeight || !EnsureScrollbar()) + return NS_ERROR_UNEXPECTED; + float t2p; - if (!mRowHeight) return NS_ERROR_UNEXPECTED; mPresContext->GetTwipsToPixels(&t2p); nscoord rh = NSToCoordRound((float)mRowHeight*t2p); @@ -3129,14 +3146,6 @@ nsOutlinerBodyFrame::GetBaseElement(nsIContent** aContent) return NS_OK; } -NS_IMETHODIMP nsOutlinerBodyFrame::ClearStyleAndImageCaches() -{ - mStyleCache.Clear(); - mImageCache = nsnull; - mScrollbar = nsnull; - return NS_OK; -} - #ifdef XP_MAC #pragma mark - #endif diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h index 58392fc67ad0..ba6a7076d608 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h @@ -252,6 +252,9 @@ public: nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow); NS_IMETHOD Destroy(nsIPresContext* aPresContext); + // Overridden nsIFrame method to clear style cache + NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext); + // Painting methods. // Paint is the generic nsIFrame paint method. We override this method // to paint our contents (our rows and cells). @@ -378,6 +381,9 @@ protected: // Builds our cache of column info. void EnsureColumns(); + // Makes |mScrollbar| non-null if at all possible, and returns it. + nsIFrame* EnsureScrollbar(); + // Update the curpos of the scrollbar. void UpdateScrollbar(); diff --git a/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp b/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp index 0a166e02776e..a54633ec65ac 100644 --- a/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp @@ -426,14 +426,6 @@ NS_IMETHODIMP nsOutlinerBoxObject::OnDragDrop(nsIDOMEvent* inEvent) return NS_OK; } -NS_IMETHODIMP nsOutlinerBoxObject::ClearStyleAndImageCaches() -{ - nsIOutlinerBoxObject* body = GetOutlinerBody(); - if (body) - return body->ClearStyleAndImageCaches(); - return NS_OK; -} - // Creation Routine /////////////////////////////////////////////////////////////////////// nsresult