mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 503879, remove nsIToolkit, additinal windows only changes which simplify message handling, patch by robarnold, r=jmathies
This commit is contained in:
parent
3d8eda9d77
commit
5fe264ae0b
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user