зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ac0332e4d1
Коммит
e3bc7ee7fd
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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++
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче