File 2512ffea91bbaec41d55eea2813a365edc3160a5.patch of Package qt6-declarative

From 2512ffea91bbaec41d55eea2813a365edc3160a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= <jan-arve.saether@qt.io>
Date: Wed, 10 Sep 2025 20:19:40 +0200
Subject: [PATCH] a11y: Send missing QAccessible::ObjectShow event for Qt Quick
 Controls

Before sending the QAccessibleEvent QAccessible::ObjectShow event from
QQuickItemPrivate::setEffectiveVisibleRecur() we checked if
QQuickItemPrivate::isAccessible was set. For e.g. Button, isAccessible
wasn't set by default: This was because isAccessible was only set as a
response to that an Accessible attached property was assigned to the
item.

Therefore, when a Button was shown it could end up not sending the
QAccessible::ObjectShow event.

This problem was first found on Button, but after more investigation, we
have found that the same problem applies to:

* BusyIndicator
* Button
* ComboBox
* Dial
* Label (without a text)
* ProgressBar
* RangeSlider
* RoundButton
* Slider
* TextArea
* TextField

The fix is to explicitly enable accessibility by calling
QQuickItemPrivate::setAccessible() on *all* Qt Quick Controls, since
they are all supposed to be accessible.

Change-Id: If4fa050149a31bf2baffa208716341d21631c042
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
---
 src/quicktemplates/qquickcontrol.cpp          |  3 ++
 src/quicktemplates/qquicklabel.cpp            |  1 +
 src/quicktemplates/qquicktextarea.cpp         |  3 ++
 src/quicktemplates/qquicktextfield.cpp        |  1 +
 .../qquickaccessible/tst_qquickaccessible.cpp | 52 +++++++++++++++++++
 5 files changed, 60 insertions(+)

diff --git a/src/quicktemplates/qquickcontrol.cpp b/src/quicktemplates/qquickcontrol.cpp
index 2585078a76f..0c524aac218 100644
--- a/src/quicktemplates/qquickcontrol.cpp
+++ b/src/quicktemplates/qquickcontrol.cpp
@@ -138,6 +138,9 @@ void QQuickControlPrivate::init()
 {
     Q_Q(QQuickControl);
     QObject::connect(q, &QQuickItem::baselineOffsetChanged, q, &QQuickControl::baselineOffsetChanged);
+#if QT_CONFIG(accessibility)
+    setAccessible();
+#endif
 }
 
 #if QT_CONFIG(quicktemplates2_multitouch)
diff --git a/src/quicktemplates/qquicklabel.cpp b/src/quicktemplates/qquicklabel.cpp
index 793cab71657..70142321d5d 100644
--- a/src/quicktemplates/qquicklabel.cpp
+++ b/src/quicktemplates/qquicklabel.cpp
@@ -51,6 +51,7 @@ QQuickLabelPrivate::QQuickLabelPrivate()
 {
 #if QT_CONFIG(accessibility)
     QAccessible::installActivationObserver(this);
+    setAccessible();
 #endif
 }
 
diff --git a/src/quicktemplates/qquicktextarea.cpp b/src/quicktemplates/qquicktextarea.cpp
index e776ca6ae34..8da0e2710ea 100644
--- a/src/quicktemplates/qquicktextarea.cpp
+++ b/src/quicktemplates/qquicktextarea.cpp
@@ -122,6 +122,9 @@ using namespace Qt::StringLiterals;
 
 QQuickTextAreaPrivate::QQuickTextAreaPrivate()
 {
+#if QT_CONFIG(accessibility)
+    setAccessible();
+#endif
 }
 
 QQuickTextAreaPrivate::~QQuickTextAreaPrivate()
diff --git a/src/quicktemplates/qquicktextfield.cpp b/src/quicktemplates/qquicktextfield.cpp
index 090dcf1146b..ab8f2649065 100644
--- a/src/quicktemplates/qquicktextfield.cpp
+++ b/src/quicktemplates/qquicktextfield.cpp
@@ -88,6 +88,7 @@ QQuickTextFieldPrivate::QQuickTextFieldPrivate()
 {
 #if QT_CONFIG(accessibility)
     QAccessible::installActivationObserver(this);
+    setAccessible();
 #endif
 }
 
diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
index 2d8cb883cda..033cb5736ed 100644
--- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
+++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
@@ -27,6 +27,7 @@
 #include <QtQuickTestUtils/private/visualtestutils_p.h>
 
 #include <QQmlComponent>
+#include <QQmlApplicationEngine>
 
 using namespace Qt::StringLiterals;
 
@@ -72,6 +73,8 @@ private slots:
     void eventTest();
     void relations_data();
     void relations();
+    void controlsThatShouldSendObjectShow_data();
+    void controlsThatShouldSendObjectShow();
 };
 
 tst_QQuickAccessible::tst_QQuickAccessible()
@@ -933,6 +936,55 @@ void tst_QQuickAccessible::relations()
     QVERIFY(!otherRelations.isEmpty());
 }
 
+void tst_QQuickAccessible::controlsThatShouldSendObjectShow_data()
+{
+    QTest::addColumn<QByteArray>("qmlSnippet");
+
+    QTest::newRow("BusyIndicator") << QByteArray("BusyIndicator { running: true }");
+    QTest::newRow("Button") << QByteArray("Button { text: 'Button' }");
+    QTest::newRow("ComboBox") << QByteArray("ComboBox { model: 3 }");
+    QTest::newRow("Dial") << QByteArray("Dial { value: 0.5 }");
+    // Label without a text is a bit unusual,
+    // but the background can be an image with meaningful info...
+    QTest::newRow("Label") << QByteArray("Label {\nbackground: Rectangle {\ncolor: 'red'\n}\nwidth: 50\nheight: 20}");
+    QTest::newRow("ProgressBar") << QByteArray("ProgressBar { value: 0.5 }");
+    QTest::newRow("RangeSlider") << QByteArray("RangeSlider { from: 1; to: 100; second.value: 50 }");
+    QTest::newRow("RoundButton") << QByteArray("RoundButton { text: 'Yes, please' }");
+    QTest::newRow("Slider") << QByteArray("Slider { value: 0.5 }");
+    QTest::newRow("Switch") << QByteArray("Switch { text: 'Switch me' }");
+    QTest::newRow("TextArea") << QByteArray("TextArea { width: 50}");
+    QTest::newRow("TextField") << QByteArray("TextField { width: 50}");
+
+    QTest::newRow("CheckBox") << QByteArray("CheckBox { text: 'checkBox' }");
+    QTest::newRow("DelayButton") << QByteArray("DelayButton { text: 'Are you really sure?' }");
+    QTest::newRow("RadioButton") << QByteArray("RadioButton { text: 'RadioButton' }");
+    QTest::newRow("TabButton") << QByteArray("TabButton { text: 'Home' }");
+}
+
+void tst_QQuickAccessible::controlsThatShouldSendObjectShow()
+{
+    QFETCH(QByteArray, qmlSnippet);
+
+    auto clearEvents = qScopeGuard([]{ QTestAccessibility::clearEvents(); });
+    QQmlApplicationEngine engine;
+    engine.loadData(QByteArray(R"(import QtQuick
+import QtQuick.Controls
+Window { visible: true
+)") + qmlSnippet + "}",
+                    QUrl());
+
+    QVERIFY(engine.rootObjects().count() > 0);
+    QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first());
+    QQuickItem *contentItem = window->contentItem();
+    QVERIFY(contentItem);
+    QQuickItem *rootItem = contentItem->childItems().first();
+    QVERIFY(rootItem);
+
+    QAccessibleEvent ev(rootItem, QAccessible::ObjectShow);
+    // Don't use QVERIFY_EVENT, because it gets very noisy when additional events are found
+    QVERIFY(QTestAccessibility::containsEvent(&ev));
+}
+
 QTEST_MAIN(tst_QQuickAccessible)
 
 #include "tst_qquickaccessible.moc"
-- 
GitLab

openSUSE Build Service is sponsored by