Route blocking accessibility calls through the watchdog so a hung app can't freeze NVDA (#20170)
Fixes #20169
Summary of the issue:
When an application stops responding, NVDA's core thread blocks on synchronous cross-process accessibility calls into it. Some of these calls — notably UiaHasServerSideProvider and the in-process Word object-model RPC — are not routed through any mechanism the watchdog can cancel, so NVDA can stay frozen until the application is killed.
Description of user facing changes:
NVDA recovers more quickly when an application stops responding; in particular, switching away from a hung application returns NVDA to responsiveness immediately.
Description of developer facing changes:
A handful of blocking cross-process accessibility calls are now run via watchdog.cancellableExecute.
Description of development approach:
Reworked from the original proposal per @jcsteh's review: rather than introducing a per-call timeout, a circuit breaker, or a new state module, this relies entirely on the existing watchdog, which already centralises hang detection with a dynamically-adjusted timeout (and crucially drops it to MIN_CORE_ALIVE_TIMEOUT when the user switches apps).
The blocking calls the watchdog cannot otherwise cancel are routed through watchdog.cancellableExecute:
UIAHandler._isUIAWindowHelper: UiaHasServerSideProvider.
NVDAObjects.UIA.kwargsFromSuper: the UIA client element lookups (ElementFromHandleBuildCache / getFocusedElementBuildCache / ElementFromPointBuildCache).
winword getTextWithFields: nvdaInProcUtils_winword_getTextInRange.
On cancellation each caller falls back exactly as it already does on the corresponding failure path. cancellableExecute itself is unchanged.