Fix for bug 297561: onmouseover , javascript alert shows twice

r+sr=roc
This commit is contained in:
emaijala%kolumbus.fi 2005-08-13 18:00:33 +00:00
parent 3738b3c44c
commit c857619c87
3 changed files with 42 additions and 38 deletions

View File

@ -944,11 +944,12 @@ MouseTrailer::~MouseTrailer()
//-------------------------------------------------------------------------
void MouseTrailer::SetMouseTrailerWindow(nsWindow * aNSWin)
{
if (mHoldMouseWindow != aNSWin && mTimer) {
nsWindow *topWin = aNSWin ? aNSWin->GetTopLevelWindow() : nsnull;
if (mHoldMouseWindow != topWin && mTimer) {
// Make sure TimerProc is fired at least once for the old window
TimerProc(nsnull, nsnull);
}
mHoldMouseWindow = aNSWin;
mHoldMouseWindow = topWin;
CreateTimer();
}
//-------------------------------------------------------------------------
@ -987,7 +988,7 @@ void MouseTrailer::DestroyTimer()
//-------------------------------------------------------------------------
void MouseTrailer::SetCaptureWindow(nsWindow * aNSWin)
{
mCaptureWindow = aNSWin;
mCaptureWindow = aNSWin ? aNSWin->GetTopLevelWindow() : nsnull;
if (nsnull != mCaptureWindow) {
mIsInCaptureMode = PR_TRUE;
}
@ -1028,17 +1029,19 @@ void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos);
if (::WindowFromPoint(mp) != mSingleton.mHoldMouseWindow->GetWindowHandle()) {
::ScreenToClient(mSingleton.mHoldMouseWindow->GetWindowHandle(), &mp);
// Need to get the top level wnd's here. Although mHoldMouseWindow is top level,
// the actual top level window handle might be something else
HWND mouseWnd = nsWindow::GetTopLevelHWND(::WindowFromPoint(mp), PR_TRUE);
HWND holdWnd = nsWindow::GetTopLevelHWND(mSingleton.mHoldMouseWindow->GetWindowHandle(), PR_TRUE);
if (mouseWnd != holdWnd) {
//notify someone that a mouse exit happened
if (nsnull != mSingleton.mHoldMouseWindow) {
mSingleton.mHoldMouseWindow->DispatchMouseEvent(NS_MOUSE_EXIT, NULL, NULL);
}
//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;
// we are out of this window and of any window, destroy timer
mSingleton.DestroyTimer();
mSingleton.mHoldMouseWindow = nsnull;
}
}
} else {

View File

@ -690,29 +690,6 @@ static PRBool LangIDToCP(WORD aLangID, UINT& oCP)
}
}
static HWND GetTopLevelHWND(HWND aWnd, PRBool aStopOnFirstTopLevel = PR_FALSE)
{
HWND curWnd = aWnd;
HWND topWnd = NULL;
while (curWnd)
{
topWnd = curWnd;
if (aStopOnFirstTopLevel)
{
DWORD style = nsToolkit::mGetWindowLong(curWnd, GWL_STYLE);
if (!(style & WS_CHILDWINDOW)) // first top-level window
break;
}
curWnd = ::GetParent(curWnd); // Parent or owner (if has no parent)
}
return topWnd;
}
/* This object maintains a correlation between attention timers and the
windows to which they belong. It's lighter than a hashtable (expected usage
is really just one at a time) and allows nsWindow::GetNSWindowPtr
@ -826,6 +803,29 @@ private:
static nsAttentionTimerMonitor *gAttentionTimerMonitor = 0;
HWND nsWindow::GetTopLevelHWND(HWND aWnd, PRBool aStopOnFirstTopLevel)
{
HWND curWnd = aWnd;
HWND topWnd = NULL;
while (curWnd)
{
topWnd = curWnd;
if (aStopOnFirstTopLevel)
{
DWORD style = nsToolkit::mGetWindowLong(curWnd, GWL_STYLE);
if (!(style & WS_CHILDWINDOW)) // first top-level window
break;
}
curWnd = ::GetParent(curWnd); // Parent or owner (if has no parent)
}
return topWnd;
}
// 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
@ -6024,7 +6024,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
if (gCurrentWindow == NULL || gCurrentWindow != this) {
if ((nsnull != gCurrentWindow) && (!gCurrentWindow->mIsDestroying)) {
MouseTrailer::GetSingleton().IgnoreNextCycle();
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam, gCurrentWindow->GetLastPoint());
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam);
}
gCurrentWindow = this;
if (!mIsDestroying) {

View File

@ -379,6 +379,7 @@ public:
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
NS_IMETHOD GetLastInputEventTime(PRUint32& aTime);
nsWindow* GetTopLevelWindow();
#ifdef MOZ_XUL
NS_IMETHOD SetWindowTranslucency(PRBool aTransparent);
@ -388,7 +389,6 @@ private:
nsresult SetWindowTranslucencyInner(PRBool aTransparent);
PRBool GetWindowTranslucencyInner() { return mIsTranslucent; }
void UpdateTranslucentWindowAlphaInner(const nsRect& aRect, PRUint8* aAlphas);
nsWindow* GetTopLevelWindow();
void ResizeTranslucentWindow(PRInt32 aNewWidth, PRInt32 aNewHeight);
nsresult UpdateTranslucentWindow();
nsresult SetupTranslucentWindowMemoryBitmap(PRBool aTranslucent);
@ -714,6 +714,7 @@ protected:
public:
static void GlobalMsgWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static HWND GetTopLevelHWND(HWND aWnd, PRBool aStopOnFirstTopLevel = PR_FALSE);
};
//