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;
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;
}
//-------------------------------------------------------------------------
//
//

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

@ -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<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
@ -150,4 +98,35 @@ private:
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

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

@ -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

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

@ -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,