wasm: a11y - synchronize focus between Qt and a11y

Listen for "focus" javascript events..
Listen for QAccessible::Focus a11y events.

When receiving QAccessible::PopupMenuStart set
focus to first item.

Task-number: QTBUG-135096
Change-Id: I676e53e77169cc1643765210318b460193042c53
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Even Oscar Andersen 2025-04-05 05:45:08 +02:00
parent 5ced648feb
commit a4aac362cf
2 changed files with 23 additions and 2 deletions

View File

@ -304,6 +304,8 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
if (iface->role() != QAccessible::PageTabList)
element.call<void>("setAttribute", std::string("id"), id.toStdString());
element.call<void>("addEventListener", emscripten::val("focus"),
emscripten::val::module_property("qtEventReceived"), true);
return element;
}();
@ -401,6 +403,12 @@ void QWasmAccessibility::setHtmlElementDescription(QAccessibleInterface *iface)
element.call<void>("setAttribute", std::string("aria-description"), desc.toStdString());
}
void QWasmAccessibility::setHtmlElementFocus(QAccessibleInterface *iface)
{
auto element = ensureHtmlElement(iface);
element.call<void>("focus");
}
void QWasmAccessibility::handleStaticTextUpdate(QAccessibleEvent *event)
{
switch (event->type()) {
@ -441,13 +449,17 @@ void QWasmAccessibility::handleEventFromHtmlElement(const emscripten::val event)
{
QAccessibleInterface *iface = m_elements.key(event["target"]);
if (iface == nullptr) {
return;
} else {
QString eventType = QString::fromStdString(event["type"].as<std::string>());
const auto& actionNames = QAccessibleBridgeUtils::effectiveActionNames(iface);
if (actionNames.contains(QAccessibleActionInterface::pressAction())) {
if (eventType == "focus") {
if (actionNames.contains(QAccessibleActionInterface::setFocusAction()))
iface->actionInterface()->doAction(QAccessibleActionInterface::setFocusAction());
} else if (actionNames.contains(QAccessibleActionInterface::pressAction())) {
iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction());
} else if (actionNames.contains(QAccessibleActionInterface::toggleAction())) {
@ -528,11 +540,15 @@ void QWasmAccessibility::handleMenuUpdate(QAccessibleEvent *event)
case QAccessible::Focus:
case QAccessible::NameChanged:
case QAccessible::MenuStart ://"TODO: To implement later
case QAccessible::PopupMenuStart://"TODO: To implement later
case QAccessible::StateChanged:{
emscripten::val element = ensureHtmlElement(iface);
element.call<void>("setAttribute", std::string("title"), text.toStdString());
} break;
case QAccessible::PopupMenuStart: {
ensureHtmlElement(iface);
if (iface->childCount() > 0)
m_elements[iface->child(0)].call<void>("focus");
} break;
case QAccessible::DescriptionChanged: {
setHtmlElementDescription(event->accessibleInterface());
} break;
@ -720,6 +736,10 @@ void QWasmAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
// Handle some common event types. See
// https://doc.qt.io/qt-5/qaccessible.html#Event-enum
switch (event->type()) {
case QAccessible::Focus:
setHtmlElementFocus(iface);
break;
case QAccessible::ObjectShow:
setHtmlElementVisibility(iface, true);

View File

@ -54,6 +54,7 @@ private:
void setHtmlElementTextName(QAccessibleInterface *iface);
void setHtmlElementTextNameLE(QAccessibleInterface *iface);
void setHtmlElementDescription(QAccessibleInterface *iface);
void setHtmlElementFocus(QAccessibleInterface *iface);
void handleStaticTextUpdate(QAccessibleEvent *event);
void handleButtonUpdate(QAccessibleEvent *event);