diff options
author | André de la Rocha <andre.rocha@qt.io> | 2022-07-06 03:22:53 +0200 |
---|---|---|
committer | André de la Rocha <andre.rocha@qt.io> | 2022-07-08 10:06:07 +0200 |
commit | 083ff27518a735e39563d1bae9c40ffbc7c1d527 (patch) | |
tree | aed497225ae6b2de1040c747b8f4a1c9f935f926 /src/plugins/platforms/windows/uiautomation | |
parent | 9aaf105bad79203065d5e947acfc08d1c82faf86 (diff) |
Windows QPA: Implement Selection UIA pattern for QTabBar
Adding Selection pattern for tab bars and SelectionItem pattern for
tab items, which are required for accessibility compliance.
Pick-to: 6.4 6.3 6.2
Fixes: QTBUG-104740
Change-Id: I0e3b1cfbf4838d8bc8b5bc2e2d7c9d372ac8b99d
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/plugins/platforms/windows/uiautomation')
3 files changed, 37 insertions, 23 deletions
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index 1bcd1ad4a9..2d5d91a7ea 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -295,14 +295,16 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow break; case UIA_SelectionPatternId: // Lists of items. - if (accessible->role() == QAccessible::List) { + if (accessible->role() == QAccessible::List + || accessible->role() == QAccessible::PageTabList) { *pRetVal = new QWindowsUiaSelectionProvider(id()); } break; case UIA_SelectionItemPatternId: // Items within a list and radio buttons. if ((accessible->role() == QAccessible::RadioButton) - || (accessible->role() == QAccessible::ListItem)) { + || (accessible->role() == QAccessible::ListItem) + || (accessible->role() == QAccessible::PageTab)) { *pRetVal = new QWindowsUiaSelectionItemProvider(id()); } break; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp index 14ec29c75b..7e829b24a7 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp @@ -40,8 +40,8 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::Select() if (!actionInterface) return UIA_E_ELEMENTNOTAVAILABLE; - if (accessible->role() == QAccessible::RadioButton) { - // For radio buttons we just invoke the selection action; others are automatically deselected. + if (accessible->role() == QAccessible::RadioButton || accessible->role() == QAccessible::PageTab) { + // For radio buttons/tabs we just invoke the selection action; others are automatically deselected. actionInterface->doAction(QAccessibleActionInterface::pressAction()); } else { // Toggle list item if not already selected. It must be done first to support all selection modes. @@ -77,8 +77,8 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::AddToSelection() if (!actionInterface) return UIA_E_ELEMENTNOTAVAILABLE; - if (accessible->role() == QAccessible::RadioButton) { - // For radio buttons we invoke the selection action. + if (accessible->role() == QAccessible::RadioButton || accessible->role() == QAccessible::PageTab) { + // For radio buttons and tabs we invoke the selection action. actionInterface->doAction(QAccessibleActionInterface::pressAction()); } else { // Toggle list item if not already selected. @@ -102,7 +102,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::RemoveFromSelection( if (!actionInterface) return UIA_E_ELEMENTNOTAVAILABLE; - if (accessible->role() != QAccessible::RadioButton) { + if (accessible->role() != QAccessible::RadioButton && accessible->role() != QAccessible::PageTab) { if (accessible->state().selected) { actionInterface->doAction(QAccessibleActionInterface::toggleAction()); } @@ -126,6 +126,8 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_IsSelected(BOOL if (accessible->role() == QAccessible::RadioButton) *pRetVal = accessible->state().checked; + else if (accessible->role() == QAccessible::PageTab) + *pRetVal = accessible->state().focused; else *pRetVal = accessible->state().selected; return S_OK; @@ -149,11 +151,10 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_SelectionContain return UIA_E_ELEMENTNOTAVAILABLE; // Radio buttons do not require a container. - if (accessible->role() == QAccessible::ListItem) { - if (QAccessibleInterface *parent = accessible->parent()) { - if (parent->role() == QAccessible::List) { - *pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent); - } + if (QAccessibleInterface *parent = accessible->parent()) { + if ((accessible->role() == QAccessible::ListItem && parent->role() == QAccessible::List) + || (accessible->role() == QAccessible::PageTab && parent->role() == QAccessible::PageTabList)) { + *pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent); } } return S_OK; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp index 1d110a637e..45f3b20552 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp @@ -45,8 +45,14 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY * QList<QAccessibleInterface *> selectedList; for (int i = 0; i < accessible->childCount(); ++i) { if (QAccessibleInterface *child = accessible->child(i)) { - if (child->state().selected) { - selectedList.append(child); + if (accessible->role() == QAccessible::PageTabList) { + if (child->role() == QAccessible::PageTab && child->state().focused) { + selectedList.append(child); + } + } else { + if (child->state().selected) { + selectedList.append(child); + } } } } @@ -90,18 +96,23 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired( if (!accessible) return UIA_E_ELEMENTNOTAVAILABLE; - // Initially returns false if none are selected. After the first selection, it may be required. - bool anySelected = false; - for (int i = 0; i < accessible->childCount(); ++i) { - if (QAccessibleInterface *child = accessible->child(i)) { - if (child->state().selected) { - anySelected = true; - break; + if (accessible->role() == QAccessible::PageTabList) { + *pRetVal = TRUE; + } else { + + // Initially returns false if none are selected. After the first selection, it may be required. + bool anySelected = false; + for (int i = 0; i < accessible->childCount(); ++i) { + if (QAccessibleInterface *child = accessible->child(i)) { + if (child->state().selected) { + anySelected = true; + break; + } } } - } - *pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable; + *pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable; + } return S_OK; } |