Bug 613781 - Make NS_MOUSE_EXIT events more reliable on windows. r=robarnold, a=final.
authorJim Mathies <jmathies@mozilla.com>
Wed, 15 Dec 2010 11:01:52 -0600
changeset 59195 075f5eb9a70b21cf5fc1d2ecfeff26c7dc97588b
parent 59194 d0234003e04273dc910817cbc82f8592ca7027b5
child 59196 e952221c325176496f920ceb1004424a79237cd6
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersrobarnold, final
bugs613781
milestone2.0b9pre
Bug 613781 - Make NS_MOUSE_EXIT events more reliable on windows. r=robarnold, a=final.
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -395,16 +395,17 @@ nsWindow::nsWindow() : nsBaseWidget()
   mIsInMouseCapture     = PR_FALSE;
   mIsTopWidgetWindow    = PR_FALSE;
   mUnicodeWidget        = PR_TRUE;
   mDisplayPanFeedback   = PR_FALSE;
   mTouchWindow          = PR_FALSE;
   mCustomNonClient      = PR_FALSE;
   mHideChrome           = PR_FALSE;
   mFullscreenMode       = PR_FALSE;
+  mMousePresent         = PR_FALSE;
   mWindowType           = eWindowType_child;
   mBorderStyle          = eBorderStyle_default;
   mPopupType            = ePopupTypeAny;
   mOldSizeMode          = nsSizeMode_Normal;
   mLastPoint.x          = 0;
   mLastPoint.y          = 0;
   mLastSize.width       = 0;
   mLastSize.height      = 0;
@@ -4916,16 +4917,18 @@ PRBool nsWindow::ProcessMessage(UINT msg
 
     case WM_MOUSEMOVE:
     {
 #ifdef WINCE_WINDOWS_MOBILE
       // Reset the kill timer so that we can continue at this
       // priority
       SetTimer(mWnd, KILL_PRIORITY_ID, 2000 /* 2seconds */, NULL);
 #endif
+      mMousePresent = PR_TRUE;
+
       // Suppress dispatch of pending events
       // when mouse moves are generated by widget
       // creation instead of user input.
       LPARAM lParamScreen = lParamToScreen(lParam);
       POINT mp;
       mp.x      = GET_X_LPARAM(lParamScreen);
       mp.y      = GET_Y_LPARAM(lParamScreen);
       PRBool userMovedMouse = PR_FALSE;
@@ -4937,16 +4940,23 @@ PRBool nsWindow::ProcessMessage(UINT msg
       result = DispatchMouseEvent(NS_MOUSE_MOVE, wParam, lParam,
                                   PR_FALSE, nsMouseEvent::eLeftButton, MOUSE_INPUT_SOURCE());
       if (userMovedMouse) {
         DispatchPendingEvents();
       }
     }
     break;
 
+    case WM_NCMOUSEMOVE:
+      // If we receive a mouse move event on non-client chrome, make sure and
+      // send an NS_MOUSE_EXIT event as well.
+      if (mMousePresent && !mIsInMouseCapture)
+        SendMessage(mWnd, WM_MOUSELEAVE, 0, 0);
+    break;
+
 #ifdef WINCE_WINDOWS_MOBILE
     case WM_TIMER:
       SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
       KillTimer(mWnd, KILL_PRIORITY_ID);
       break;
 #endif
 
     case WM_LBUTTONDOWN:
@@ -4972,16 +4982,20 @@ PRBool nsWindow::ProcessMessage(UINT msg
       KillTimer(mWnd, KILL_PRIORITY_ID);
 #endif
     }
     break;
 
 #ifndef WINCE
     case WM_MOUSELEAVE:
     {
+      if (!mMousePresent)
+        break;
+      mMousePresent = PR_FALSE;
+
       // We need to check mouse button states and put them in for
       // wParam.
       WPARAM mouseState = (GetKeyState(VK_LBUTTON) ? MK_LBUTTON : 0)
         | (GetKeyState(VK_MBUTTON) ? MK_MBUTTON : 0)
         | (GetKeyState(VK_RBUTTON) ? MK_RBUTTON : 0);
       // Synthesize an event position because we don't get one from
       // WM_MOUSELEAVE.
       LPARAM pos = lParamToClient(::GetMessagePos());
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -495,16 +495,17 @@ protected:
   PRPackedBool          mUnicodeWidget;
   PRPackedBool          mPainting;
   PRPackedBool          mExitToNonClientArea;
   PRPackedBool          mTouchWindow;
   PRPackedBool          mDisplayPanFeedback;
   PRPackedBool          mHideChrome;
   PRPackedBool          mIsRTL;
   PRPackedBool          mFullscreenMode;
+  PRPackedBool          mMousePresent;
   PRUint32              mBlurSuppressLevel;
   DWORD_PTR             mOldStyle;
   DWORD_PTR             mOldExStyle;
   HIMC                  mOldIMC;
   IMEContext            mIMEContext;
   nsNativeDragTarget*   mNativeDragTarget;
   HKL                   mLastKeyboardLayout;
   nsPopupType           mPopupType;