From 84f9002d883ca20197e04740ed1947fc7bb9927b Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Thu, 3 Nov 2011 16:39:07 -0400 Subject: [PATCH] Bug 503879, remove nsIToolkit, additinal windows only changes which simplify message handling, patch by robarnold, r=jmathies --- widget/src/windows/nsToolkit.cpp | 201 +------------------------------ widget/src/windows/nsToolkit.h | 87 +++++-------- widget/src/windows/nsWindow.cpp | 37 ++---- widget/src/windows/nsWindow.h | 1 - 4 files changed, 46 insertions(+), 280 deletions(-) diff --git a/widget/src/windows/nsToolkit.cpp b/widget/src/windows/nsToolkit.cpp index 4792f9b2e8f..e2ea6f33c91 100644 --- a/widget/src/windows/nsToolkit.cpp +++ b/widget/src/windows/nsToolkit.cpp @@ -56,8 +56,6 @@ nsToolkit* nsToolkit::gToolkit = nsnull; HINSTANCE nsToolkit::mDllInstance = 0; -bool nsToolkit::mIsWinXP = false; -static bool dummy = nsToolkit::InitVersionInfo(); static const unsigned long kD3DUsageDelay = 5000; @@ -67,41 +65,8 @@ 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 @@ -110,24 +75,12 @@ void RunPump(void* arg) 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, @@ -145,55 +98,19 @@ nsToolkit::nsToolkit() 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; } @@ -205,99 +122,6 @@ nsToolkit::StartAllowingD3D9() 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 @@ -315,27 +139,6 @@ nsToolkit* nsToolkit::GetToolkit() } -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; -} - //------------------------------------------------------------------------- // // diff --git a/widget/src/windows/nsToolkit.h b/widget/src/windows/nsToolkit.h index 9838c44fe2d..86167f44dad 100644 --- a/widget/src/windows/nsToolkit.h +++ b/widget/src/windows/nsToolkit.h @@ -36,8 +36,8 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef TOOLKIT_H -#define TOOLKIT_H +#ifndef nsToolkit_h__ +#define nsToolkit_h__ #include "nsdefs.h" @@ -54,9 +54,6 @@ #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 @@ -66,55 +63,6 @@ class MouseTrailer; #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 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 @@ -150,4 +98,35 @@ private: nsCOMPtr 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 mD3D9Timer; + MouseTrailer mMouseTrailer; +}; + #endif // TOOLKIT_H diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 0e00d23e82c..cbe1cd5d6d3 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -4670,12 +4670,17 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam, 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: @@ -5608,26 +5613,6 @@ BOOL CALLBACK nsWindow::BroadcastMsg(HWND aTopWindow, LPARAM 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 diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index 07677f5185f..9b92567d4b3 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -243,7 +243,6 @@ public: /** * 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,