зеркало из https://github.com/mozilla/pjs.git
Fix for bug 285000: MouseTrailer tweaks and fixes.
r+sr=bzbarsky
This commit is contained in:
Родитель
a5c92e5099
Коммит
1a031c80c9
|
@ -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());
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче