Bug 1341691 - Improve handling of touch events when dismissing popups. r?jimm draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 24 Feb 2017 08:32:00 -0500
changeset 489227 22735b556d9955ac7c36c60d9406abd541a321e2
parent 489193 be661bae6cb9a53935c5b87744bf68879d9ebcc5
child 546949 82f1bd829d9d29da6dce05943b76887c36c7516b
push id46767
push userkgupta@mozilla.com
push dateFri, 24 Feb 2017 13:32:53 +0000
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
@@ -6666,16 +6666,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;
 
@@ -7885,22 +7904,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);