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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Hiroyuki Ikezoe 2018-10-04 07:23:57 +00:00
parent a4be0a2e71
commit 6f732cd3ed
3 changed files with 53 additions and 2 deletions

View File

@ -10,6 +10,7 @@
#include <dbt.h>
#include <hidclass.h>
#include <ntddmou.h>
#include <setupapi.h>
namespace mozilla {
namespace widget {
@ -37,5 +38,32 @@ InputDeviceUtils::UnregisterNotification(HDEVNOTIFY aHandle)
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

View File

@ -16,6 +16,9 @@ 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

View File

@ -13,6 +13,7 @@
#include "gfxUtils.h"
#include "nsWindow.h"
#include "nsWindowDefs.h"
#include "InputDeviceUtils.h"
#include "KeyboardLayout.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/BackgroundHangMonitor.h"
@ -1900,7 +1901,26 @@ IsTabletDevice()
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 */
@ -1912,7 +1932,7 @@ WinUtils::GetPrimaryPointerCapabilities()
}
if (IsMousePresent()) {
return PointerCapabilities::Fine|
return PointerCapabilities::Fine |
PointerCapabilities::Hover;
}