From 32bf150d0fbcd239f79bf60200fdacb3e85c2612 Mon Sep 17 00:00:00 2001 From: "emaijala%kolumbus.fi" Date: Sat, 13 Aug 2005 18:00:33 +0000 Subject: [PATCH] Fix for bug 297561: onmouseover , javascript alert shows twice r+sr=roc git-svn-id: svn://10.0.0.236/trunk@177709 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/widget/src/windows/nsToolkit.cpp | 29 +++++++------- mozilla/widget/src/windows/nsWindow.cpp | 48 ++++++++++++------------ mozilla/widget/src/windows/nsWindow.h | 3 +- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/mozilla/widget/src/windows/nsToolkit.cpp b/mozilla/widget/src/windows/nsToolkit.cpp index 96866403e2f..89708ee1f7d 100644 --- a/mozilla/widget/src/windows/nsToolkit.cpp +++ b/mozilla/widget/src/windows/nsToolkit.cpp @@ -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 { diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index 58f8e04b5ee..bf22b6e6692 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -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) { diff --git a/mozilla/widget/src/windows/nsWindow.h b/mozilla/widget/src/windows/nsWindow.h index b644fddbef8..48e706d73c1 100644 --- a/mozilla/widget/src/windows/nsWindow.h +++ b/mozilla/widget/src/windows/nsWindow.h @@ -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); }; //