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. Fixes: QTBUG-104740 Change-Id: I0e3b1cfbf4838d8bc8b5bc2e2d7c9d372ac8b99d Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> (cherry picked from commit 083ff27518a735e39563d1bae9c40ffbc7c1d527) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
4ef77e81b3
commit
c9c3f57883
@ -295,14 +295,16 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow
|
|||||||
break;
|
break;
|
||||||
case UIA_SelectionPatternId:
|
case UIA_SelectionPatternId:
|
||||||
// Lists of items.
|
// Lists of items.
|
||||||
if (accessible->role() == QAccessible::List) {
|
if (accessible->role() == QAccessible::List
|
||||||
|
|| accessible->role() == QAccessible::PageTabList) {
|
||||||
*pRetVal = new QWindowsUiaSelectionProvider(id());
|
*pRetVal = new QWindowsUiaSelectionProvider(id());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UIA_SelectionItemPatternId:
|
case UIA_SelectionItemPatternId:
|
||||||
// Items within a list and radio buttons.
|
// Items within a list and radio buttons.
|
||||||
if ((accessible->role() == QAccessible::RadioButton)
|
if ((accessible->role() == QAccessible::RadioButton)
|
||||||
|| (accessible->role() == QAccessible::ListItem)) {
|
|| (accessible->role() == QAccessible::ListItem)
|
||||||
|
|| (accessible->role() == QAccessible::PageTab)) {
|
||||||
*pRetVal = new QWindowsUiaSelectionItemProvider(id());
|
*pRetVal = new QWindowsUiaSelectionItemProvider(id());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -40,8 +40,8 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::Select()
|
|||||||
if (!actionInterface)
|
if (!actionInterface)
|
||||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||||
|
|
||||||
if (accessible->role() == QAccessible::RadioButton) {
|
if (accessible->role() == QAccessible::RadioButton || accessible->role() == QAccessible::PageTab) {
|
||||||
// For radio buttons we just invoke the selection action; others are automatically deselected.
|
// For radio buttons/tabs we just invoke the selection action; others are automatically deselected.
|
||||||
actionInterface->doAction(QAccessibleActionInterface::pressAction());
|
actionInterface->doAction(QAccessibleActionInterface::pressAction());
|
||||||
} else {
|
} else {
|
||||||
// Toggle list item if not already selected. It must be done first to support all selection modes.
|
// 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)
|
if (!actionInterface)
|
||||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||||
|
|
||||||
if (accessible->role() == QAccessible::RadioButton) {
|
if (accessible->role() == QAccessible::RadioButton || accessible->role() == QAccessible::PageTab) {
|
||||||
// For radio buttons we invoke the selection action.
|
// For radio buttons and tabs we invoke the selection action.
|
||||||
actionInterface->doAction(QAccessibleActionInterface::pressAction());
|
actionInterface->doAction(QAccessibleActionInterface::pressAction());
|
||||||
} else {
|
} else {
|
||||||
// Toggle list item if not already selected.
|
// Toggle list item if not already selected.
|
||||||
@ -102,7 +102,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::RemoveFromSelection(
|
|||||||
if (!actionInterface)
|
if (!actionInterface)
|
||||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||||
|
|
||||||
if (accessible->role() != QAccessible::RadioButton) {
|
if (accessible->role() != QAccessible::RadioButton && accessible->role() != QAccessible::PageTab) {
|
||||||
if (accessible->state().selected) {
|
if (accessible->state().selected) {
|
||||||
actionInterface->doAction(QAccessibleActionInterface::toggleAction());
|
actionInterface->doAction(QAccessibleActionInterface::toggleAction());
|
||||||
}
|
}
|
||||||
@ -126,6 +126,8 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_IsSelected(BOOL
|
|||||||
|
|
||||||
if (accessible->role() == QAccessible::RadioButton)
|
if (accessible->role() == QAccessible::RadioButton)
|
||||||
*pRetVal = accessible->state().checked;
|
*pRetVal = accessible->state().checked;
|
||||||
|
else if (accessible->role() == QAccessible::PageTab)
|
||||||
|
*pRetVal = accessible->state().focused;
|
||||||
else
|
else
|
||||||
*pRetVal = accessible->state().selected;
|
*pRetVal = accessible->state().selected;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -149,13 +151,12 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_SelectionContain
|
|||||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||||
|
|
||||||
// Radio buttons do not require a container.
|
// Radio buttons do not require a container.
|
||||||
if (accessible->role() == QAccessible::ListItem) {
|
|
||||||
if (QAccessibleInterface *parent = accessible->parent()) {
|
if (QAccessibleInterface *parent = accessible->parent()) {
|
||||||
if (parent->role() == QAccessible::List) {
|
if ((accessible->role() == QAccessible::ListItem && parent->role() == QAccessible::List)
|
||||||
|
|| (accessible->role() == QAccessible::PageTab && parent->role() == QAccessible::PageTabList)) {
|
||||||
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent);
|
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +45,17 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY *
|
|||||||
QList<QAccessibleInterface *> selectedList;
|
QList<QAccessibleInterface *> selectedList;
|
||||||
for (int i = 0; i < accessible->childCount(); ++i) {
|
for (int i = 0; i < accessible->childCount(); ++i) {
|
||||||
if (QAccessibleInterface *child = accessible->child(i)) {
|
if (QAccessibleInterface *child = accessible->child(i)) {
|
||||||
|
if (accessible->role() == QAccessible::PageTabList) {
|
||||||
|
if (child->role() == QAccessible::PageTab && child->state().focused) {
|
||||||
|
selectedList.append(child);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (child->state().selected) {
|
if (child->state().selected) {
|
||||||
selectedList.append(child);
|
selectedList.append(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) {
|
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) {
|
||||||
for (LONG i = 0; i < selectedList.size(); ++i) {
|
for (LONG i = 0; i < selectedList.size(); ++i) {
|
||||||
@ -90,6 +96,10 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(
|
|||||||
if (!accessible)
|
if (!accessible)
|
||||||
return UIA_E_ELEMENTNOTAVAILABLE;
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
||||||
|
|
||||||
|
if (accessible->role() == QAccessible::PageTabList) {
|
||||||
|
*pRetVal = TRUE;
|
||||||
|
} else {
|
||||||
|
|
||||||
// Initially returns false if none are selected. After the first selection, it may be required.
|
// Initially returns false if none are selected. After the first selection, it may be required.
|
||||||
bool anySelected = false;
|
bool anySelected = false;
|
||||||
for (int i = 0; i < accessible->childCount(); ++i) {
|
for (int i = 0; i < accessible->childCount(); ++i) {
|
||||||
@ -102,6 +112,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(
|
|||||||
}
|
}
|
||||||
|
|
||||||
*pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
|
*pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
|
||||||
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user