From 5c5673fe67b3e4c3ac9efd8aa70ad79a548df0db Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Tue, 12 Sep 2006 04:36:03 +0000 Subject: [PATCH] Coalesce native theme change notifications to deal with the dozens of them we get when the GTK theme changes. Bug 352096, r+sr=roc --- layout/base/nsPresContext.cpp | 64 +++++++++++++++++++++++++++++++---- layout/base/nsPresContext.h | 8 +++++ 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index ff3761ddfe76..21900a4963ce 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -73,6 +73,8 @@ #include "nsIDOMDocument.h" #include "nsAutoPtr.h" #include "nsEventStateManager.h" +#include "nsThreadUtils.h" + #ifdef IBMBIDI #include "nsBidiPresUtils.h" #endif // IBMBIDI @@ -156,8 +158,7 @@ static NS_DEFINE_CID(kSelectionImageService, NS_SELECTIONIMAGESERVICE_CID); nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType) : mType(aType), mDocument(aDocument), mTextZoom(1.0), - mPageSize(-1, -1), mIsRootPaginatedDocument(PR_FALSE), - mCanPaginatedScroll(PR_FALSE), + mPageSize(-1, -1), mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO), mCompatibilityMode(eCompatibility_FullStandards), mImageAnimationModePref(imgIContainer::kNormalAnimMode), @@ -174,7 +175,9 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType) mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)), mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)) + NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)), + mCanPaginatedScroll(PR_FALSE), + mIsRootPaginatedDocument(PR_FALSE) { // NOTE! nsPresContext::operator new() zeroes out all members, so don't // bother initializing members to 0. @@ -290,6 +293,16 @@ static const char* const kGenericFont[] = { ".fantasy." }; +// Set to true when LookAndFeelChanged needs to be called. This is used +// because the look and feel is a service, so there's no need to notify it from +// more than one prescontext. +static PRBool sLookAndFeelChanged; + +// Set to true when ThemeChanged needs to be called on mTheme. This is used +// because mTheme is a service, so there's no need to notify it from more than +// one prescontext. +static PRBool sThemeChanged; + void nsPresContext::GetFontPreferences() { @@ -1217,14 +1230,36 @@ nsPresContext::GetTheme() void nsPresContext::ThemeChanged() { + if (!mPendingThemeChanged) { + sLookAndFeelChanged = PR_TRUE; + sThemeChanged = PR_TRUE; + + nsCOMPtr ev = + new nsRunnableMethod(this, + &nsPresContext::ThemeChangedInternal); + if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) { + mPendingThemeChanged = PR_TRUE; + } + } +} + +void +nsPresContext::ThemeChangedInternal() +{ + mPendingThemeChanged = PR_FALSE; + // Tell the theme that it changed, so it can flush any handles to stale theme // data. - if (mTheme) + if (mTheme && sThemeChanged) { mTheme->ThemeChanged(); + sThemeChanged = PR_FALSE; + } // Clear all cached nsILookAndFeel colors. - if (mLookAndFeel) + if (mLookAndFeel && sLookAndFeelChanged) { mLookAndFeel->LookAndFeelChanged(); + sLookAndFeelChanged = PR_FALSE; + } // We have to clear style data because the assumption of style rule // immutability has been violated since any style rule that uses @@ -1236,9 +1271,26 @@ nsPresContext::ThemeChanged() void nsPresContext::SysColorChanged() { - if (mLookAndFeel) { + if (!mPendingSysColorChanged) { + sLookAndFeelChanged = PR_TRUE; + nsCOMPtr ev = + new nsRunnableMethod(this, + &nsPresContext::SysColorChangedInternal); + if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) { + mPendingSysColorChanged = PR_TRUE; + } + } +} + +void +nsPresContext::SysColorChangedInternal() +{ + mPendingSysColorChanged = PR_FALSE; + + if (mLookAndFeel && sLookAndFeelChanged) { // Don't use the cached values for the system colors mLookAndFeel->LookAndFeelChanged(); + sLookAndFeelChanged = PR_FALSE; } // Reset default background and foreground colors for the document since diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 4a6574c3f6e8..c5a822219c7c 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -84,6 +84,8 @@ class nsICSSPseudoComparator; class nsIAtom; struct nsStyleStruct; struct nsStyleBackground; +template class nsRunnableMethod; +class nsIRunnable; #ifdef MOZ_REFLOW_PERF class nsIRenderingContext; @@ -653,6 +655,10 @@ public: mType == eContext_PrintPreview); }; protected: + friend class nsRunnableMethod; + NS_HIDDEN_(void) ThemeChangedInternal(); + NS_HIDDEN_(void) SysColorChangedInternal(); + NS_HIDDEN_(void) SetImgAnimations(nsIContent *aParent, PRUint16 aMode); NS_HIDDEN_(void) GetDocumentColorPreferences(); @@ -754,6 +760,8 @@ protected: unsigned mIsRootPaginatedDocument : 1; unsigned mPrefBidiDirection : 1; unsigned mPrefScrollbarSide : 2; + unsigned mPendingSysColorChanged : 1; + unsigned mPendingThemeChanged : 1; #ifdef IBMBIDI unsigned mIsVisual : 1;