Bug 1493128 - Consider a single mouse type device queried by SetupDiEnumDeviceInterfaces on tablet or on system with a digitizer as COARSE type pointer device. r=masayuki
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Thu, 04 Oct 2018 07:23:57 +0000
changeset 495260 bf098432003adaa3862f8271de486ee3bdbd8362
parent 495259 b37a0f29a956f16fd757ad0884b9f907f3d15f3c
child 495261 3e260539c399797e74ab7bebdad9cf62207a5e23
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1493128, 1495938
milestone64.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 1493128 - Consider a single mouse type device queried by SetupDiEnumDeviceInterfaces on tablet or on system with a digitizer as COARSE type pointer device. r=masayuki Unfortunately there is no realiable way to tell whether there is no mouse connected or not. So we are going to take a heuristic way here. The way is that; 1) Count mouse type devices with SetupDiEnumDeviceInterfaces [1] 2) If the count is 1 and if the system is used as tablet or has a touch device, the device should be COARSE This way causes a misrecognition as if there is a mouse device in the case where the touchscreen is disabled on the tablet even if there is no mouse connected (i.e. the case where CountMouseDevices() returns 1 and the system is on table mode). We will try to fix the misrecognition in a later bug (bug 1495938). [1] https://docs.microsoft.com/en-us/windows/desktop/api/setupapi/nf-setupapi-setupdienumdeviceinterfaces Differential Revision: https://phabricator.services.mozilla.com/D7565
widget/windows/InputDeviceUtils.cpp
widget/windows/InputDeviceUtils.h
widget/windows/WinUtils.cpp
--- a/widget/windows/InputDeviceUtils.cpp
+++ b/widget/windows/InputDeviceUtils.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InputDeviceUtils.h"
 
 #define INITGUID
 #include <dbt.h>
 #include <hidclass.h>
 #include <ntddmou.h>
+#include <setupapi.h>
 
 namespace mozilla {
 namespace widget {
 
 HDEVNOTIFY
 InputDeviceUtils::RegisterNotification(HWND aHwnd)
 {
   DEV_BROADCAST_DEVICEINTERFACE filter = {};
@@ -32,10 +33,37 @@ void
 InputDeviceUtils::UnregisterNotification(HDEVNOTIFY aHandle)
 {
   if (!aHandle) {
     return;
   }
   UnregisterDeviceNotification(aHandle);
 }
 
+DWORD
+InputDeviceUtils::CountMouseDevices()
+{
+  HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_MOUSE,
+                                      nullptr,
+                                      nullptr,
+                                      DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
+  if (hdev == INVALID_HANDLE_VALUE) {
+    return 0;
+  }
+
+  DWORD count = 0;
+  SP_INTERFACE_DEVICE_DATA info = {};
+  info.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
+  while (SetupDiEnumDeviceInterfaces(hdev,
+                                     nullptr,
+                                     &GUID_DEVINTERFACE_MOUSE,
+                                     count,
+                                     &info)) {
+    if (info.Flags & SPINT_ACTIVE) {
+      count++;
+    }
+  }
+  SetupDiDestroyDeviceInfoList(hdev);
+  return count;
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/windows/InputDeviceUtils.h
+++ b/widget/windows/InputDeviceUtils.h
@@ -11,13 +11,16 @@
 
 namespace mozilla {
 namespace widget {
 
 class InputDeviceUtils {
 public:
   static HDEVNOTIFY RegisterNotification(HWND aHwnd);
   static void UnregisterNotification(HDEVNOTIFY aHandle);
+
+  // Returns the number of mouse type devices connected to this system.
+  static DWORD CountMouseDevices();
 };
 
 } // namespace widget
 } // namespace mozilla
 #endif // mozilla_widget_InputDeviceUtils_h__
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -8,16 +8,17 @@
 
 #include <knownfolders.h>
 #include <winioctl.h>
 
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "nsWindow.h"
 #include "nsWindowDefs.h"
+#include "InputDeviceUtils.h"
 #include "KeyboardLayout.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/BackgroundHangMonitor.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/RefPtr.h"
@@ -1895,29 +1896,48 @@ IsTabletDevice()
     return !GetSystemMetrics(SM_CONVERTIBLESLATEMODE);
   }
   return false;
 }
 
 static bool
 IsMousePresent()
 {
-  return ::GetSystemMetrics(SM_MOUSEPRESENT);
+  if (!::GetSystemMetrics(SM_MOUSEPRESENT)) {
+    return false;
+  }
+
+  DWORD count = InputDeviceUtils::CountMouseDevices();
+  if (!count) {
+    return false;
+  }
+
+  // If there is a mouse device and if this machine is a tablet or has a
+  // digitizer, that's counted as the mouse device.
+  // FIXME: Bug 1495938:  We should drop this heuristic way once we find out a
+  // reliable way to tell there is no mouse or not.
+  if (count == 1 &&
+      (WinUtils::IsTouchDeviceSupportPresent() ||
+       IsTabletDevice())) {
+    return false;
+  }
+
+  return true;
 }
 
 /* static */
 PointerCapabilities
 WinUtils::GetPrimaryPointerCapabilities()
 {
   if (IsTabletDevice()) {
     return PointerCapabilities::Coarse;
   }
 
   if (IsMousePresent()) {
-    return PointerCapabilities::Fine|
+    return PointerCapabilities::Fine |
            PointerCapabilities::Hover;
   }
 
   if (IsTouchDeviceSupportPresent()) {
     return PointerCapabilities::Coarse;
   }
 
   return PointerCapabilities::None;