Bug 503879, remove nsIToolkit, additinal windows only changes which simplify message handling, patch by robarnold, r=jmathies

This commit is contained in:
Neil Deakin 2011-11-03 16:39:07 -04:00
Родитель 03043bde04
Коммит 84f9002d88
4 изменённых файлов: 46 добавлений и 280 удалений

Просмотреть файл

@ -56,8 +56,6 @@
nsToolkit* nsToolkit::gToolkit = nsnull; nsToolkit* nsToolkit::gToolkit = nsnull;
HINSTANCE nsToolkit::mDllInstance = 0; HINSTANCE nsToolkit::mDllInstance = 0;
bool nsToolkit::mIsWinXP = false;
static bool dummy = nsToolkit::InitVersionInfo();
static const unsigned long kD3DUsageDelay = 5000; static const unsigned long kD3DUsageDelay = 5000;
@ -67,41 +65,8 @@ StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
nsWindow::StartAllowingD3D9(true); nsWindow::StartAllowingD3D9(true);
} }
//
// main for the message pump thread
//
bool gThreadState = false;
struct ThreadInitInfo {
PRMonitor *monitor;
nsToolkit *toolkit;
};
MouseTrailer* nsToolkit::gMouseTrailer; 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 // constructor
@ -110,24 +75,12 @@ void RunPump(void* arg)
nsToolkit::nsToolkit() nsToolkit::nsToolkit()
{ {
MOZ_COUNT_CTOR(nsToolkit); MOZ_COUNT_CTOR(nsToolkit);
mGuiThread = NULL;
mDispatchWnd = 0;
#if defined(MOZ_STATIC_COMPONENT_LIBS) #if defined(MOZ_STATIC_COMPONENT_LIBS)
nsToolkit::Startup(GetModuleHandle(NULL)); nsToolkit::Startup(GetModuleHandle(NULL));
#endif #endif
gMouseTrailer = new MouseTrailer(); gMouseTrailer = &mMouseTrailer;
// 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();
}
mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1"); mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1");
mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9, mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9,
@ -145,55 +98,19 @@ nsToolkit::nsToolkit()
nsToolkit::~nsToolkit() nsToolkit::~nsToolkit()
{ {
MOZ_COUNT_DTOR(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 void
nsToolkit::Startup(HMODULE hModule) nsToolkit::Startup(HMODULE hModule)
{ {
nsToolkit::mDllInstance = 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(); nsUXThemeData::Initialize();
} }
void void
nsToolkit::Shutdown() 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; delete gToolkit;
gToolkit = nsnull; gToolkit = nsnull;
} }
@ -205,99 +122,6 @@ nsToolkit::StartAllowingD3D9()
nsWindow::StartAllowingD3D9(false); 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 // 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;
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //

Просмотреть файл

@ -36,8 +36,8 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef TOOLKIT_H #ifndef nsToolkit_h__
#define TOOLKIT_H #define nsToolkit_h__
#include "nsdefs.h" #include "nsdefs.h"
@ -54,9 +54,6 @@
#define GET_Y_LPARAM(pt) (short(HIWORD(pt))) #define GET_Y_LPARAM(pt) (short(HIWORD(pt)))
#endif #endif
class nsIEventQueue;
class MouseTrailer;
// we used to use MAX_PATH // we used to use MAX_PATH
// which works great for one file // which works great for one file
// but for multiple files, the format is // but for multiple files, the format is
@ -66,55 +63,6 @@ class MouseTrailer;
#define FILE_BUFFER_SIZE 4096 #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. * Makes sure exit/enter mouse messages are always dispatched.
* In the case where the mouse has exited the outer most window the * In the case where the mouse has exited the outer most window the
@ -150,4 +98,35 @@ private:
nsCOMPtr<nsITimer> mTimer; 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 #endif // TOOLKIT_H

Просмотреть файл

@ -4670,12 +4670,17 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
break; break;
case WM_SYSCOLORCHANGE: case WM_SYSCOLORCHANGE:
if (mWindowType == eWindowType_invisible) {
::EnumThreadWindows(GetCurrentThreadId(), nsWindow::BroadcastMsg, msg);
}
else {
// Note: This is sent for child windows as well as top-level windows. // 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. // 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 // But we cycle through all of the childwindows and send it to them as well
// so all presentations get notified properly. // so all presentations get notified properly.
// See nsWindow::GlobalMsgWindowProc. // See nsWindow::GlobalMsgWindowProc.
DispatchStandardEvent(NS_SYSCOLORCHANGED); DispatchStandardEvent(NS_SYSCOLORCHANGED);
}
break; break;
case WM_NOTIFY: case WM_NOTIFY:
@ -5608,26 +5613,6 @@ BOOL CALLBACK nsWindow::BroadcastMsg(HWND aTopWindow, LPARAM aMsg)
return TRUE; 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 * SECTION: Event processing helpers

Просмотреть файл

@ -243,7 +243,6 @@ public:
/** /**
* Window utilities * Window utilities
*/ */
static void GlobalMsgWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
nsWindow* GetTopLevelWindow(bool aStopOnDialogOrPopup); nsWindow* GetTopLevelWindow(bool aStopOnDialogOrPopup);
static HWND GetTopLevelHWND(HWND aWnd, static HWND GetTopLevelHWND(HWND aWnd,
bool aStopIfNotChild = false, bool aStopIfNotChild = false,