Bug 503879, remove nsIToolkit, additinal windows only changes which simplify message handling, patch by robarnold, r=jmathies
authorNeil Deakin <neil@mozilla.com>
Thu, 03 Nov 2011 16:39:07 -0400
changeset 79696 ca673b65d7eb5c90a2d51a6b59c6c7dcb8f7b708
parent 79695 52b9e8718829e49d544185d47a75aa2cffc21c17
child 79697 e0274a0c094e153c7e4a52c96d5ebd1d6dea8018
push id3103
push userneil@mozilla.com
push dateThu, 03 Nov 2011 20:41:05 +0000
treeherdermozilla-inbound@797d8083efca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs503879
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 503879, remove nsIToolkit, additinal windows only changes which simplify message handling, patch by robarnold, r=jmathies
widget/src/windows/nsToolkit.cpp
widget/src/windows/nsToolkit.h
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
--- a/widget/src/windows/nsToolkit.cpp
+++ b/widget/src/windows/nsToolkit.cpp
@@ -51,88 +51,41 @@
 #include "nsUXThemeData.h"
 
 // unknwn.h is needed to build with WIN32_LEAN_AND_MEAN
 #include <unknwn.h>
 
 nsToolkit* nsToolkit::gToolkit = nsnull;
 
 HINSTANCE nsToolkit::mDllInstance = 0;
-bool      nsToolkit::mIsWinXP     = false;
-static bool dummy = nsToolkit::InitVersionInfo();
 
 static const unsigned long kD3DUsageDelay = 5000;
 
 static void
 StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
 {
   nsWindow::StartAllowingD3D9(true);
 }
 
-//
-// main for the message pump thread
-//
-bool gThreadState = false;
-
-struct ThreadInitInfo {
-    PRMonitor *monitor;
-    nsToolkit *toolkit;
-};
-
 MouseTrailer*       nsToolkit::gMouseTrailer;
 
-void RunPump(void* arg)
-{
-    ThreadInitInfo *info = (ThreadInitInfo*)arg;
-    ::PR_EnterMonitor(info->monitor);
-
-    // do registration and creation in this thread
-    info->toolkit->CreateInternalWindow(PR_GetCurrentThread());
-
-    gThreadState = true;
-
-    ::PR_Notify(info->monitor);
-    ::PR_ExitMonitor(info->monitor);
-
-    delete info;
-
-    // Process messages
-    MSG msg;
-    while (::GetMessageW(&msg, NULL, 0, 0)) {
-        TranslateMessage(&msg);
-        ::DispatchMessageW(&msg);
-    }
-}
-
 //-------------------------------------------------------------------------
 //
 // constructor
 //
 //-------------------------------------------------------------------------
 nsToolkit::nsToolkit()  
 {
     MOZ_COUNT_CTOR(nsToolkit);
-    mGuiThread  = NULL;
-    mDispatchWnd = 0;
 
 #if defined(MOZ_STATIC_COMPONENT_LIBS)
     nsToolkit::Startup(GetModuleHandle(NULL));
 #endif
 
-    gMouseTrailer = new MouseTrailer();
-
-    // Store the thread ID of the thread containing the message pump.  
-    // If no thread is provided create one
-    PRThread* thread = PR_GetCurrentThread();
-    if (NULL != thread) {
-      CreateInternalWindow(thread);
-    } else {
-      // create a thread where the message pump will run
-      CreateUIThread();
-    }
+    gMouseTrailer = &mMouseTrailer;
 
     mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1");
     mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9,
                                      NULL,
                                      kD3DUsageDelay,
                                      nsITimer::TYPE_ONE_SHOT);
 }
 
@@ -140,207 +93,57 @@ nsToolkit::nsToolkit()
 //-------------------------------------------------------------------------
 //
 // destructor
 //
 //-------------------------------------------------------------------------
 nsToolkit::~nsToolkit()
 {
     MOZ_COUNT_DTOR(nsToolkit);
-    NS_PRECONDITION(::IsWindow(mDispatchWnd), "Invalid window handle");
-
-    // Destroy the Dispatch Window
-    ::DestroyWindow(mDispatchWnd);
-    mDispatchWnd = NULL;
-
-    if (gMouseTrailer) {
-      gMouseTrailer->DestroyTimer();
-      delete gMouseTrailer;
-      gMouseTrailer = nsnull;
-    }
+    gMouseTrailer = nsnull;
 }
 
 void
 nsToolkit::Startup(HMODULE hModule)
 {
     nsToolkit::mDllInstance = hModule;
-
-    //
-    // register the internal window class
-    //
-    WNDCLASSW wc;
-    wc.style            = CS_GLOBALCLASS;
-    wc.lpfnWndProc      = nsToolkit::WindowProc;
-    wc.cbClsExtra       = 0;
-    wc.cbWndExtra       = 0;
-    wc.hInstance        = nsToolkit::mDllInstance;
-    wc.hIcon            = NULL;
-    wc.hCursor          = NULL;
-    wc.hbrBackground    = NULL;
-    wc.lpszMenuName     = NULL;
-    wc.lpszClassName    = L"nsToolkitClass";
-    VERIFY(::RegisterClassW(&wc) || 
-           GetLastError() == ERROR_CLASS_ALREADY_EXISTS);
-
     nsUXThemeData::Initialize();
 }
 
-
 void
 nsToolkit::Shutdown()
 {
-#if defined (MOZ_STATIC_COMPONENT_LIBS)
-    // Crashes on certain XP machines/profiles - see bug 448104 for details
-    //nsUXThemeData::Teardown();
-    //VERIFY(::UnregisterClass("nsToolkitClass", nsToolkit::mDllInstance));
-    ::UnregisterClassW(L"nsToolkitClass", nsToolkit::mDllInstance);
-#endif
-
     delete gToolkit;
     gToolkit = nsnull;
 }
 
 void
 nsToolkit::StartAllowingD3D9()
 {
   nsToolkit::GetToolkit()->mD3D9Timer->Cancel();
   nsWindow::StartAllowingD3D9(false);
 }
 
 //-------------------------------------------------------------------------
 //
-// Register the window class for the internal window and create the window
-//
-//-------------------------------------------------------------------------
-void nsToolkit::CreateInternalWindow(PRThread *aThread)
-{
-    
-    NS_PRECONDITION(aThread, "null thread");
-    mGuiThread  = aThread;
-
-    //
-    // create the internal window
-    //
-
-    mDispatchWnd = ::CreateWindowW(L"nsToolkitClass",
-                                   L"NetscapeDispatchWnd",
-                                  WS_DISABLED,
-                                  -50, -50,
-                                  10, 10,
-                                  NULL,
-                                  NULL,
-                                  nsToolkit::mDllInstance,
-                                  NULL);
-
-    VERIFY(mDispatchWnd);
-}
-
-
-//-------------------------------------------------------------------------
-//
-// Create a new thread and run the message pump in there
-//
-//-------------------------------------------------------------------------
-void nsToolkit::CreateUIThread()
-{
-    PRMonitor *monitor = ::PR_NewMonitor();
-
-    ::PR_EnterMonitor(monitor);
-
-    ThreadInitInfo *ti = new ThreadInitInfo();
-    ti->monitor = monitor;
-    ti->toolkit = this;
-
-    // create a gui thread
-    mGuiThread = ::PR_CreateThread(PR_SYSTEM_THREAD,
-                                    RunPump,
-                                    (void*)ti,
-                                    PR_PRIORITY_NORMAL,
-                                    PR_LOCAL_THREAD,
-                                    PR_UNJOINABLE_THREAD,
-                                    0);
-
-    // wait for the gui thread to start
-    while(!gThreadState) {
-        ::PR_Wait(monitor, PR_INTERVAL_NO_TIMEOUT);
-    }
-
-    // at this point the thread is running
-    ::PR_ExitMonitor(monitor);
-    ::PR_DestroyMonitor(monitor);
-}
-
-
-//-------------------------------------------------------------------------
-//
-// nsToolkit WindowProc. Used to call methods on the "main GUI thread"...
-//
-//-------------------------------------------------------------------------
-LRESULT CALLBACK nsToolkit::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, 
-                                       LPARAM lParam)
-{
-    switch (msg) {
-        case WM_SYSCOLORCHANGE:
-        {
-          // WM_SYSCOLORCHANGE messages are only dispatched to top
-          // level windows but NS_SYSCOLORCHANGE messages must be dispatched
-          // to all windows including child windows. We dispatch these messages 
-          // from the nsToolkit because if we are running embedded we may not 
-          // have a top-level nsIWidget window.
-          
-          // On WIN32 all windows are automatically invalidated after the 
-          // WM_SYSCOLORCHANGE is dispatched so the window is drawn using
-          // the current system colors.
-          nsWindow::GlobalMsgWindowProc(hWnd, msg, wParam, lParam);
-        }
-    }
-
-    return ::DefWindowProcW(hWnd, msg, wParam, lParam);
-}
-
-
-
-//-------------------------------------------------------------------------
-//
 // Return the nsToolkit for the current thread.  If a toolkit does not
 // yet exist, then one will be created...
 //
 //-------------------------------------------------------------------------
 // static
 nsToolkit* nsToolkit::GetToolkit()
 {
   if (!gToolkit) {
     gToolkit = new nsToolkit();
   }
 
   return gToolkit;
 }
 
 
-bool nsToolkit::InitVersionInfo()
-{
-  static bool isInitialized = false;
-
-  if (!isInitialized)
-  {
-    isInitialized = true;
-
-    OSVERSIONINFO osversion;
-    osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
-    ::GetVersionEx(&osversion);
-
-    if (osversion.dwMajorVersion == 5)  { 
-      nsToolkit::mIsWinXP = (osversion.dwMinorVersion == 1);
-    }
-  }
-
-  return true;
-}
-
 //-------------------------------------------------------------------------
 //
 //
 //-------------------------------------------------------------------------
 MouseTrailer::MouseTrailer() : mMouseTrailerWindow(nsnull), mCaptureWindow(nsnull),
   mIsInCaptureMode(false), mEnabled(true)
 {
 }
--- a/widget/src/windows/nsToolkit.h
+++ b/widget/src/windows/nsToolkit.h
@@ -31,96 +31,44 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 ***** */
 
-#ifndef TOOLKIT_H      
-#define TOOLKIT_H
+#ifndef nsToolkit_h__
+#define nsToolkit_h__
 
 #include "nsdefs.h"
 
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 
 #include <imm.h>
 
 // Avoid including windowsx.h to prevent macro pollution
 #ifndef GET_X_LPARAM
 #define GET_X_LPARAM(pt) (short(LOWORD(pt)))
 #endif
 #ifndef GET_Y_LPARAM
 #define GET_Y_LPARAM(pt) (short(HIWORD(pt)))
 #endif
 
-class nsIEventQueue;
-class MouseTrailer;
-
 // we used to use MAX_PATH
 // which works great for one file
 // but for multiple files, the format is
 // dirpath\0\file1\0file2\0...filen\0\0
 // and that can quickly be more than MAX_PATH (260)
 // see bug #172001 for more details
 #define FILE_BUFFER_SIZE 4096 
 
 
 /**
- * Wrapper around the thread running the message pump.
- * The toolkit abstraction is necessary because the message pump must
- * execute within the same thread that created the widget under Win32.
- */ 
-
-class nsToolkit
-{
-
-  public:
-                            nsToolkit();
-            void            CreateInternalWindow(PRThread *aThread);
-
-private:
-                            ~nsToolkit();
-            void            CreateUIThread(void);
-
-public:
-
-    static nsToolkit* GetToolkit();
-
-    // Window procedure for the internal window
-    static LRESULT CALLBACK WindowProc(HWND hWnd, 
-                                        UINT Msg, 
-                                        WPARAM WParam, 
-                                        LPARAM lParam);
-
-protected:
-    static nsToolkit* gToolkit;
-
-    // Handle of the window used to receive dispatch messages.
-    HWND        mDispatchWnd;
-    // Thread Id of the "main" Gui thread.
-    PRThread    *mGuiThread;
-    nsCOMPtr<nsITimer> mD3D9Timer;
-
-public:
-    static HINSTANCE mDllInstance;
-    // OS flag
-    static bool      mIsWinXP;
-
-    static bool InitVersionInfo();
-    static void Startup(HINSTANCE hModule);
-    static void Shutdown();
-    static void StartAllowingD3D9();
-
-    static MouseTrailer *gMouseTrailer;
-};
-
-/**
  * Makes sure exit/enter mouse messages are always dispatched.
  * In the case where the mouse has exited the outer most window the
  * only way to tell if it has exited is to set a timer and look at the
  * mouse pointer to see if it is within the outer most window.
  */ 
 
 class MouseTrailer 
 {
@@ -145,9 +93,40 @@ private:
     // Information for mouse enter/exit events
     HWND                  mMouseTrailerWindow;
     HWND                  mCaptureWindow;
     bool                  mIsInCaptureMode;
     bool                  mEnabled;
     nsCOMPtr<nsITimer>    mTimer;
 };
 
+/**
+ * Wrapper around the thread running the message pump.
+ * The toolkit abstraction is necessary because the message pump must
+ * execute within the same thread that created the widget under Win32.
+ */ 
+
+class nsToolkit
+{
+public:
+    nsToolkit();
+
+private:
+    ~nsToolkit();
+
+public:
+    static nsToolkit* GetToolkit();
+
+    static HINSTANCE mDllInstance;
+    static MouseTrailer *gMouseTrailer;
+
+    static void Startup(HMODULE hModule);
+    static void Shutdown();
+    static void StartAllowingD3D9();
+
+protected:
+    static nsToolkit* gToolkit;
+
+    nsCOMPtr<nsITimer> mD3D9Timer;
+    MouseTrailer mMouseTrailer;
+};
+
 #endif  // TOOLKIT_H
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -4665,22 +4665,27 @@ bool nsWindow::ProcessMessage(UINT msg, 
       result = true;
       break;
 
     case WM_DISPLAYCHANGE:
       DispatchStandardEvent(NS_DISPLAYCHANGED);
       break;
 
     case WM_SYSCOLORCHANGE:
-      // Note: This is sent for child windows as well as top-level windows.
-      // The Win32 toolkit normally only sends these events to top-level windows.
-      // But we cycle through all of the childwindows and send it to them as well
-      // so all presentations get notified properly.
-      // See nsWindow::GlobalMsgWindowProc.
-      DispatchStandardEvent(NS_SYSCOLORCHANGED);
+      if (mWindowType == eWindowType_invisible) {
+        ::EnumThreadWindows(GetCurrentThreadId(), nsWindow::BroadcastMsg, msg);
+      }
+      else {
+        // Note: This is sent for child windows as well as top-level windows.
+        // The Win32 toolkit normally only sends these events to top-level windows.
+        // But we cycle through all of the childwindows and send it to them as well
+        // so all presentations get notified properly.
+        // See nsWindow::GlobalMsgWindowProc.
+        DispatchStandardEvent(NS_SYSCOLORCHANGED);
+      }
       break;
 
     case WM_NOTIFY:
       // TAB change
     {
       LPNMHDR pnmh = (LPNMHDR) lParam;
 
         switch (pnmh->code) {
@@ -5603,36 +5608,16 @@ BOOL CALLBACK nsWindow::BroadcastMsgToCh
 BOOL CALLBACK nsWindow::BroadcastMsg(HWND aTopWindow, LPARAM aMsg)
 {
   // Iterate each of aTopWindows child windows sending the aMsg
   // to each of them.
   ::EnumChildWindows(aTopWindow, nsWindow::BroadcastMsgToChildren, aMsg);
   return TRUE;
 }
 
-// This method is called from nsToolkit::WindowProc to forward global
-// messages which need to be dispatched to all child windows.
-void nsWindow::GlobalMsgWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-  switch (msg) {
-    case WM_SYSCOLORCHANGE:
-      // Code to dispatch WM_SYSCOLORCHANGE message to all child windows.
-      // WM_SYSCOLORCHANGE is only sent to top-level windows, but the
-      // cross platform API requires that NS_SYSCOLORCHANGE message be sent to
-      // all child windows as well. When running in an embedded application
-      // we may not receive a WM_SYSCOLORCHANGE message because the top
-      // level window is owned by the embeddor.
-      // System color changes are posted to top-level windows only.
-      // The NS_SYSCOLORCHANGE must be dispatched to all child
-      // windows as well.
-     ::EnumThreadWindows(GetCurrentThreadId(), nsWindow::BroadcastMsg, msg);
-    break;
-  }
-}
-
 /**************************************************************
  *
  * SECTION: Event processing helpers
  *
  * Special processing for certain event types and 
  * synthesized events.
  *
  **************************************************************/
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -238,17 +238,16 @@ public:
 #ifdef ACCESSIBILITY
   nsAccessible* DispatchAccessibleEvent(PRUint32 aEventType);
   nsAccessible* GetRootAccessible();
 #endif // ACCESSIBILITY
 
   /**
    * Window utilities
    */
-  static void             GlobalMsgWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
   nsWindow*               GetTopLevelWindow(bool aStopOnDialogOrPopup);
   static HWND             GetTopLevelHWND(HWND aWnd, 
                                           bool aStopIfNotChild = false, 
                                           bool aStopIfNotPopup = true);
   HWND                    GetWindowHandle() { return mWnd; }
   WNDPROC                 GetPrevWindowProc() { return mPrevWndProc; }
   static nsWindow*        GetNSWindowPtr(HWND aWnd);
   WindowHook&             GetWindowHook() { return mWindowHook; }