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;
#ifndef WINCE
nsWindow *MouseTrailer::mCaptureWindow = NULL;
nsWindow *MouseTrailer::mHoldMouse = NULL;
MouseTrailer *MouseTrailer::theMouseTrailer = NULL;
PRBool MouseTrailer::gIgnoreNextCycle(PR_FALSE);
PRBool MouseTrailer::mIsInCaptureMode(PR_FALSE);
MouseTrailer MouseTrailer::mSingleton;
#endif
#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) {
if (nsnull == MouseTrailer::theMouseTrailer) {
MouseTrailer::theMouseTrailer = new MouseTrailer();
}
return MouseTrailer::theMouseTrailer;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
nsWindow * MouseTrailer::GetMouseTrailerWindow() {
return MouseTrailer::mHoldMouse;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::SetMouseTrailerWindow(nsWindow * aNSWin) {
MouseTrailer::mHoldMouse = aNSWin;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
MouseTrailer::MouseTrailer()
MouseTrailer::MouseTrailer() : mHoldMouseWindow(nsnull), mCaptureWindow(nsnull),
mIsInCaptureMode(PR_FALSE), mIgnoreNextCycle(PR_FALSE)
{
mHoldMouse = NULL;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
MouseTrailer::~MouseTrailer()
{
DestroyTimer();
if (mHoldMouse) {
NS_RELEASE(mHoldMouse);
}
DestroyTimer();
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
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);
NS_ENSURE_SUCCESS(rv, rv);
return mTimer->InitWithFuncCallback(MouseTrailer::TimerProc, nsnull, 200,
return mTimer->InitWithFuncCallback(TimerProc, nsnull, 200,
nsITimer::TYPE_REPEATING_SLACK);
}
@ -1020,8 +996,6 @@ void MouseTrailer::SetCaptureWindow(nsWindow * aNSWin)
mIsInCaptureMode = PR_TRUE;
}
}
#define TIMER_DEBUG 1
//-------------------------------------------------------------------------
//
//
@ -1033,48 +1007,48 @@ void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
// Capture could end outside our window
// Also, for some reason when the mouse is on the frame it thinks that
// it is inside the window that is being captured.
if (nsnull != MouseTrailer::mCaptureWindow) {
if (MouseTrailer::mCaptureWindow != MouseTrailer::mHoldMouse) {
if (nsnull != mSingleton.mCaptureWindow) {
if (mSingleton.mCaptureWindow != mSingleton.mHoldMouseWindow) {
return;
}
} else {
if (mIsInCaptureMode) {
// the mHoldMouse could be bad from rolling over the frame, so clear
if (mSingleton.mIsInCaptureMode) {
// 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
// since we canceled the capture
MouseTrailer::mHoldMouse = nsnull;
mIsInCaptureMode = PR_FALSE;
mSingleton.mHoldMouseWindow = nsnull;
mSingleton.mIsInCaptureMode = PR_FALSE;
return;
}
}
if (MouseTrailer::mHoldMouse && ::IsWindow(MouseTrailer::mHoldMouse->GetWindowHandle())) {
if (gIgnoreNextCycle) {
gIgnoreNextCycle = 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;
if (mSingleton.mHoldMouseWindow && ::IsWindow(mSingleton.mHoldMouseWindow->GetWindowHandle())) {
if (mSingleton.mIgnoreNextCycle) {
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) != 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

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

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

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

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