Bug 1341691 - Improve handling of touch events when dismissing popups. r=jimm
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 24 Feb 2017 08:32:00 -0500
changeset 374197 174aaab139dc326fed3f584a3d427508c7801c40
parent 374196 3026fb03c97d8c1223770a46f4bc86a731ac3edc
child 374198 86de81c342fd5844644f354f3b7768092698a701
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1341691
milestone54.0a1
Bug 1341691 - Improve handling of touch events when dismissing popups. r=jimm When user input is used to dismiss popups, the user input may sometimes be consumed (for example, clicking on a combobox element will dismiss the combobox popup, but consume the event to avoid reopening the popup right away). This handling was present for some types of input events but missing for touch events. This patch adds it for touch events as well. MozReview-Commit-ID: 5wsuTdMbkX2
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6667,16 +6667,35 @@ void nsWindow::UserActivity()
   }
 
   // Check that we now have the idle service.
   if (mIdleService) {
     mIdleService->ResetIdleTimeOut(0);
   }
 }
 
+nsIntPoint nsWindow::GetTouchCoordinates(WPARAM wParam, LPARAM lParam)
+{
+  nsIntPoint ret;
+  uint32_t cInputs = LOWORD(wParam);
+  if (cInputs != 1) {
+    // Just return 0,0 if there isn't exactly one touch point active
+    return ret;
+  }
+  PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
+  if (mGesture.GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs)) {
+    ret.x = TOUCH_COORD_TO_PIXEL(pInputs[0].x);
+    ret.y = TOUCH_COORD_TO_PIXEL(pInputs[0].y);
+  }
+  delete[] pInputs;
+  // Note that we don't call CloseTouchInputHandle here because we need
+  // to read the touch input info again in OnTouch later.
+  return ret;
+}
+
 bool nsWindow::OnTouch(WPARAM wParam, LPARAM lParam)
 {
   uint32_t cInputs = LOWORD(wParam);
   PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
 
   if (mGesture.GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs)) {
     MultiTouchInput touchInput, touchEndInput;
 
@@ -7886,22 +7905,29 @@ nsWindow::DealWithPopups(HWND aWnd, UINT
 
     default:
       return false;
   }
 
   // Only need to deal with the last rollup for left mouse down events.
   NS_ASSERTION(!mLastRollup, "mLastRollup is null");
 
-  if (nativeMessage == WM_LBUTTONDOWN || nativeMessage == WM_POINTERDOWN) {
-    POINT pt;
-    pt.x = GET_X_LPARAM(aLParam);
-    pt.y = GET_Y_LPARAM(aLParam);
-    ::ClientToScreen(aWnd, &pt);
-    nsIntPoint pos(pt.x, pt.y);
+  if (nativeMessage == WM_TOUCH || nativeMessage == WM_LBUTTONDOWN || nativeMessage == WM_POINTERDOWN) {
+    nsIntPoint pos;
+    if (nativeMessage == WM_TOUCH) {
+      if (nsWindow* win = WinUtils::GetNSWindowPtr(aWnd)) {
+        pos = win->GetTouchCoordinates(aWParam, aLParam);
+      }
+    } else {
+      POINT pt;
+      pt.x = GET_X_LPARAM(aLParam);
+      pt.y = GET_Y_LPARAM(aLParam);
+      ::ClientToScreen(aWnd, &pt);
+      pos = nsIntPoint(pt.x, pt.y);
+    }
 
     consumeRollupEvent =
       rollupListener->Rollup(popupsToRollup, true, &pos, &mLastRollup);
     NS_IF_ADDREF(mLastRollup);
   } else {
     consumeRollupEvent =
       rollupListener->Rollup(popupsToRollup, true, nullptr, nullptr);
   }
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -409,16 +409,17 @@ protected:
   static bool             EventIsInsideWindow(nsWindow* aWindow);
   // Convert nsEventStatus value to a windows boolean
   static bool             ConvertStatus(nsEventStatus aStatus);
   static void             PostSleepWakeNotification(const bool aIsSleepMode);
   int32_t                 ClientMarginHitTestPoint(int32_t mx, int32_t my);
   TimeStamp               GetMessageTimeStamp(LONG aEventTime) const;
   static void             UpdateFirstEventTime(DWORD aEventTime);
   void                    FinishLiveResizing(ResizeState aNewState);
+  nsIntPoint              GetTouchCoordinates(WPARAM wParam, LPARAM lParam);
 
   /**
    * Event handlers
    */
   virtual void            OnDestroy() override;
   virtual bool            OnResize(nsIntRect &aWindowRect);
   bool                    OnGesture(WPARAM wParam, LPARAM lParam);
   bool                    OnTouch(WPARAM wParam, LPARAM lParam);