diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.cpp b/src/plugins/platforms/wasm/qwasmaccessibility.cpp index e3a46db43ce..a82e2ea6c1b 100644 --- a/src/plugins/platforms/wasm/qwasmaccessibility.cpp +++ b/src/plugins/platforms/wasm/qwasmaccessibility.cpp @@ -25,8 +25,10 @@ Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility") QWasmAccessibility::QWasmAccessibility() { - s_instance = this; + + if (qEnvironmentVariableIntValue("QT_WASM_ENABLE_ACCESSIBILITY") == 1) + enableAccessibility(); } QWasmAccessibility::~QWasmAccessibility() @@ -51,6 +53,11 @@ void QWasmAccessibility::removeAccessibilityEnableButton(QWindow *window) get()->removeAccessibilityEnableButtonImpl(window); } +void QWasmAccessibility::onShowWindow(QWindow *window) +{ + get()->onShowWindowImpl(window); +} + void QWasmAccessibility::addAccessibilityEnableButtonImpl(QWindow *window) { if (m_accessibilityEnabled) @@ -68,6 +75,14 @@ void QWasmAccessibility::addAccessibilityEnableButtonImpl(QWindow *window) m_enableButtons.insert(std::make_pair(window, std::move(enableContext))); } +void QWasmAccessibility::onShowWindowImpl(QWindow *window) +{ + if (!m_accessibilityEnabled) + return; + + populateAccessibilityTree(QAccessible::queryAccessibleInterface(window)); +} + void QWasmAccessibility::removeAccessibilityEnableButtonImpl(QWindow *window) { auto it = m_enableButtons.find(window); @@ -83,8 +98,8 @@ void QWasmAccessibility::removeAccessibilityEnableButtonImpl(QWindow *window) void QWasmAccessibility::enableAccessibility() { - // Enable accessibility globally for the applicaton. Remove all "enable" - // buttons and populate the accessibility tree, starting from the root object. + // Enable accessibility. Remove all "enable" buttons and populate the + // accessibility tree for each window. Q_ASSERT(!m_accessibilityEnabled); m_accessibilityEnabled = true; @@ -93,16 +108,16 @@ void QWasmAccessibility::enableAccessibility() const auto &[element, callback] = value; Q_UNUSED(key); Q_UNUSED(callback); + onShowWindowImpl(key); element["parentElement"].call("removeChild", element); } m_enableButtons.clear(); - populateAccessibilityTree(QAccessible::queryAccessibleInterface(m_rootObject)); } emscripten::val QWasmAccessibility::getContainer(QWindow *window) { - return window ? static_cast(window->handle())->a11yContainer() - : emscripten::val::undefined(); + const auto wasmWindow = QWasmWindow::fromWindow(window); + return (wasmWindow) ? wasmWindow->a11yContainer() : emscripten::val::undefined(); } emscripten::val QWasmAccessibility::getContainer(QAccessibleInterface *iface) @@ -549,13 +564,19 @@ void QWasmAccessibility::populateAccessibilityTree(QAccessibleInterface *iface) if (!iface) return; - // Create html element for the interface, sync up properties. - ensureHtmlElement(iface); - setHtmlElementVisibility(iface, true); - setHtmlElementGeometry(iface); - setHtmlElementTextName(iface); - setHtmlElementDescription(iface); + // We ignore toplevel windows which is categorized + // by getWindow(iface->parent()) != getWindow(iface) + QWindow *window1 = getWindow(iface); + QWindow *window0 = (iface->parent()) ? getWindow(iface->parent()) : nullptr; + if (window1 && window0 == window1) { + // Create html element for the interface, sync up properties. + ensureHtmlElement(iface); + setHtmlElementVisibility(iface, true); + setHtmlElementGeometry(iface); + setHtmlElementTextName(iface); + setHtmlElementDescription(iface); + } for (int i = 0; i < iface->childCount(); ++i) populateAccessibilityTree(iface->child(i)); } diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.h b/src/plugins/platforms/wasm/qwasmaccessibility.h index c4be7f0d72a..2a2deb11dc9 100644 --- a/src/plugins/platforms/wasm/qwasmaccessibility.h +++ b/src/plugins/platforms/wasm/qwasmaccessibility.h @@ -31,11 +31,13 @@ public: static void addAccessibilityEnableButton(QWindow *window); static void removeAccessibilityEnableButton(QWindow *window); + static void onShowWindow(QWindow *); private: void addAccessibilityEnableButtonImpl(QWindow *window); void removeAccessibilityEnableButtonImpl(QWindow *window); void enableAccessibility(); + void onShowWindowImpl(QWindow *); static emscripten::val getContainer(QWindow *window); static emscripten::val getContainer(QAccessibleInterface *iface); @@ -84,7 +86,6 @@ private: bool m_accessibilityEnabled = false; std::map>> m_enableButtons; QHash m_elements; - }; #endif // QT_CONFIG(accessibility) diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 16ee1c3bc53..98e9d9f9bfe 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -193,6 +193,9 @@ void QWasmWindow::registerEventHandlers() QWasmWindow::~QWasmWindow() { +#if QT_CONFIG(accessibility) + QWasmAccessibility::removeAccessibilityEnableButton(window()); +#endif shutdown(); emscripten::val::module_property("specialHTMLTargets").delete_(canvasSelector()); @@ -201,9 +204,6 @@ QWasmWindow::~QWasmWindow() commitParent(nullptr); if (m_requestAnimationFrameId > -1) emscripten_cancel_animation_frame(m_requestAnimationFrameId); -#if QT_CONFIG(accessibility) - QWasmAccessibility::removeAccessibilityEnableButton(window()); -#endif } QSurfaceFormat QWasmWindow::format() const @@ -274,7 +274,7 @@ void QWasmWindow::initialize() #if QT_CONFIG(accessibility) // Add accessibility-enable button. The user can activate this // button to opt-in to accessibility. - if (window()->isTopLevel()) + if (window()->isTopLevel()) QWasmAccessibility::addAccessibilityEnableButton(window()); #endif } @@ -383,8 +383,12 @@ void QWasmWindow::setVisible(bool visible) if (window() == QGuiApplication::focusWindow()) focus(); - if (visible) + if (visible) { applyWindowState(); +#if QT_CONFIG(accessibility) + QWasmAccessibility::onShowWindow(window()); +#endif + } } bool QWasmWindow::isVisible() const diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index 8b5e6d56a71..c77bfae3cb2 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -140,11 +140,11 @@ private: QWasmDeadKeySupport *m_deadKeySupport; QRect m_normalGeometry {0, 0, 0 ,0}; - emscripten::val m_document; - emscripten::val m_decoratedWindow; - emscripten::val m_window; - emscripten::val m_a11yContainer; - emscripten::val m_canvas; + emscripten::val m_document = emscripten::val::undefined(); + emscripten::val m_decoratedWindow = emscripten::val::undefined(); + emscripten::val m_window = emscripten::val::undefined(); + emscripten::val m_a11yContainer = emscripten::val::undefined(); + emscripten::val m_canvas = emscripten::val::undefined(); emscripten::val m_context2d = emscripten::val::undefined(); std::unique_ptr m_nonClientArea;