Bug 1325676: Prevent Windows 8 touchscreen support from instantiating a11y; r?jimm
MozReview-Commit-ID: 5qgjBPSVrAh
--- a/toolkit/xre/test/win/TestDllInterceptor.cpp
+++ b/toolkit/xre/test/win/TestDllInterceptor.cpp
@@ -162,15 +162,16 @@ int main()
TestDetour("user32.dll", "CreateWindowExW") &&
TestHook("user32.dll", "InSendMessageEx") &&
TestHook("imm32.dll", "ImmGetContext") &&
TestHook("imm32.dll", "ImmGetCompositionStringW") &&
TestHook("imm32.dll", "ImmSetCandidateWindow") &&
#ifdef _M_X64
TestHook("user32.dll", "GetKeyState") &&
#endif
+ TestHook("user32.dll", "SetWinEventHook") &&
TestDetour("ntdll.dll", "LdrLoadDll")) {
printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n");
return 0;
}
return 1;
}
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -341,37 +341,43 @@ DWORD CurrentWindowsTimeGetter::sLastPos
* 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().
+ *
+ * For Windows 8, we also hook tiptsf!ProcessCaretEvents, which is an a11y hook
+ * function that also calls into UIA.
*/
class TIPMessageHandler
{
public:
~TIPMessageHandler()
{
if (mHook) {
::UnhookWindowsHookEx(mHook);
}
}
static void Initialize()
{
MOZ_ASSERT(!sInstance);
+ if (!IsWin8OrLater()) {
+ return;
+ }
+
sInstance = new TIPMessageHandler();
ClearOnShutdown(&sInstance);
}
static bool IsA11yBlocked()
{
- MOZ_ASSERT(sInstance);
if (!sInstance) {
return false;
}
return sInstance->mA11yBlockCount > 0;
}
private:
@@ -388,31 +394,44 @@ private:
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);
+
+ if (!IsWin10OrLater()) {
+ // tiptsf loads when STA COM is first initialized, so it should be present
+ sTipTsfInterceptor.Init("tiptsf.dll");
+ DebugOnly<bool> ok = sTipTsfInterceptor.AddHook("ProcessCaretEvents",
+ reinterpret_cast<intptr_t>(&ProcessCaretEventsHook),
+ (void**) &sProcessCaretEventsStub);
+ MOZ_ASSERT(ok);
+ }
}
class MOZ_RAII A11yInstantiationBlocker
{
public:
A11yInstantiationBlocker()
{
- MOZ_ASSERT(TIPMessageHandler::sInstance);
+ if (!TIPMessageHandler::sInstance) {
+ return;
+ }
++TIPMessageHandler::sInstance->mA11yBlockCount;
}
~A11yInstantiationBlocker()
{
- MOZ_ASSERT(TIPMessageHandler::sInstance &&
- TIPMessageHandler::sInstance->mA11yBlockCount > 0);
+ if (!TIPMessageHandler::sInstance) {
+ return;
+ }
+ MOZ_ASSERT(TIPMessageHandler::sInstance->mA11yBlockCount > 0);
--TIPMessageHandler::sInstance->mA11yBlockCount;
}
};
friend class A11yInstantiationBlocker;
static LRESULT CALLBACK TIPHook(int aCode, WPARAM aWParam, LPARAM aLParam)
{
@@ -428,24 +447,39 @@ private:
A11yInstantiationBlocker block;
return ::CallNextHookEx(nullptr, aCode, aWParam, aLParam);
}
}
return ::CallNextHookEx(nullptr, aCode, aWParam, aLParam);
}
+ static void CALLBACK ProcessCaretEventsHook(HWINEVENTHOOK aWinEventHook,
+ DWORD aEvent, HWND aHwnd,
+ LONG aObjectId, LONG aChildId,
+ DWORD aGeneratingTid,
+ DWORD aEventTime)
+ {
+ A11yInstantiationBlocker block;
+ sProcessCaretEventsStub(aWinEventHook, aEvent, aHwnd, aObjectId, aChildId,
+ aGeneratingTid, aEventTime);
+ }
+
static StaticAutoPtr<TIPMessageHandler> sInstance;
-
- HHOOK mHook;
- UINT mMessages[7];
- uint32_t mA11yBlockCount;
+ static WindowsDllInterceptor sTipTsfInterceptor;
+ static WINEVENTPROC sProcessCaretEventsStub;
+
+ HHOOK mHook;
+ UINT mMessages[7];
+ uint32_t mA11yBlockCount;
};
StaticAutoPtr<TIPMessageHandler> TIPMessageHandler::sInstance;
+WindowsDllInterceptor TIPMessageHandler::sTipTsfInterceptor;
+WINEVENTPROC TIPMessageHandler::sProcessCaretEventsStub;
#endif // defined(ACCESSIBILITY)
} // namespace mozilla
/**************************************************************
*
* SECTION: globals variables