From 9be0f2945d404ceb743e4805f7df388c7fd039f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Thu, 9 Jun 2022 13:10:03 +0200 Subject: [PATCH] wasm: begin work on accessibility backend Implement a11y support by adding html elements of the appropriate type and/or with the appropriate ARIA attribute behind the canvas. Also add a simple manual-test. Change-Id: I2898fb038c1d326135a1341cdee323bc964420bb Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/CMakeLists.txt | 1 + .../platforms/wasm/qwasmaccessibility.cpp | 250 ++++++++++++++++++ .../platforms/wasm/qwasmaccessibility.h | 44 +++ .../platforms/wasm/qwasmintegration.cpp | 13 +- src/plugins/platforms/wasm/qwasmintegration.h | 6 + src/plugins/platforms/wasm/qwasmscreen.cpp | 11 +- tests/manual/wasm/CMakeLists.txt | 1 + tests/manual/wasm/a11y/CMakeLists.txt | 3 + .../wasm/a11y/basic_widgets/CMakeLists.txt | 17 ++ .../a11y/basic_widgets/basic_widgets.html | 24 ++ tests/manual/wasm/a11y/basic_widgets/main.cpp | 33 +++ 11 files changed, 401 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/wasm/qwasmaccessibility.cpp create mode 100644 src/plugins/platforms/wasm/qwasmaccessibility.h create mode 100644 tests/manual/wasm/a11y/CMakeLists.txt create mode 100644 tests/manual/wasm/a11y/basic_widgets/CMakeLists.txt create mode 100644 tests/manual/wasm/a11y/basic_widgets/basic_widgets.html create mode 100644 tests/manual/wasm/a11y/basic_widgets/main.cpp diff --git a/src/plugins/platforms/wasm/CMakeLists.txt b/src/plugins/platforms/wasm/CMakeLists.txt index efd468c9be..113dad18c6 100644 --- a/src/plugins/platforms/wasm/CMakeLists.txt +++ b/src/plugins/platforms/wasm/CMakeLists.txt @@ -11,6 +11,7 @@ qt_internal_add_plugin(QWasmIntegrationPlugin STATIC SOURCES main.cpp + qwasmaccessibility.cpp qwasmaccessibility.h qwasmclipboard.cpp qwasmclipboard.h qwasmcompositor.cpp qwasmcompositor.h qwasmcursor.cpp qwasmcursor.h diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.cpp b/src/plugins/platforms/wasm/qwasmaccessibility.cpp new file mode 100644 index 0000000000..b96a3799e6 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmaccessibility.cpp @@ -0,0 +1,250 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwasmaccessibility.h" +#include "qwasmscreen.h" + +// Qt WebAssembly a11y backend +// +// This backend implements accessibility support by creating "shadowing" html +// elements for each Qt UI element. We access the DOM by using Emscripten's +// val.h API. +// +// Currently, html elements are created in response to notifyAccessibilityUpdate +// events. In addition or alternatively, we could also walk the accessibility tree +// from setRootObject(). + + +QWasmAccessibility::QWasmAccessibility() +{ + +} + +QWasmAccessibility::~QWasmAccessibility() +{ + +} + +emscripten::val QWasmAccessibility::getContainer(QAccessibleInterface *iface) +{ + // Get to QWasmScreen::container(), return undefined element if unable to + QWindow *window = iface->window(); + if (!window) + return emscripten::val::undefined(); + QWasmScreen *screen = QWasmScreen::get(window->screen()); + if (!screen) + return emscripten::val::undefined(); + return screen->container(); +} + +emscripten::val QWasmAccessibility::getDocument(const emscripten::val &container) +{ + if (container.isUndefined()) + return emscripten::val::undefined(); + return container["ownerDocument"]; +} + +emscripten::val QWasmAccessibility::getDocument(QAccessibleInterface *iface) +{ + return getDocument(getContainer(iface)); +} + +emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *iface) +{ + // Get the html container element for the interface; this depends on which + // QScreen it is on. If the interface is not on a screen yet we get an undefined + // container, and the code below handles that case as well. + emscripten::val container = getContainer(iface); + + // Get the correct html document for the container, or fall back + // to the global document. TODO: Does using the correct document actually matter? + emscripten::val document = container.isUndefined() ? emscripten::val::global("document") : getDocument(container); + + // Translate the Qt a11y elemen role into html element type + ARIA role. + // Here we can either create
elements with a spesific ARIA role, + // or create e.g.