Fix for bug 285000: MouseTrailer tweaks and fixes.

r+sr=bzbarsky
This commit is contained in:
emaijala%kolumbus.fi 2005-03-11 18:46:56 +00:00
Родитель a5c92e5099
Коммит 1a031c80c9
3 изменённых файлов: 81 добавлений и 120 удалений

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

@ -93,11 +93,7 @@ IActiveIMMApp* nsToolkit::gAIMMApp = NULL;
PRInt32 nsToolkit::gAIMMCount = 0; PRInt32 nsToolkit::gAIMMCount = 0;
#ifndef WINCE #ifndef WINCE
nsWindow *MouseTrailer::mCaptureWindow = NULL; MouseTrailer MouseTrailer::mSingleton;
nsWindow *MouseTrailer::mHoldMouse = NULL;
MouseTrailer *MouseTrailer::theMouseTrailer = NULL;
PRBool MouseTrailer::gIgnoreNextCycle(PR_FALSE);
PRBool MouseTrailer::mIsInCaptureMode(PR_FALSE);
#endif #endif
#if !defined(MOZ_STATIC_COMPONENT_LIBS) && !defined(MOZ_ENABLE_LIBXUL) #if !defined(MOZ_STATIC_COMPONENT_LIBS) && !defined(MOZ_ENABLE_LIBXUL)
@ -934,51 +930,31 @@ NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
// //
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
MouseTrailer * MouseTrailer::GetMouseTrailer(DWORD aThreadID) { MouseTrailer::MouseTrailer() : mHoldMouseWindow(nsnull), mCaptureWindow(nsnull),
if (nsnull == MouseTrailer::theMouseTrailer) { mIsInCaptureMode(PR_FALSE), mIgnoreNextCycle(PR_FALSE)
MouseTrailer::theMouseTrailer = new MouseTrailer();
}
return MouseTrailer::theMouseTrailer;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
nsWindow * MouseTrailer::GetMouseTrailerWindow() {
return MouseTrailer::mHoldMouse;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::SetMouseTrailerWindow(nsWindow * aNSWin) {
MouseTrailer::mHoldMouse = aNSWin;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
MouseTrailer::MouseTrailer()
{ {
mHoldMouse = NULL;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
MouseTrailer::~MouseTrailer() MouseTrailer::~MouseTrailer()
{ {
DestroyTimer(); DestroyTimer();
if (mHoldMouse) { }
NS_RELEASE(mHoldMouse); //-------------------------------------------------------------------------
} //
//
//-------------------------------------------------------------------------
void MouseTrailer::SetMouseTrailerWindow(nsWindow * aNSWin)
{
if (mHoldMouseWindow != aNSWin && mTimer) {
// Make sure TimerProc is fired at least once for the old window
TimerProc(nsnull, nsnull);
}
mHoldMouseWindow = aNSWin;
CreateTimer();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
@ -993,7 +969,7 @@ nsresult MouseTrailer::CreateTimer()
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return mTimer->InitWithFuncCallback(MouseTrailer::TimerProc, nsnull, 200, return mTimer->InitWithFuncCallback(TimerProc, nsnull, 200,
nsITimer::TYPE_REPEATING_SLACK); nsITimer::TYPE_REPEATING_SLACK);
} }
@ -1020,8 +996,6 @@ void MouseTrailer::SetCaptureWindow(nsWindow * aNSWin)
mIsInCaptureMode = PR_TRUE; mIsInCaptureMode = PR_TRUE;
} }
} }
#define TIMER_DEBUG 1
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
@ -1033,48 +1007,48 @@ void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
// Capture could end outside our window // Capture could end outside our window
// Also, for some reason when the mouse is on the frame it thinks that // Also, for some reason when the mouse is on the frame it thinks that
// it is inside the window that is being captured. // it is inside the window that is being captured.
if (nsnull != MouseTrailer::mCaptureWindow) { if (nsnull != mSingleton.mCaptureWindow) {
if (MouseTrailer::mCaptureWindow != MouseTrailer::mHoldMouse) { if (mSingleton.mCaptureWindow != mSingleton.mHoldMouseWindow) {
return; return;
} }
} else { } else {
if (mIsInCaptureMode) { if (mSingleton.mIsInCaptureMode) {
// the mHoldMouse could be bad from rolling over the frame, so clear // The mHoldMouse could be bad from rolling over the frame, so clear
// it if we were capturing and now this is the first timer call back // it if we were capturing and now this is the first timer call back
// since we canceled the capture // since we canceled the capture
MouseTrailer::mHoldMouse = nsnull; mSingleton.mHoldMouseWindow = nsnull;
mIsInCaptureMode = PR_FALSE; mSingleton.mIsInCaptureMode = PR_FALSE;
return; return;
} }
} }
if (MouseTrailer::mHoldMouse && ::IsWindow(MouseTrailer::mHoldMouse->GetWindowHandle())) { if (mSingleton.mHoldMouseWindow && ::IsWindow(mSingleton.mHoldMouseWindow->GetWindowHandle())) {
if (gIgnoreNextCycle) { if (mSingleton.mIgnoreNextCycle) {
gIgnoreNextCycle = PR_FALSE; mSingleton.mIgnoreNextCycle = PR_FALSE;
}
else {
POINT mp;
DWORD pos = ::GetMessagePos();
mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos);
if (::WindowFromPoint(mp) != mHoldMouse->GetWindowHandle()) {
::ScreenToClient(mHoldMouse->GetWindowHandle(), &mp);
//notify someone that a mouse exit happened
if (nsnull != MouseTrailer::mHoldMouse) {
MouseTrailer::mHoldMouse->DispatchMouseEvent(NS_MOUSE_EXIT);
}
// we are out of this window and of any window, destroy timer
MouseTrailer::theMouseTrailer->DestroyTimer();
MouseTrailer::mHoldMouse = NULL;
}
}
} else {
MouseTrailer::theMouseTrailer->DestroyTimer();
MouseTrailer::mHoldMouse = NULL;
} }
else {
POINT mp;
DWORD pos = ::GetMessagePos();
mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos);
if (::WindowFromPoint(mp) != mSingleton.mHoldMouseWindow->GetWindowHandle()) {
::ScreenToClient(mSingleton.mHoldMouseWindow->GetWindowHandle(), &mp);
//notify someone that a mouse exit happened
if (nsnull != mSingleton.mHoldMouseWindow) {
mSingleton.mHoldMouseWindow->DispatchMouseEvent(NS_MOUSE_EXIT);
}
// we are out of this window and of any window, destroy timer
mSingleton.DestroyTimer();
mSingleton.mHoldMouseWindow = nsnull;
}
}
} else {
mSingleton.DestroyTimer();
mSingleton.mHoldMouseWindow = nsnull;
}
} }
#endif #endif

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

@ -156,44 +156,38 @@ class nsWindow;
*/ */
#ifndef WINCE #ifndef WINCE
class MouseTrailer { class MouseTrailer
{
public: public:
static MouseTrailer * GetMouseTrailer(DWORD aThreadID); static MouseTrailer &GetSingleton() { return mSingleton; }
static nsWindow * GetMouseTrailerWindow();
static nsWindow * GetCaptureWindow() { return mCaptureWindow; } nsWindow *GetMouseTrailerWindow() { return mHoldMouseWindow; }
nsWindow *GetCaptureWindow() { return mCaptureWindow; }
static void SetMouseTrailerWindow(nsWindow * aNSWin); void SetMouseTrailerWindow(nsWindow * aNSWin);
static void SetCaptureWindow(nsWindow * aNSWin); void SetCaptureWindow(nsWindow * aNSWin);
static void IgnoreNextCycle() { gIgnoreNextCycle = PR_TRUE; } void IgnoreNextCycle() { mIgnoreNextCycle = PR_TRUE; }
void DestroyTimer();
static void TimerProc(nsITimer* aTimer, void* aClosure);
private: private:
/// Global nsToolkit Instance MouseTrailer();
static MouseTrailer* theMouseTrailer; ~MouseTrailer();
public: nsresult CreateTimer();
~MouseTrailer();
nsresult CreateTimer(); static void TimerProc(nsITimer* aTimer, void* aClosure);
void DestroyTimer();
private: // Global nsToolkit Instance
MouseTrailer(); static MouseTrailer mSingleton;
private: // information for mouse enter/exit events
/* global information for mouse enter/exit events // last window
*/ nsWindow *mHoldMouseWindow;
//@{ nsWindow *mCaptureWindow;
/// last window PRBool mIsInCaptureMode;
static nsWindow* mHoldMouse; PRBool mIgnoreNextCycle;
static nsWindow* mCaptureWindow; // timer
static PRBool mIsInCaptureMode; nsCOMPtr<nsITimer> mTimer;
/// timer
nsCOMPtr<nsITimer> mTimer;
static PRBool gIgnoreNextCycle;
//@}
}; };
#endif // WINCE #endif // WINCE

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

@ -901,9 +901,8 @@ nsWindow::~nsWindow()
} }
#ifndef WINCE #ifndef WINCE
MouseTrailer * mouseTrailer = MouseTrailer::GetMouseTrailer(0); if (MouseTrailer::GetSingleton().GetMouseTrailerWindow() == this) {
if (mouseTrailer->GetMouseTrailerWindow() == this) { MouseTrailer::GetSingleton().DestroyTimer();
mouseTrailer->DestroyTimer();
} }
#endif #endif
@ -939,12 +938,12 @@ NS_METHOD nsWindow::CaptureMouse(PRBool aCapture)
{ {
if (aCapture) { if (aCapture) {
#ifndef WINCE #ifndef WINCE
MouseTrailer::SetCaptureWindow(this); MouseTrailer::GetSingleton().SetCaptureWindow(this);
#endif #endif
::SetCapture(mWnd); ::SetCapture(mWnd);
} else { } else {
#ifndef WINCE #ifndef WINCE
MouseTrailer::SetCaptureWindow(NULL); MouseTrailer::GetSingleton().SetCaptureWindow(NULL);
#endif #endif
::ReleaseCapture(); ::ReleaseCapture();
} }
@ -5501,10 +5500,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
// set that window into the mouse trailer timer. // set that window into the mouse trailer timer.
if (!mIsInMouseCapture) { if (!mIsInMouseCapture) {
#ifndef WINCE #ifndef WINCE
MouseTrailer * mouseTrailer = MouseTrailer::GetMouseTrailer(0); MouseTrailer::GetSingleton().SetMouseTrailerWindow(this);
mouseTrailer->TimerProc(nsnull, nsnull);
MouseTrailer::SetMouseTrailerWindow(this);
mouseTrailer->CreateTimer();
#endif #endif
} else { } else {
POINT mp; POINT mp;
@ -5535,10 +5531,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
// only set the window into the mouse trailer if we have a good window // only set the window into the mouse trailer if we have a good window
if (nsnull != someWindow) { if (nsnull != someWindow) {
#ifndef WINCE #ifndef WINCE
MouseTrailer * mouseTrailer = MouseTrailer::GetMouseTrailer(0); MouseTrailer::GetSingleton().SetMouseTrailerWindow(someWindow);
mouseTrailer->TimerProc(nsnull, nsnull);
MouseTrailer::SetMouseTrailerWindow(someWindow);
mouseTrailer->CreateTimer();
#endif #endif
} }
} }
@ -5552,7 +5545,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
if (gCurrentWindow == NULL || gCurrentWindow != this) { if (gCurrentWindow == NULL || gCurrentWindow != this) {
if ((nsnull != gCurrentWindow) && (!gCurrentWindow->mIsDestroying)) { if ((nsnull != gCurrentWindow) && (!gCurrentWindow->mIsDestroying)) {
#ifndef WINCE #ifndef WINCE
MouseTrailer::IgnoreNextCycle(); MouseTrailer::GetSingleton().IgnoreNextCycle();
#endif #endif
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam, gCurrentWindow->GetLastPoint()); gCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam, gCurrentWindow->GetLastPoint());
} }