Bug 669028 part.2 Make nsLookAndFeel singleton r=roc
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 09 Sep 2011 11:27:11 +0900
changeset 76808 7e1031d213ba3764606578c23e85f97fef9ace57
parent 76807 71486524f1ed28a41a8bfb6ac6188f5c31202858
child 76809 19b106d56f8a558817688b6d554ce956018e9f0b
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersroc
bugs669028
milestone9.0a1
Bug 669028 part.2 Make nsLookAndFeel singleton r=roc
widget/src/android/nsWidgetFactory.cpp
widget/src/build/nsWinWidgetFactory.cpp
widget/src/cocoa/nsWidgetFactory.mm
widget/src/gtk2/nsWidgetFactory.cpp
widget/src/os2/nsWidgetFactory.cpp
widget/src/qt/nsWidgetFactory.cpp
widget/src/xpwidgets/nsXPLookAndFeel.cpp
widget/src/xpwidgets/nsXPLookAndFeel.h
--- a/widget/src/android/nsWidgetFactory.cpp
+++ b/widget/src/android/nsWidgetFactory.cpp
@@ -58,17 +58,18 @@
 #include "nsFilePicker.h"
 #include "nsHTMLFormatConverter.h"
 #include "nsIMEPicker.h"
 #include "nsFilePickerProxy.h"
 #include "nsXULAppAPI.h"
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsLookAndFeel,
+                                         nsLookAndFeel::GetAddRefedInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerAndroid)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceAndroid)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsAndroid, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecAndroid)
@@ -159,16 +160,17 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/imepicker;1", &kNS_IMEPICKER_CID },
   { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
   { NULL }
 };
 
 static void
 nsWidgetAndroidModuleDtor()
 {
+    nsLookAndFeel::Shutdown();
     nsAppShellShutdown();
 }
 
 static const mozilla::Module kWidgetModule = {
     mozilla::Module::kVersion,
     kWidgetCIDs,
     kWidgetContracts,
     NULL,
--- a/widget/src/build/nsWinWidgetFactory.cpp
+++ b/widget/src/build/nsWinWidgetFactory.cpp
@@ -75,17 +75,18 @@
 #include "nsPrintSession.h"
 #endif
 
 using namespace mozilla::widget;
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(ChildWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsLookAndFeel,
+                                         nsLookAndFeel::GetAddRefedInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerWin)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceWin)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
@@ -217,19 +218,26 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
   { "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID },
   { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
   { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
 #endif
   { NULL }
 };
 
+static void
+nsWidgetWindowsModuleDtor()
+{
+  nsLookAndFeel::Shutdown();
+  nsAppShellShutdown();
+}
+
 static const mozilla::Module kWidgetModule = {
   mozilla::Module::kVersion,
   kWidgetCIDs,
   kWidgetContracts,
   NULL,
   NULL,
   nsAppShellInit,
-  nsAppShellShutdown
+  nsWidgetWindowsModuleDtor
 };
 
 NSMODULE_DEFN(nsWidgetModule) = &kWidgetModule;
--- a/widget/src/cocoa/nsWidgetFactory.mm
+++ b/widget/src/cocoa/nsWidgetFactory.mm
@@ -65,17 +65,18 @@
 #include "nsPrintOptionsX.h"
 #include "nsPrintDialogX.h"
 #include "nsPrintSession.h"
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCocoaWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildView)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsLookAndFeel,
+                                         nsLookAndFeel::GetAddRefedInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerCocoa)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecX)
@@ -188,19 +189,26 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
   { "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
   { "@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID },
   { "@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID },
   { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
   { NULL }
 };
 
+static void
+nsWidgetCocoaModuleDtor()
+{
+  nsLookAndFeel::Shutdown();
+  nsAppShellShutdown();
+}
+
 static const mozilla::Module kWidgetModule = {
   mozilla::Module::kVersion,
   kWidgetCIDs,
   kWidgetContracts,
   NULL,
   NULL,
   nsAppShellInit,
-  nsAppShellShutdown
+  nsWidgetCocoaModuleDtor
 };
 
 NSMODULE_DEFN(nsWidgetMacModule) = &kWidgetModule;
--- a/widget/src/gtk2/nsWidgetFactory.cpp
+++ b/widget/src/gtk2/nsWidgetFactory.cpp
@@ -87,17 +87,18 @@ using namespace mozilla;
 #define XULFILEPICKER_CID \
   { 0x54ae32f8, 0x1dd2, 0x11b2, \
     { 0xa2, 0x09, 0xdf, 0x7c, 0x50, 0x53, 0x70, 0xf8} }
 static NS_DEFINE_CID(kXULFilePickerCID, XULFILEPICKER_CID);
 static NS_DEFINE_CID(kNativeFilePickerCID, NS_FILEPICKER_CID);
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsLookAndFeel,
+                                         nsLookAndFeel::GetAddRefedInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 #ifdef MOZ_X11
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsClipboard, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 #endif
@@ -334,16 +335,17 @@ static const mozilla::Module::ContractID
     { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
 #endif
     { NULL }
 };
 
 static void
 nsWidgetGtk2ModuleDtor()
 {
+  nsLookAndFeel::Shutdown();
   nsFilePicker::Shutdown();
   nsSound::Shutdown();
   nsWindow::ReleaseGlobals();
   nsAppShellShutdown();
 }
 
 static const mozilla::Module kWidgetModule = {
     mozilla::Module::kVersion,
--- a/widget/src/os2/nsWidgetFactory.cpp
+++ b/widget/src/os2/nsWidgetFactory.cpp
@@ -88,17 +88,18 @@
 
 // objects that just require generic constructors
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsLookAndFeel,
+                                         nsLookAndFeel::GetAddRefedInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecOS2)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsOS2, Init)
@@ -176,16 +177,17 @@ static const mozilla::Module::ContractID
   { NS_RWSSERVICE_CONTRACTID, &kNS_RWSSERVICE_CID },
   { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
   { NULL }
 };
 
 static void
 nsWidgetOS2ModuleDtor()
 {
+  nsLookAndFeel::Shutdown();
   nsWindow::ReleaseGlobals();
   nsFilePicker::ReleaseGlobals();
   nsAppShellShutdown();
 }
 
 static const mozilla::Module kWidgetModule = {
   mozilla::Module::kVersion,
   kWidgetCIDs,
--- a/widget/src/qt/nsWidgetFactory.cpp
+++ b/widget/src/qt/nsWidgetFactory.cpp
@@ -78,17 +78,18 @@
 extern PRBool gDisableNativeTheme;
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPopupWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsLookAndFeel,
+                                         nsLookAndFeel::GetAddRefedInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerQt)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceQt)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 
@@ -243,16 +244,17 @@ static const mozilla::Module::ContractID
     { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
 #endif
     { NULL }
 };
 
 static void
 nsWidgetQtModuleDtor()
 {
+    nsLookAndFeel::Shutdown();
     nsSound::Shutdown();
     nsWindow::ReleaseGlobals();
     nsAppShellShutdown();
 }
 
 static const mozilla::Module kWidgetModule = {
     mozilla::Module::kVersion,
     kWidgetCIDs,
--- a/widget/src/xpwidgets/nsXPLookAndFeel.cpp
+++ b/widget/src/xpwidgets/nsXPLookAndFeel.cpp
@@ -33,16 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nscore.h"
 
 #include "nsXPLookAndFeel.h"
+#include "nsLookAndFeel.h"
 #include "nsCRT.h"
 #include "nsFont.h"
 #include "mozilla/Preferences.h"
 
 #include "gfxPlatform.h"
 #include "qcms.h"
 
 #ifdef DEBUG
@@ -208,16 +209,55 @@ const char nsXPLookAndFeel::sColorPrefs[
 };
 
 PRInt32 nsXPLookAndFeel::sCachedColors[nsILookAndFeel::eColor_LAST_COLOR] = {0};
 PRInt32 nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
 
 PRBool nsXPLookAndFeel::sInitialized = PR_FALSE;
 PRBool nsXPLookAndFeel::sUseNativeColors = PR_TRUE;
 
+nsXPLookAndFeel* nsXPLookAndFeel::sInstance = nsnull;
+PRBool nsXPLookAndFeel::sShutdown = PR_FALSE;
+
+// static
+nsLookAndFeel*
+nsXPLookAndFeel::GetAddRefedInstance()
+{
+  nsLookAndFeel* lookAndFeel = GetInstance();
+  NS_IF_ADDREF(lookAndFeel);
+  return lookAndFeel;
+}
+
+// static
+nsLookAndFeel*
+nsXPLookAndFeel::GetInstance()
+{
+  if (sInstance) {
+    return static_cast<nsLookAndFeel*>(sInstance);
+  }
+
+  NS_ENSURE_TRUE(!sShutdown, nsnull);
+
+  NS_ADDREF(sInstance = new nsLookAndFeel());
+  return static_cast<nsLookAndFeel*>(sInstance);
+}
+
+// static
+void
+nsXPLookAndFeel::Shutdown()
+{
+  if (sShutdown) {
+    return;
+  }
+  sShutdown = PR_TRUE;
+  if (sInstance) {
+    sInstance->Release();
+  }
+}
+
 nsXPLookAndFeel::nsXPLookAndFeel() : nsILookAndFeel()
 {
 }
 
 // static
 void
 nsXPLookAndFeel::IntPrefChanged (nsLookAndFeelIntPref *data)
 {
@@ -401,16 +441,19 @@ nsXPLookAndFeel::Init()
   PRBool val;
   if (NS_SUCCEEDED(Preferences::GetBool("ui.use_native_colors", &val))) {
     sUseNativeColors = val;
   }
 }
 
 nsXPLookAndFeel::~nsXPLookAndFeel()
 {
+  NS_ASSERTION(sInstance == this,
+               "This destroying instance isn't the singleton instance");
+  sInstance = nsnull;
 }
 
 PRBool
 nsXPLookAndFeel::IsSpecialColor(const nsColorID aID, nscolor &aColor)
 {
   switch (aID) {
     case eColor_TextSelectForeground:
       return (aColor == NS_DONT_CHANGE_COLOR);
--- a/widget/src/xpwidgets/nsXPLookAndFeel.h
+++ b/widget/src/xpwidgets/nsXPLookAndFeel.h
@@ -40,16 +40,18 @@
 
 #include "nsILookAndFeel.h"
 #include "nsCOMPtr.h"
 
 #ifdef NS_DEBUG
 struct nsSize;
 #endif
 
+class nsLookAndFeel;
+
 typedef enum {
   nsLookAndFeelTypeInt,
   nsLookAndFeelTypeFloat,
   nsLookAndFeelTypeColor
 } nsLookAndFeelType;
 
 struct nsLookAndFeelIntPref
 {
@@ -82,16 +84,20 @@ struct nsLookAndFeelFloatPref
 class nsXPLookAndFeel: public nsILookAndFeel
 {
 public:
   nsXPLookAndFeel();
   virtual ~nsXPLookAndFeel();
 
   NS_DECL_ISUPPORTS
 
+  static nsLookAndFeel* GetAddRefedInstance();
+  static nsLookAndFeel* GetInstance();
+  static void Shutdown();
+
   void Init();
 
   //
   // All these routines will return NS_OK if they have a value,
   // in which case the nsLookAndFeel should use that value;
   // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
   // platform-specific nsLookAndFeel should use its own values instead.
   //
@@ -125,13 +131,14 @@ protected:
   static nsLookAndFeelFloatPref sFloatPrefs[];
   /* this length must not be shorter than the length of the longest string in the array
    * see nsXPLookAndFeel.cpp
    */
   static const char sColorPrefs[][38];
   static PRInt32 sCachedColors[nsILookAndFeel::eColor_LAST_COLOR];
   static PRInt32 sCachedColorBits[COLOR_CACHE_SIZE];
   static PRBool sUseNativeColors;
+
+  static nsXPLookAndFeel* sInstance;
+  static PRBool sShutdown;
 };
 
-extern nsresult NS_NewXPLookAndFeel(nsILookAndFeel**);
-
 #endif