Bug 1549972 - Use ClientMarginHitTestPoint when checking if the mouse is within a draggable region. r=jmathies
authorMike Conley <mconley@mozilla.com>
Thu, 09 May 2019 15:00:34 +0000
changeset 532280 8f236d0ba0fac44d77a3098b85adf085feef9e3a
parent 532279 d41f800069310e11f51add4796f3443100e3cb50
child 532281 46287ed82b8f3bd422103f4f2a9ec7b8af9205b0
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs1549972
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1549972 - Use ClientMarginHitTestPoint when checking if the mouse is within a draggable region. r=jmathies ClientMarginHitTestPoint takes into account the fact that we want a minimum of kResizableBorderMinSize pixels thickness around the window to trigger resizing. Differential Revision: https://phabricator.services.mozilla.com/D30427
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -610,17 +610,17 @@ nsWindow::nsWindow(bool aIsChildWindow)
   mOldExStyle = 0;
   mPainting = 0;
   mLastKeyboardLayout = 0;
   mBlurSuppressLevel = 0;
   mLastPaintEndTime = TimeStamp::Now();
   mCachedHitTestPoint.x = 0;
   mCachedHitTestPoint.y = 0;
   mCachedHitTestTime = TimeStamp::Now();
-  mCachedHitTestResult = false;
+  mCachedHitTestResult = 0;
 #ifdef MOZ_XUL
   mTransparencyMode = eTransparencyOpaque;
   memset(&mGlassMargins, 0, sizeof mGlassMargins);
 #endif
   DWORD background = ::GetSysColor(COLOR_BTNFACE);
   mBrush = ::CreateSolidBrush(NSRGB_2_COLOREF(background));
   mSendingSetText = false;
   mDefaultScale = -1.0;  // not yet set, will be calculated on first use
@@ -5307,33 +5307,34 @@ bool nsWindow::ProcessMessage(UINT msg, 
     case WM_ERASEBKGND:
       if (!AutoErase((HDC)wParam)) {
         *aRetValue = 1;
         result = true;
       }
       break;
 
     case WM_MOUSEMOVE: {
-      mMouseInDraggableArea =
-          WithinDraggableRegion(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+      LPARAM lParamScreen = lParamToScreen(lParam);
+      mMouseInDraggableArea = WithinDraggableRegion(GET_X_LPARAM(lParamScreen),
+                                                    GET_Y_LPARAM(lParamScreen));
+
       if (!mMousePresent && !sIsInMouseCapture) {
         // First MOUSEMOVE over the client area. Ask for MOUSELEAVE
         TRACKMOUSEEVENT mTrack;
         mTrack.cbSize = sizeof(TRACKMOUSEEVENT);
         mTrack.dwFlags = TME_LEAVE;
         mTrack.dwHoverTime = 0;
         mTrack.hwndTrack = mWnd;
         TrackMouseEvent(&mTrack);
       }
       mMousePresent = 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);
       bool userMovedMouse = false;
       if ((sLastMouseMovePoint.x != mp.x) || (sLastMouseMovePoint.y != mp.y)) {
         userMovedMouse = true;
       }
 
@@ -5343,18 +5344,17 @@ bool nsWindow::ProcessMessage(UINT msg, 
                              mPointerEvents.GetCachedPointerInfo(msg, wParam));
       if (userMovedMouse) {
         DispatchPendingEvents();
       }
     } break;
 
     case WM_NCMOUSEMOVE: {
       LPARAM lParamClient = lParamToClient(lParam);
-      if (WithinDraggableRegion(GET_X_LPARAM(lParamClient),
-                                GET_Y_LPARAM(lParamClient))) {
+      if (WithinDraggableRegion(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
         // If we noticed the mouse moving in our draggable region, forward the
         // message as a normal WM_MOUSEMOVE.
         SendMessage(mWnd, WM_MOUSEMOVE, 0, lParamClient);
       } else if (mMousePresent && !sIsInMouseCapture) {
         // If we receive a mouse move event on non-client chrome, make sure and
         // send an eMouseExitFromWidget event as well.
         SendMessage(mWnd, WM_MOUSELEAVE, 0, 0);
       }
@@ -6158,37 +6158,39 @@ int32_t nsWindow::ClientMarginHitTestPoi
       testResult = HTCAPTION;
     else if (bottom || left || right)
       testResult = HTBORDER;
   }
 
   if (!sIsInMouseCapture && allowContentOverride) {
     POINT pt = {mx, my};
     ::ScreenToClient(mWnd, &pt);
-    if (WithinDraggableRegion(pt.x, pt.y)) {
+
+    if (pt.x == mCachedHitTestPoint.x && pt.y == mCachedHitTestPoint.y &&
+        TimeStamp::Now() - mCachedHitTestTime <
+            TimeDuration::FromMilliseconds(HITTEST_CACHE_LIFETIME_MS)) {
+      return mCachedHitTestResult;
+    }
+
+    mCachedHitTestPoint = {pt.x, pt.y};
+    mCachedHitTestTime = TimeStamp::Now();
+
+    if (mDraggableRegion.Contains(pt.x, pt.y)) {
       testResult = HTCAPTION;
     } else {
       testResult = HTCLIENT;
     }
+    mCachedHitTestResult = testResult;
   }
 
   return testResult;
 }
 
-bool nsWindow::WithinDraggableRegion(int32_t clientX, int32_t clientY) {
-  if (clientX == mCachedHitTestPoint.x && clientY == mCachedHitTestPoint.y &&
-      TimeStamp::Now() - mCachedHitTestTime <
-          TimeDuration::FromMilliseconds(HITTEST_CACHE_LIFETIME_MS)) {
-    return mCachedHitTestResult;
-  }
-  mCachedHitTestPoint = {clientX, clientY};
-  mCachedHitTestTime = TimeStamp::Now();
-
-  mCachedHitTestResult = mDraggableRegion.Contains(clientX, clientY);
-  return mCachedHitTestResult;
+bool nsWindow::WithinDraggableRegion(int32_t screenX, int32_t screenY) {
+  return ClientMarginHitTestPoint(screenX, screenY) == HTCAPTION;
 }
 
 TimeStamp nsWindow::GetMessageTimeStamp(LONG aEventTime) const {
   CurrentWindowsTimeGetter getCurrentTime(mWnd);
   return TimeConverter().GetTimeStampFromSystemTime(aEventTime, getCurrentTime);
 }
 
 void nsWindow::PostSleepWakeNotification(const bool aIsSleepMode) {
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -659,17 +659,17 @@ class nsWindow final : public nsWindowBa
   bool mMouseTransparent;
 
   // Whether we're in the process of sending a WM_SETTEXT ourselves
   bool mSendingSetText;
 
   // Whether we we're created as a child window (aka ChildWindow) or not.
   bool mIsChildWindow : 1;
 
-  bool mCachedHitTestResult;
+  int32_t mCachedHitTestResult;
 
   // The point in time at which the last paint completed. We use this to avoid
   //  painting too rapidly in response to frequent input events.
   TimeStamp mLastPaintEndTime;
 
   // The location of the window buttons in the window.
   mozilla::Maybe<LayoutDeviceIntRect> mWindowButtonsRect;