зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1323521: Prevent Windows touchscreen support from instantiating a11y; r=jimm
MozReview-Commit-ID: 3xV0b97lEre --HG-- extra : rebase_source : 7edcc93d409ffcd50e0fe4307573c2660a274b28 extra : amend_source : 0b8f3fbc292b632b448c135ea55fa6f63d292b35
This commit is contained in:
Родитель
1ce9acc2f9
Коммит
39b609a350
|
@ -329,6 +329,118 @@ private:
|
||||||
Maybe<TimeStamp> CurrentWindowsTimeGetter::sBackwardsSkewStamp;
|
Maybe<TimeStamp> CurrentWindowsTimeGetter::sBackwardsSkewStamp;
|
||||||
DWORD CurrentWindowsTimeGetter::sLastPostTime = 0;
|
DWORD CurrentWindowsTimeGetter::sLastPostTime = 0;
|
||||||
|
|
||||||
|
#if defined(ACCESSIBILITY)
|
||||||
|
/**
|
||||||
|
* Windows touchscreen code works by setting a global WH_GETMESSAGE hook and
|
||||||
|
* injecting tiptsf.dll. The touchscreen process then posts registered messages
|
||||||
|
* to our main thread. The tiptsf hook picks up those registered messages and
|
||||||
|
* uses them as commands, some of which call into UIA, which then calls into
|
||||||
|
* MSAA, which then sends WM_GETOBJECT to us.
|
||||||
|
*
|
||||||
|
* We can get ahead of this by installing our own thread-local WH_GETMESSAGE
|
||||||
|
* hook. Since thread-local hooks are called ahead of global hooks, we will
|
||||||
|
* see these registered messages before tiptsf does. At this point we can then
|
||||||
|
* raise a flag that blocks a11y before invoking CallNextHookEx which will then
|
||||||
|
* invoke the global tiptsf hook. Then when we see WM_GETOBJECT, we check the
|
||||||
|
* flag by calling TIPMessageHandler::IsA11yBlocked().
|
||||||
|
*/
|
||||||
|
class TIPMessageHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~TIPMessageHandler()
|
||||||
|
{
|
||||||
|
if (mHook) {
|
||||||
|
::UnhookWindowsHookEx(mHook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Initialize()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!sInstance);
|
||||||
|
sInstance = new TIPMessageHandler();
|
||||||
|
ClearOnShutdown(&sInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsA11yBlocked()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(sInstance);
|
||||||
|
if (!sInstance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sInstance->mA11yBlockCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TIPMessageHandler()
|
||||||
|
: mHook(nullptr)
|
||||||
|
, mA11yBlockCount(0)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
// Registered messages used by tiptsf
|
||||||
|
mMessages[0] = ::RegisterWindowMessage(L"ImmersiveFocusNotification");
|
||||||
|
mMessages[1] = ::RegisterWindowMessage(L"TipCloseMenus");
|
||||||
|
mMessages[2] = ::RegisterWindowMessage(L"TabletInputPanelOpening");
|
||||||
|
mMessages[3] = ::RegisterWindowMessage(L"IHM Pen or Touch Event noticed");
|
||||||
|
mMessages[4] = ::RegisterWindowMessage(L"ProgrammabilityCaretVisibility");
|
||||||
|
mMessages[5] = ::RegisterWindowMessage(L"CaretTrackingUpdateIPHidden");
|
||||||
|
mMessages[6] = ::RegisterWindowMessage(L"CaretTrackingUpdateIPInfo");
|
||||||
|
|
||||||
|
mHook = ::SetWindowsHookEx(WH_GETMESSAGE, &TIPHook, nullptr,
|
||||||
|
::GetCurrentThreadId());
|
||||||
|
MOZ_ASSERT(mHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MOZ_RAII A11yInstantiationBlocker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
A11yInstantiationBlocker()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(TIPMessageHandler::sInstance);
|
||||||
|
++TIPMessageHandler::sInstance->mA11yBlockCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
~A11yInstantiationBlocker()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(TIPMessageHandler::sInstance &&
|
||||||
|
TIPMessageHandler::sInstance->mA11yBlockCount > 0);
|
||||||
|
--TIPMessageHandler::sInstance->mA11yBlockCount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class A11yInstantiationBlocker;
|
||||||
|
|
||||||
|
static LRESULT CALLBACK TIPHook(int aCode, WPARAM aWParam, LPARAM aLParam)
|
||||||
|
{
|
||||||
|
if (aCode < 0 || !sInstance) {
|
||||||
|
return ::CallNextHookEx(nullptr, aCode, aWParam, aLParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG* msg = reinterpret_cast<MSG*>(aLParam);
|
||||||
|
UINT& msgCode = msg->message;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ArrayLength(sInstance->mMessages); ++i) {
|
||||||
|
if (msgCode == sInstance->mMessages[i]) {
|
||||||
|
A11yInstantiationBlocker block;
|
||||||
|
return ::CallNextHookEx(nullptr, aCode, aWParam, aLParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ::CallNextHookEx(nullptr, aCode, aWParam, aLParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StaticAutoPtr<TIPMessageHandler> sInstance;
|
||||||
|
|
||||||
|
HHOOK mHook;
|
||||||
|
UINT mMessages[7];
|
||||||
|
uint32_t mA11yBlockCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
StaticAutoPtr<TIPMessageHandler> TIPMessageHandler::sInstance;
|
||||||
|
|
||||||
|
#endif // defined(ACCESSIBILITY)
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
|
@ -456,6 +568,9 @@ nsWindow::nsWindow()
|
||||||
// WinTaskbar.cpp for details.
|
// WinTaskbar.cpp for details.
|
||||||
mozilla::widget::WinTaskbar::RegisterAppUserModelID();
|
mozilla::widget::WinTaskbar::RegisterAppUserModelID();
|
||||||
KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0));
|
KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0));
|
||||||
|
#if defined(ACCESSIBILITY)
|
||||||
|
mozilla::TIPMessageHandler::Initialize();
|
||||||
|
#endif // defined(ACCESSIBILITY)
|
||||||
IMEHandler::Initialize();
|
IMEHandler::Initialize();
|
||||||
if (SUCCEEDED(::OleInitialize(nullptr))) {
|
if (SUCCEEDED(::OleInitialize(nullptr))) {
|
||||||
sIsOleInitialized = TRUE;
|
sIsOleInitialized = TRUE;
|
||||||
|
@ -3281,9 +3396,9 @@ nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen)
|
||||||
if (aFullScreen && !sCurrentWindow) {
|
if (aFullScreen && !sCurrentWindow) {
|
||||||
sCurrentWindow = this;
|
sCurrentWindow = this;
|
||||||
LPARAM pos = sCurrentWindow->lParamToClient(sMouseExitlParamScreen);
|
LPARAM pos = sCurrentWindow->lParamToClient(sMouseExitlParamScreen);
|
||||||
sCurrentWindow->DispatchMouseEvent(eMouseEnterIntoWidget,
|
sCurrentWindow->DispatchMouseEvent(eMouseEnterIntoWidget,
|
||||||
sMouseExitwParam, pos, false,
|
sMouseExitwParam, pos, false,
|
||||||
WidgetMouseEvent::eLeftButton,
|
WidgetMouseEvent::eLeftButton,
|
||||||
MOUSE_INPUT_SOURCE(), MOUSE_POINTERID());
|
MOUSE_INPUT_SOURCE(), MOUSE_POINTERID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5599,7 +5714,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
||||||
// Do explicit casting to make it working on 64bit systems (see bug 649236
|
// Do explicit casting to make it working on 64bit systems (see bug 649236
|
||||||
// for details).
|
// for details).
|
||||||
int32_t objId = static_cast<DWORD>(lParam);
|
int32_t objId = static_cast<DWORD>(lParam);
|
||||||
if (objId == OBJID_CLIENT) { // oleacc.dll will be loaded dynamically
|
if (!TIPMessageHandler::IsA11yBlocked() && objId == OBJID_CLIENT) { // oleacc.dll will be loaded dynamically
|
||||||
a11y::Accessible* rootAccessible = GetAccessible(); // Held by a11y cache
|
a11y::Accessible* rootAccessible = GetAccessible(); // Held by a11y cache
|
||||||
if (rootAccessible) {
|
if (rootAccessible) {
|
||||||
IAccessible *msaaAccessible = nullptr;
|
IAccessible *msaaAccessible = nullptr;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче