9fc1c5f
Index: layout/base/nsPresContext.cpp
9fc1c5f
===================================================================
9fc1c5f
RCS file: /cvsroot/mozilla/layout/base/nsPresContext.cpp,v
9fc1c5f
retrieving revision 3.288.12.2.4.1
9fc1c5f
diff -d -u -p -r3.288.12.2.4.1 nsPresContext.cpp
9fc1c5f
--- layout/base/nsPresContext.cpp	21 Apr 2006 23:30:50 -0000	3.288.12.2.4.1
9fc1c5f
+++ layout/base/nsPresContext.cpp	26 Sep 2006 19:26:40 -0000
9fc1c5f
@@ -73,6 +73,9 @@
9fc1c5f
 #include "nsIDOMDocument.h"
9fc1c5f
 #include "nsAutoPtr.h"
9fc1c5f
 #include "nsEventStateManager.h"
9fc1c5f
+#include "nsIEventQueue.h"
9fc1c5f
+#include "nsIEventQueueService.h"
9fc1c5f
+
9fc1c5f
 #ifdef IBMBIDI
9fc1c5f
 #include "nsBidiPresUtils.h"
9fc1c5f
 #endif // IBMBIDI
9fc1c5f
@@ -267,6 +270,7 @@ nsPresContext::~nsPresContext()
9fc1c5f
   NS_IF_RELEASE(mDeviceContext);
9fc1c5f
   NS_IF_RELEASE(mLookAndFeel);
9fc1c5f
   NS_IF_RELEASE(mLangGroup);
9fc1c5f
+  NS_IF_RELEASE(mEventQueueService);
9fc1c5f
 }
9fc1c5f
 
9fc1c5f
 NS_IMPL_ISUPPORTS2(nsPresContext, nsPresContext, nsIObserver)
9fc1c5f
@@ -285,6 +289,17 @@ static const char* const kGenericFont[] 
9fc1c5f
   ".fantasy."
9fc1c5f
 };
9fc1c5f
 
9fc1c5f
+// Set to true when LookAndFeelChanged needs to be called.  This is used
9fc1c5f
+// because the look and feel is a service, so there's no need to notify it from
9fc1c5f
+// more than one prescontext.
9fc1c5f
+static PRBool sLookAndFeelChanged;
9fc1c5f
+
9fc1c5f
+// Set to true when ThemeChanged needs to be called on mTheme.  This is used
9fc1c5f
+// because mTheme is a service, so there's no need to notify it from more than
9fc1c5f
+// one prescontext.
9fc1c5f
+static PRBool sThemeChanged;
9fc1c5f
+
9fc1c5f
+
9fc1c5f
 void
9fc1c5f
 nsPresContext::GetFontPreferences()
9fc1c5f
 {
9fc1c5f
@@ -709,6 +724,9 @@ nsPresContext::Init(nsIDeviceContext* aD
9fc1c5f
                                        this);
9fc1c5f
 #endif
9fc1c5f
 
9fc1c5f
+  rv = CallGetService(NS_EVENTQUEUESERVICE_CONTRACTID, &mEventQueueService);
9fc1c5f
+  NS_ENSURE_SUCCESS(rv, rv);
9fc1c5f
+
9fc1c5f
   // Initialize our state from the user preferences
9fc1c5f
   GetUserPreferences();
9fc1c5f
 
9fc1c5f
@@ -1180,33 +1198,126 @@ nsPresContext::GetTheme()
9fc1c5f
 void
9fc1c5f
 nsPresContext::ThemeChanged()
9fc1c5f
 {
9fc1c5f
+  if (!mPendingThemeChanged) {
9fc1c5f
+    sLookAndFeelChanged = PR_TRUE;
9fc1c5f
+    sThemeChanged = PR_TRUE;
9fc1c5f
+
9fc1c5f
+    nsCOMPtr<nsIEventQueue> eventQ;
9fc1c5f
+    mEventQueueService->
9fc1c5f
+      GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE,
9fc1c5f
+                           getter_AddRefs(eventQ));
9fc1c5f
+    if (!eventQ) {
9fc1c5f
+      return;
9fc1c5f
+    }
9fc1c5f
+
9fc1c5f
+    PLEvent* evt = new PLEvent();
9fc1c5f
+    if (!evt) {
9fc1c5f
+      return;
9fc1c5f
+    }
9fc1c5f
+
9fc1c5f
+    PL_InitEvent(evt, this, nsPresContext::ThemeChangedInternal,
9fc1c5f
+                 nsPresContext::DestroyThemeChangeEvt);
9fc1c5f
+
9fc1c5f
+    // After this point, event destruction will release |this|
9fc1c5f
+    NS_ADDREF_THIS();
9fc1c5f
+
9fc1c5f
+    nsresult rv = eventQ->PostEvent(evt);
9fc1c5f
+    if (NS_FAILED(rv)) {
9fc1c5f
+      PL_DestroyEvent(evt);
9fc1c5f
+    } else {
9fc1c5f
+      mPendingThemeChanged = PR_TRUE;
9fc1c5f
+    }
9fc1c5f
+  }    
9fc1c5f
+}
9fc1c5f
+
9fc1c5f
+void* PR_CALLBACK
9fc1c5f
+nsPresContext::ThemeChangedInternal(PLEvent *aEvent)
9fc1c5f
+{
9fc1c5f
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
9fc1c5f
+
9fc1c5f
+  pc->mPendingThemeChanged = PR_FALSE;
9fc1c5f
+
9fc1c5f
   // Tell the theme that it changed, so it can flush any handles to stale theme
9fc1c5f
   // data.
9fc1c5f
-  if (mTheme)
9fc1c5f
-    mTheme->ThemeChanged();
9fc1c5f
+  if (pc->mTheme && sThemeChanged) {
9fc1c5f
+    pc->mTheme->ThemeChanged();
9fc1c5f
+    sThemeChanged = PR_FALSE;
9fc1c5f
+  }
9fc1c5f
 
9fc1c5f
   // Clear all cached nsILookAndFeel colors.
9fc1c5f
-  if (mLookAndFeel)
9fc1c5f
-    mLookAndFeel->LookAndFeelChanged();
9fc1c5f
+  if (pc->mLookAndFeel && sLookAndFeelChanged) {
9fc1c5f
+    pc->mLookAndFeel->LookAndFeelChanged();
9fc1c5f
+    sLookAndFeelChanged = PR_FALSE;
9fc1c5f
+  }
9fc1c5f
 
9fc1c5f
   // We have to clear style data because the assumption of style rule
9fc1c5f
   // immutability has been violated since any style rule that uses
9fc1c5f
   // system colors or fonts (and probably -moz-appearance as well) has
9fc1c5f
   // changed.
9fc1c5f
-  nsPresContext::ClearStyleDataAndReflow();
9fc1c5f
+  pc->ClearStyleDataAndReflow();
9fc1c5f
+
9fc1c5f
+  return nsnull;
9fc1c5f
+}
9fc1c5f
+
9fc1c5f
+
9fc1c5f
+void PR_CALLBACK
9fc1c5f
+nsPresContext::DestroyThemeChangeEvt(PLEvent* aEvent)
9fc1c5f
+{
9fc1c5f
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
9fc1c5f
+  NS_RELEASE(pc);
9fc1c5f
+  delete aEvent;
9fc1c5f
 }
9fc1c5f
 
9fc1c5f
 void
9fc1c5f
 nsPresContext::SysColorChanged()
9fc1c5f
 {
9fc1c5f
-  if (mLookAndFeel) {
9fc1c5f
+  if (!mPendingSysColorChanged) {
9fc1c5f
+    sLookAndFeelChanged = PR_TRUE;
9fc1c5f
+
9fc1c5f
+    nsCOMPtr<nsIEventQueue> eventQ;
9fc1c5f
+    mEventQueueService->
9fc1c5f
+      GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE,
9fc1c5f
+                           getter_AddRefs(eventQ));
9fc1c5f
+    if (!eventQ) {
9fc1c5f
+      return;
9fc1c5f
+    }
9fc1c5f
+
9fc1c5f
+    PLEvent* evt = new PLEvent();
9fc1c5f
+    if (!evt) {
9fc1c5f
+      return;
9fc1c5f
+    }
9fc1c5f
+
9fc1c5f
+    PL_InitEvent(evt, this, nsPresContext::SysColorChangedInternal,
9fc1c5f
+                 nsPresContext::DestroySysColorChangeEvt);
9fc1c5f
+
9fc1c5f
+    // After this point, event destruction will release |this|
9fc1c5f
+    NS_ADDREF_THIS();
9fc1c5f
+
9fc1c5f
+    nsresult rv = eventQ->PostEvent(evt);
9fc1c5f
+    if (NS_FAILED(rv)) {
9fc1c5f
+      PL_DestroyEvent(evt);
9fc1c5f
+    } else {
9fc1c5f
+      mPendingSysColorChanged = PR_TRUE;
9fc1c5f
+    }
9fc1c5f
+  }
9fc1c5f
+}
9fc1c5f
+
9fc1c5f
+void* PR_CALLBACK
9fc1c5f
+nsPresContext::SysColorChangedInternal(PLEvent *aEvent)
9fc1c5f
+{
9fc1c5f
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
9fc1c5f
+
9fc1c5f
+  pc->mPendingSysColorChanged = PR_FALSE;
9fc1c5f
+  
9fc1c5f
+  if (pc->mLookAndFeel && sLookAndFeelChanged) {
9fc1c5f
      // Don't use the cached values for the system colors
9fc1c5f
-    mLookAndFeel->LookAndFeelChanged();
9fc1c5f
+    pc->mLookAndFeel->LookAndFeelChanged();
9fc1c5f
+    sLookAndFeelChanged = PR_FALSE;
9fc1c5f
   }
9fc1c5f
-   
9fc1c5f
+
9fc1c5f
   // Reset default background and foreground colors for the document since
9fc1c5f
   // they may be using system colors
9fc1c5f
-  GetDocumentColorPreferences();
9fc1c5f
+  pc->GetDocumentColorPreferences();
9fc1c5f
 
9fc1c5f
   // Clear out all of the style data since it may contain RGB values
9fc1c5f
   // which originated from system colors.
9fc1c5f
@@ -1222,7 +1333,17 @@ nsPresContext::SysColorChanged()
9fc1c5f
   // data without reflowing/updating views will lead to incorrect change hints
9fc1c5f
   // later, because when generating change hints, any style structs which have
9fc1c5f
   // been cleared and not reread are assumed to not be used at all.
9fc1c5f
-  ClearStyleDataAndReflow();
9fc1c5f
+  pc->ClearStyleDataAndReflow();
9fc1c5f
+
9fc1c5f
+  return nsnull;
9fc1c5f
+}
9fc1c5f
+
9fc1c5f
+void PR_CALLBACK
9fc1c5f
+nsPresContext::DestroySysColorChangeEvt(PLEvent* aEvent)
9fc1c5f
+{
9fc1c5f
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
9fc1c5f
+  NS_RELEASE(pc);
9fc1c5f
+  delete aEvent;
9fc1c5f
 }
9fc1c5f
 
9fc1c5f
 void
9fc1c5f
Index: layout/base/nsPresContext.h
9fc1c5f
===================================================================
9fc1c5f
RCS file: /cvsroot/mozilla/layout/base/nsPresContext.h,v
9fc1c5f
retrieving revision 3.150.4.2
9fc1c5f
diff -d -u -p -r3.150.4.2 nsPresContext.h
9fc1c5f
--- layout/base/nsPresContext.h	29 Aug 2005 16:15:39 -0000	3.150.4.2
9fc1c5f
+++ layout/base/nsPresContext.h	26 Sep 2006 19:26:40 -0000
9fc1c5f
@@ -56,6 +56,7 @@
9fc1c5f
 #include "nsCRT.h"
9fc1c5f
 #include "nsIPrintSettings.h"
9fc1c5f
 #include "nsPropertyTable.h"
9fc1c5f
+#include "plevent.h"
9fc1c5f
 #ifdef IBMBIDI
9fc1c5f
 class nsBidiPresUtils;
9fc1c5f
 #endif // IBMBIDI
9fc1c5f
@@ -76,6 +77,7 @@ class nsIAtom;
9fc1c5f
 class nsIEventStateManager;
9fc1c5f
 class nsIURI;
9fc1c5f
 class nsILookAndFeel;
9fc1c5f
+class nsIEventQueueService;
9fc1c5f
 class nsICSSPseudoComparator;
9fc1c5f
 class nsIAtom;
9fc1c5f
 struct nsStyleStruct;
9fc1c5f
@@ -627,6 +629,14 @@ public:
9fc1c5f
   const nscoord* GetBorderWidthTable() { return mBorderWidthTable; }
9fc1c5f
 
9fc1c5f
 protected:
9fc1c5f
+  static NS_HIDDEN_(void*) PR_CALLBACK ThemeChangedInternal(PLEvent* aEvent);
9fc1c5f
+  static NS_HIDDEN_(void*) PR_CALLBACK SysColorChangedInternal(PLEvent* aEvent);
9fc1c5f
+  static NS_HIDDEN_(void) PR_CALLBACK DestroyThemeChangeEvt(PLEvent* aEvent);
9fc1c5f
+  static NS_HIDDEN_(void) PR_CALLBACK DestroySysColorChangeEvt(PLEvent* aEvent);
9fc1c5f
+
9fc1c5f
+  friend void* PR_CALLBACK ThemeChangedInternal(PLEvent* aEvent);
9fc1c5f
+  friend void* PR_CALLBACK SysColorChangedInternal(PLEvent* aEvent);
9fc1c5f
+
9fc1c5f
   NS_HIDDEN_(void) SetImgAnimations(nsIContent *aParent, PRUint16 aMode);
9fc1c5f
   NS_HIDDEN_(void) GetDocumentColorPreferences();
9fc1c5f
 
9fc1c5f
@@ -654,6 +664,7 @@ protected:
9fc1c5f
                                         // from gfx back to layout.
9fc1c5f
   nsIEventStateManager* mEventManager;  // [STRONG]
9fc1c5f
   nsILookAndFeel*       mLookAndFeel;   // [STRONG]
9fc1c5f
+  nsIEventQueueService *mEventQueueService; // [STRONG]
9fc1c5f
   nsIAtom*              mMedium;        // initialized by subclass ctors;
9fc1c5f
                                         // weak pointer to static atom
9fc1c5f
 
9fc1c5f
@@ -724,6 +735,8 @@ protected:
9fc1c5f
   unsigned              mCanPaginatedScroll : 1;
9fc1c5f
   unsigned              mDoScaledTwips : 1;
9fc1c5f
   unsigned              mEnableJapaneseTransform : 1;
9fc1c5f
+  unsigned              mPendingSysColorChanged : 1;
9fc1c5f
+  unsigned              mPendingThemeChanged : 1;
9fc1c5f
 #ifdef IBMBIDI
9fc1c5f
   unsigned              mIsVisual : 1;
9fc1c5f
   unsigned              mIsBidiSystem : 1;