diff options
Diffstat (limited to 'src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp')
-rw-r--r-- | src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index 2d5d91a7ea..16f0a3f9a6 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -38,10 +38,13 @@ QT_BEGIN_NAMESPACE using namespace QWindowsUiAutomation; +QMutex QWindowsUiaMainProvider::m_mutex; // Returns a cached instance of the provider for a specific accessible interface. QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible) { + QMutexLocker locker(&m_mutex); + if (!accessible) return nullptr; @@ -71,10 +74,11 @@ QWindowsUiaMainProvider::~QWindowsUiaMainProvider() void QWindowsUiaMainProvider::notifyFocusChange(QAccessibleEvent *event) { if (QAccessibleInterface *accessible = event->accessibleInterface()) { - // If this is a table/tree/list, raise event for the focused cell/item instead. - if (accessible->tableInterface()) + // If this is a complex element, raise event for the focused child instead. + if (accessible->childCount()) { if (QAccessibleInterface *child = accessible->focusChild()) accessible = child; + } if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_AutomationFocusChangedEventId); } @@ -103,6 +107,10 @@ void QWindowsUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *eve if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { if (accessible->state().active) { QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Window_WindowOpenedEventId); + if (QAccessibleInterface *focused = accessible->focusChild()) { + if (QWindowsUiaMainProvider *focusedProvider = providerForAccessible(focused)) + QWindowsUiaWrapper::instance()->raiseAutomationEvent(focusedProvider, UIA_AutomationFocusChangedEventId); + } } else { QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Window_WindowClosedEventId); } @@ -235,6 +243,8 @@ ULONG QWindowsUiaMainProvider::AddRef() ULONG STDMETHODCALLTYPE QWindowsUiaMainProvider::Release() { + QMutexLocker locker(&m_mutex); + if (!--m_ref) { delete this; return 0; @@ -699,26 +709,18 @@ HRESULT QWindowsUiaMainProvider::ElementProviderFromPoint(double x, double y, IR QPoint point; nativeUiaPointToPoint(uiaPoint, window, &point); - if (auto targetacc = accessible->childAt(point.x(), point.y())) { - auto acc = accessible->childAt(point.x(), point.y()); - // Reject the cases where childAt() returns a different instance in each call for the same - // element (e.g., QAccessibleTree), as it causes an endless loop with Youdao Dictionary installed. - if (targetacc == acc) { - // Controls can be embedded within grouping elements. By default returns the innermost control. - while (acc) { - targetacc = acc; - // For accessibility tools it may be better to return the text element instead of its subcomponents. - if (targetacc->textInterface()) break; - acc = targetacc->childAt(point.x(), point.y()); - if (acc != targetacc->childAt(point.x(), point.y())) { - qCDebug(lcQpaUiAutomation) << "Non-unique childAt() for" << targetacc; - break; - } - } - *pRetVal = providerForAccessible(targetacc); - } else { - qCDebug(lcQpaUiAutomation) << "Non-unique childAt() for" << accessible; + QAccessibleInterface *targetacc = accessible->childAt(point.x(), point.y()); + + if (targetacc) { + QAccessibleInterface *acc = targetacc; + // Controls can be embedded within grouping elements. By default returns the innermost control. + while (acc) { + targetacc = acc; + // For accessibility tools it may be better to return the text element instead of its subcomponents. + if (targetacc->textInterface()) break; + acc = acc->childAt(point.x(), point.y()); } + *pRetVal = providerForAccessible(targetacc); } return S_OK; } |