Bug 1035774 - Support dynamic input device changes for windows. r=aklotz

Note that this dynamic change will not work without a patch for bug 1478576
if user doesn't touch browser windows.

Differential Revision: https://phabricator.services.mozilla.com/D3301
This commit is contained in:
Hiroyuki Ikezoe 2018-08-14 16:38:03 +09:00
Родитель fa9d7563e5
Коммит 3ce66a8f65
5 изменённых файлов: 95 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:set ts=2 sts=2 sw=2 et cin: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* 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>
namespace mozilla {
namespace widget {
HDEVNOTIFY
InputDeviceUtils::RegisterNotification(HWND aHwnd)
{
DEV_BROADCAST_DEVICEINTERFACE filter = {};
filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// We only need notifications for mouse type devices.
filter.dbcc_classguid = GUID_DEVINTERFACE_MOUSE;
return RegisterDeviceNotification(aHwnd,
&filter,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
void
InputDeviceUtils::UnregisterNotification(HDEVNOTIFY aHandle)
{
if (!aHandle) {
return;
}
UnregisterDeviceNotification(aHandle);
}
} // namespace widget
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sts=2 sw=2 et cin: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_widget_InputDeviceUtils_h__
#define mozilla_widget_InputDeviceUtils_h__
#include <windows.h>
namespace mozilla {
namespace widget {
class InputDeviceUtils {
public:
static HDEVNOTIFY RegisterNotification(HWND aHwnd);
static void UnregisterNotification(HDEVNOTIFY aHandle);
};
} // namespace widget
} // namespace mozilla
#endif // mozilla_widget_InputDeviceUtils_h__

Просмотреть файл

@ -99,6 +99,11 @@ SOURCES += [
'WinMouseScrollHandler.cpp',
]
# Needs INITGUID and we don't allow INITGUID in unified sources since bug 970429.
SOURCES += [
'InputDeviceUtils.cpp',
]
if CONFIG['NS_PRINTING']:
UNIFIED_SOURCES += [
'nsDeviceContextSpecWin.cpp',

Просмотреть файл

@ -77,6 +77,7 @@
#include <wtsapi32.h>
#include <process.h>
#include <commctrl.h>
#include <dbt.h>
#include <unknwn.h>
#include <psapi.h>
@ -143,6 +144,7 @@
#include "nsStyleConsts.h"
#include "gfxConfig.h"
#include "InProcessWinCompositorWidget.h"
#include "InputDeviceUtils.h"
#include "ScreenHelperWin.h"
#include "nsIGfxInfo.h"
@ -604,6 +606,7 @@ nsWindow::nsWindow(bool aIsChildWindow)
mPaintDC = nullptr;
mPrevWndProc = nullptr;
mNativeDragTarget = nullptr;
mDeviceNotifyHandle = nullptr;
mInDtor = false;
mIsVisible = false;
mIsTopWidgetWindow = false;
@ -848,6 +851,9 @@ nsWindow::Create(nsIWidget* aParent,
NS_WARNING("nsWindow CreateWindowEx failed.");
return NS_ERROR_FAILURE;
}
mDeviceNotifyHandle = InputDeviceUtils::RegisterNotification(mWnd);
// If mDefaultScale is set before mWnd has been set, it will have the scale of the
// primary monitor, rather than the monitor that the window is actually on. For
// non-popup windows this gets corrected by the WM_DPICHANGED message which resets
@ -981,6 +987,9 @@ void nsWindow::Destroy()
* delete the nsWindow. */
ClearCachedResources();
InputDeviceUtils::UnregisterNotification(mDeviceNotifyHandle);
mDeviceNotifyHandle = nullptr;
// The DestroyWindow function destroys the specified window. The function sends WM_DESTROY
// and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus
// from it. The function also destroys the window's menu, flushes the thread message queue,
@ -5344,6 +5353,22 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
}
break;
case WM_DEVICECHANGE:
{
if (wParam == DBT_DEVICEARRIVAL ||
wParam == DBT_DEVICEREMOVECOMPLETE) {
DEV_BROADCAST_HDR* hdr = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
// Check dbch_devicetype explicitly since we will get other device types
// (e.g. DBT_DEVTYP_VOLUME) for some reasons even if we specify
// DBT_DEVTYP_DEVICEINTERFACE in the filter for
// RegisterDeviceNotification.
if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
NotifyThemeChanged();
}
}
}
break;
case WM_NCCALCSIZE:
{
if (mCustomNonClient) {

Просмотреть файл

@ -537,6 +537,7 @@ protected:
WNDPROC mPrevWndProc;
HBRUSH mBrush;
IMEContext mDefaultIMC;
HDEVNOTIFY mDeviceNotifyHandle;
bool mIsTopWidgetWindow;
bool mInDtor;
bool mIsVisible;