This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch base-browser-102.5.0esr-12.0-1 in repository tor-browser.
commit ba56a38c2cbc8a488724e5a9980078a82278306e Author: James Teh jteh@mozilla.com AuthorDate: Fri Oct 28 14:48:25 2022 +0000
Bug 1774285 - Avoid a11y instantiation after clipboard copy. r=nlapre,jamie, a=dmeehan
This prevents a11y from getting instantiated shortly after clipboard paste, in order to prevent hangs with the Windows 11 suggested actions feature.
When combined with the previous patch, the behavior is the following:
* For users with a11y already-enabled:
* No hang (due to clipboard flush). * Quick actions menu is positioned at selection offset.
* For users with a11y disabled (most):
* No hang (due to no a11y instantiation + clipboard flush). * Quick actions menu is positioned at pointer (cursor) offset.
Co-Authored-By: Emilio Cobos Álvarez emilio@crisal.io
Differential Revision: https://phabricator.services.mozilla.com/D160652
Depends on D160646 --- accessible/windows/msaa/Compatibility.cpp | 37 ++++++++++++++++++++++++++++ accessible/windows/msaa/Compatibility.h | 3 +++ accessible/windows/msaa/LazyInstantiator.cpp | 8 ++++++ modules/libpref/init/StaticPrefList.yaml | 12 +++++++++ widget/nsClipboardProxy.cpp | 7 ++++++ widget/windows/nsClipboard.cpp | 7 ++++++ 6 files changed, 74 insertions(+)
diff --git a/accessible/windows/msaa/Compatibility.cpp b/accessible/windows/msaa/Compatibility.cpp index ce4e858d38ce..3fdda8f866c6 100644 --- a/accessible/windows/msaa/Compatibility.cpp +++ b/accessible/windows/msaa/Compatibility.cpp @@ -243,3 +243,40 @@ void Compatibility::GetHumanReadableConsumersStr(nsAString& aResult) { } } } + +// Time when SuppressA11yForClipboardCopy() was called, as returned by +// ::GetTickCount(). +static DWORD sA11yClipboardCopySuppressionStartTime = 0; + +/* static */ +void Compatibility::SuppressA11yForClipboardCopy() { + // Bug 1774285: Windows Suggested Actions (introduced in Windows 11 22H2) + // might walk the a11y tree using UIA whenever anything is copied to the + // clipboard. This causes an unacceptable hang, particularly when the cache + // is disabled. + bool doSuppress = [&] { + switch ( + StaticPrefs::accessibility_windows_suppress_after_clipboard_copy()) { + case 0: + return false; + case 1: + return true; + default: + return NeedsWindows11SuggestedActionsWorkaround(); + } + }(); + + if (doSuppress) { + sA11yClipboardCopySuppressionStartTime = ::GetTickCount(); + } +} + +/* static */ +bool Compatibility::IsA11ySuppressedForClipboardCopy() { + constexpr DWORD kSuppressTimeout = 1000; // ms + if (!sA11yClipboardCopySuppressionStartTime) { + return false; + } + return ::GetTickCount() - sA11yClipboardCopySuppressionStartTime < + kSuppressTimeout; +} diff --git a/accessible/windows/msaa/Compatibility.h b/accessible/windows/msaa/Compatibility.h index b9684db70e82..072ecb4e0a05 100644 --- a/accessible/windows/msaa/Compatibility.h +++ b/accessible/windows/msaa/Compatibility.h @@ -77,6 +77,9 @@ class Compatibility { static bool IsModuleVersionLessThan(HMODULE aModuleHandle, unsigned long long aVersion);
+ static void SuppressA11yForClipboardCopy(); + static bool IsA11ySuppressedForClipboardCopy(); + private: Compatibility(); Compatibility(const Compatibility&); diff --git a/accessible/windows/msaa/LazyInstantiator.cpp b/accessible/windows/msaa/LazyInstantiator.cpp index 9bc2190ef82f..b637c0bb9b9c 100644 --- a/accessible/windows/msaa/LazyInstantiator.cpp +++ b/accessible/windows/msaa/LazyInstantiator.cpp @@ -214,6 +214,14 @@ bool LazyInstantiator::IsBlockedInjection() { * @return true if we should instantiate a11y */ bool LazyInstantiator::ShouldInstantiate(const DWORD aClientTid) { + if (Compatibility::IsA11ySuppressedForClipboardCopy()) { + // Bug 1774285: Windows Suggested Actions (introduced in Windows 11 22H2) + // walks the entire a11y tree using UIA whenever anything is copied to the + // clipboard. This causes an unacceptable hang, particularly when the cache + // is disabled. Don't allow a11y to be instantiated by this. + return false; + } + if (!aClientTid) { // aClientTid == 0 implies that this is either an in-process call, or else // we failed to retrieve information about the remote caller. diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index b7c239fd080b..72ae8d3af80d 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -228,6 +228,18 @@ #endif mirror: once
+# Whether to avoid accessibility activation on Windows shortly after clipboard +# copy. +# +# Possible values are: +# * 0: never +# * 1: always +# * 2 (or others): when needed +- name: accessibility.windows.suppress-after-clipboard-copy + type: uint32_t + value: 2 + mirror: always + #--------------------------------------------------------------------------- # Prefs starting with "alerts." #--------------------------------------------------------------------------- diff --git a/widget/nsClipboardProxy.cpp b/widget/nsClipboardProxy.cpp index c375ac8e57a0..8bea74f2b464 100644 --- a/widget/nsClipboardProxy.cpp +++ b/widget/nsClipboardProxy.cpp @@ -2,6 +2,9 @@ * 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/. */
+#if defined(ACCESSIBILITY) && defined(XP_WIN) +# include "mozilla/a11y/Compatibility.h" +#endif #include "mozilla/dom/ContentChild.h" #include "mozilla/Unused.h" #include "nsArrayUtils.h" @@ -23,6 +26,10 @@ nsClipboardProxy::nsClipboardProxy() : mClipboardCaps(false, false) {} NS_IMETHODIMP nsClipboardProxy::SetData(nsITransferable* aTransferable, nsIClipboardOwner* anOwner, int32_t aWhichClipboard) { +#if defined(ACCESSIBILITY) && defined(XP_WIN) + a11y::Compatibility::SuppressA11yForClipboardCopy(); +#endif + ContentChild* child = ContentChild::GetSingleton();
IPCDataTransfer ipcDataTransfer; diff --git a/widget/windows/nsClipboard.cpp b/widget/windows/nsClipboard.cpp index 2007bd9bdb83..87c3eac895d7 100644 --- a/widget/windows/nsClipboard.cpp +++ b/widget/windows/nsClipboard.cpp @@ -15,6 +15,9 @@ #include <thread> #include <chrono>
+#ifdef ACCESSIBILITY +# include "mozilla/a11y/Compatibility.h" +#endif #include "mozilla/Logging.h" #include "mozilla/StaticPrefs_clipboard.h" #include "nsArrayUtils.h" @@ -482,6 +485,10 @@ NS_IMETHODIMP nsClipboard::SetNativeClipboardData(int32_t aWhichClipboard) { return NS_ERROR_FAILURE; }
+#ifdef ACCESSIBILITY + a11y::Compatibility::SuppressA11yForClipboardCopy(); +#endif + IDataObject* dataObj; if (NS_SUCCEEDED(CreateNativeDataObject(mTransferable, &dataObj, nullptr))) { // this add refs dataObj