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

This commit is contained in:
dbaron%fas.harvard.edu 2002-03-07 23:48:26 +00:00
parent ac0332e4d1
commit e3bc7ee7fd
12 changed files with 108 additions and 92 deletions

View File

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

View File

@ -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<nsIOutlinerBoxObject> outlinerBox(do_QueryInterface(aFrame));
if (outlinerBox)
outlinerBox->ClearStyleAndImageCaches();
// Perhaps this should move to the appropriate |DidSetStyleContext|?
nsCOMPtr<nsIMenuFrame> 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<nsIAtom> frameType;
child->GetFrameType(getter_AddRefs(frameType));

View File

@ -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<nsIOutlinerBoxObject> outlinerBox(do_QueryInterface(aFrame));
if (outlinerBox)
outlinerBox->ClearStyleAndImageCaches();
// Perhaps this should move to the appropriate |DidSetStyleContext|?
nsCOMPtr<nsIMenuFrame> 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<nsIAtom> frameType;
child->GetFrameType(getter_AddRefs(frameType));

View File

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

View File

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

View File

@ -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<nsIContent> parContent;
GetBaseElement(getter_AddRefs(parContent));
nsCOMPtr<nsIPresShell> 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<nsIContent> scrollbarContent;
NS_ASSERTION(mScrollbar, "no scroll bar");
if (!mScrollbar)
if (!EnsureScrollbar())
return;
nsCOMPtr<nsIContent> 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<nsIContent> parContent;
GetBaseElement(getter_AddRefs(parContent));
nsCOMPtr<nsIPresShell> 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

View File

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

View File

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

View File

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

View File

@ -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<nsIContent> parContent;
GetBaseElement(getter_AddRefs(parContent));
nsCOMPtr<nsIPresShell> 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<nsIContent> scrollbarContent;
NS_ASSERTION(mScrollbar, "no scroll bar");
if (!mScrollbar)
if (!EnsureScrollbar())
return;
nsCOMPtr<nsIContent> 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<nsIContent> parContent;
GetBaseElement(getter_AddRefs(parContent));
nsCOMPtr<nsIPresShell> 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

View File

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

View File

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