chore: patch qt accessbility
This commit is contained in:
parent
2501e04ccb
commit
9eed94f782
|
@ -51,6 +51,7 @@ let
|
||||||
./qtdeclarative.patch
|
./qtdeclarative.patch
|
||||||
# prevent headaches from stale qmlcache data
|
# prevent headaches from stale qmlcache data
|
||||||
./qtdeclarative-default-disable-qmlcache.patch
|
./qtdeclarative-default-disable-qmlcache.patch
|
||||||
|
./qtdeclarative-accessibility.patch
|
||||||
];
|
];
|
||||||
qtscript = [ ./qtscript.patch ];
|
qtscript = [ ./qtscript.patch ];
|
||||||
qtserialport = [ ./qtserialport.patch ];
|
qtserialport = [ ./qtserialport.patch ];
|
||||||
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
From 3c08d08ae2bbd449cc0579a1b3cb499383c7a60c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Volker Hilsheimer <volker.hilsheimer@qt.io>
|
||||||
|
Date: Tue, 18 Apr 2023 22:05:36 +0200
|
||||||
|
Subject: [PATCH] Accessibility: respect value in attached Accessible in
|
||||||
|
controls
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=utf8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
QQuickItemPrivate::accessibleRole is virtual and called by the framework
|
||||||
|
to determine the role of an item. The default implementation checks and
|
||||||
|
respects a possible Accessible attached object. However, subclasses that
|
||||||
|
override the virtual don't, so the attached properties are ignored, and
|
||||||
|
the class-specific implementation wins. This makes it impossible to
|
||||||
|
change the role of e.g. a checkable button.
|
||||||
|
|
||||||
|
To fix that, move the code respecting the attached object into a non-
|
||||||
|
virtual function that the framework calls instead, and only call the
|
||||||
|
virtual member if there is no attached object, or if that object is not
|
||||||
|
initialized with a role. Replace calls to the virtual from the
|
||||||
|
framework with calls to the non-virtual wrapper.
|
||||||
|
|
||||||
|
Do this for both QQuickItem and for QQuickPopup, and adjust the logic
|
||||||
|
in QQuickControl types that create an attached object and initialize
|
||||||
|
it's role when accessibility becomes active. Use the non-overridable
|
||||||
|
effective role value for that as well.
|
||||||
|
|
||||||
|
Add a test case, and to avoid any new framework calls to the virtual,
|
||||||
|
make it private.
|
||||||
|
|
||||||
|
Fixes: QTBUG-110114
|
||||||
|
Pick-to: 6.5 6.2
|
||||||
|
Change-Id: Ia709cecbd181b6d8ee3297a4af60c1e7db9a2c51
|
||||||
|
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||||
|
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
|
||||||
|
---
|
||||||
|
src/quick/accessible/qaccessiblequickitem.cpp | 2 +-
|
||||||
|
src/quick/items/qquickitem.cpp | 17 +++++++++-----
|
||||||
|
src/quick/items/qquickitem_p.h | 3 +++
|
||||||
|
src/quicktemplates/qquickcontrol.cpp | 3 ++-
|
||||||
|
src/quicktemplates/qquicklabel.cpp | 2 +-
|
||||||
|
src/quicktemplates/qquickpopup.cpp | 14 ++++++++++++
|
||||||
|
src/quicktemplates/qquickpopup_p.h | 3 +++
|
||||||
|
src/quicktemplates/qquickpopupitem.cpp | 2 +-
|
||||||
|
src/quicktemplates/qquicktextarea.cpp | 2 +-
|
||||||
|
src/quicktemplates/qquicktextfield.cpp | 2 +-
|
||||||
|
.../qquickaccessible/tst_qquickaccessible.cpp | 26 ++++++++++++++++++++++
|
||||||
|
11 files changed, 65 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
|
||||||
|
index 4a446e468d5..6f8df29538e 100644
|
||||||
|
--- a/src/quick/accessible/qaccessiblequickitem.cpp
|
||||||
|
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
|
||||||
|
@@ -456,7 +456,7 @@ QAccessible::Role QAccessibleQuickItem::role() const
|
||||||
|
|
||||||
|
QAccessible::Role role = QAccessible::NoRole;
|
||||||
|
if (item())
|
||||||
|
- role = QQuickItemPrivate::get(item())->accessibleRole();
|
||||||
|
+ role = QQuickItemPrivate::get(item())->effectiveAccessibleRole();
|
||||||
|
if (role == QAccessible::NoRole) {
|
||||||
|
if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
|
||||||
|
role = QAccessible::StaticText;
|
||||||
|
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
|
||||||
|
index d53a190b5f1..2e645a918de 100644
|
||||||
|
--- a/src/quick/items/qquickitem.cpp
|
||||||
|
+++ b/src/quick/items/qquickitem.cpp
|
||||||
|
@@ -2376,7 +2376,7 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#if QT_CONFIG(accessibility)
|
||||||
|
- QAccessible::Role role = QQuickItemPrivate::get(item)->accessibleRole();
|
||||||
|
+ QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole();
|
||||||
|
if (role == QAccessible::EditableText || role == QAccessible::Table || role == QAccessible::List) {
|
||||||
|
return true;
|
||||||
|
} else if (role == QAccessible::ComboBox || role == QAccessible::SpinBox) {
|
||||||
|
@@ -9731,13 +9731,20 @@ QQuickItemPrivate::ExtraData::ExtraData()
|
||||||
|
|
||||||
|
|
||||||
|
#if QT_CONFIG(accessibility)
|
||||||
|
-QAccessible::Role QQuickItemPrivate::accessibleRole() const
|
||||||
|
+QAccessible::Role QQuickItemPrivate::effectiveAccessibleRole() const
|
||||||
|
{
|
||||||
|
Q_Q(const QQuickItem);
|
||||||
|
- QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false));
|
||||||
|
- if (accessibleAttached)
|
||||||
|
- return accessibleAttached->role();
|
||||||
|
+ auto *attached = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false);
|
||||||
|
+ auto role = QAccessible::NoRole;
|
||||||
|
+ if (auto *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(attached))
|
||||||
|
+ role = accessibleAttached->role();
|
||||||
|
+ if (role == QAccessible::NoRole)
|
||||||
|
+ role = accessibleRole();
|
||||||
|
+ return role;
|
||||||
|
+}
|
||||||
|
|
||||||
|
+QAccessible::Role QQuickItemPrivate::accessibleRole() const
|
||||||
|
+{
|
||||||
|
return QAccessible::NoRole;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
|
||||||
|
index e1e909d1a26..df6ec900ce8 100644
|
||||||
|
--- a/src/quick/items/qquickitem_p.h
|
||||||
|
+++ b/src/quick/items/qquickitem_p.h
|
||||||
|
@@ -601,7 +601,10 @@ public:
|
||||||
|
virtual void implicitHeightChanged();
|
||||||
|
|
||||||
|
#if QT_CONFIG(accessibility)
|
||||||
|
+ QAccessible::Role effectiveAccessibleRole() const;
|
||||||
|
+private:
|
||||||
|
virtual QAccessible::Role accessibleRole() const;
|
||||||
|
+public:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setImplicitAntialiasing(bool antialiasing);
|
||||||
|
diff --git a/src/quicktemplates/qquickcontrol.cpp b/src/quicktemplates/qquickcontrol.cpp
|
||||||
|
index ace34c9d638..7af4b295230 100644
|
||||||
|
--- a/src/quicktemplates/qquickcontrol.cpp
|
||||||
|
+++ b/src/quicktemplates/qquickcontrol.cpp
|
||||||
|
@@ -2185,12 +2185,13 @@ QAccessible::Role QQuickControl::accessibleRole() const
|
||||||
|
|
||||||
|
void QQuickControl::accessibilityActiveChanged(bool active)
|
||||||
|
{
|
||||||
|
+ Q_D(QQuickControl);
|
||||||
|
if (!active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true));
|
||||||
|
Q_ASSERT(accessibleAttached);
|
||||||
|
- accessibleAttached->setRole(accessibleRole());
|
||||||
|
+ accessibleAttached->setRole(d->effectiveAccessibleRole());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/src/quicktemplates/qquicklabel.cpp b/src/quicktemplates/qquicklabel.cpp
|
||||||
|
index 39ad6b88c31..ee8723d755b 100644
|
||||||
|
--- a/src/quicktemplates/qquicklabel.cpp
|
||||||
|
+++ b/src/quicktemplates/qquicklabel.cpp
|
||||||
|
@@ -190,7 +190,7 @@ void QQuickLabelPrivate::accessibilityActiveChanged(bool active)
|
||||||
|
Q_Q(QQuickLabel);
|
||||||
|
QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
|
||||||
|
Q_ASSERT(accessibleAttached);
|
||||||
|
- accessibleAttached->setRole(accessibleRole());
|
||||||
|
+ accessibleAttached->setRole(effectiveAccessibleRole());
|
||||||
|
maybeSetAccessibleName(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/quicktemplates/qquickpopup.cpp b/src/quicktemplates/qquickpopup.cpp
|
||||||
|
index 5b267899517..63999c23a55 100644
|
||||||
|
--- a/src/quicktemplates/qquickpopup.cpp
|
||||||
|
+++ b/src/quicktemplates/qquickpopup.cpp
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include <QtCore/qloggingcategory.h>
|
||||||
|
#include <QtQml/qqmlinfo.h>
|
||||||
|
#include <QtQuick/qquickitem.h>
|
||||||
|
+#include <QtQuick/private/qquickaccessibleattached_p.h>
|
||||||
|
#include <QtQuick/private/qquicktransition_p.h>
|
||||||
|
#include <QtQuick/private/qquickitem_p.h>
|
||||||
|
|
||||||
|
@@ -2769,6 +2770,19 @@ QFont QQuickPopup::defaultFont() const
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_CONFIG(accessibility)
|
||||||
|
+QAccessible::Role QQuickPopup::effectiveAccessibleRole() const
|
||||||
|
+{
|
||||||
|
+ auto *attached = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, false);
|
||||||
|
+
|
||||||
|
+ auto role = QAccessible::NoRole;
|
||||||
|
+ if (auto *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(attached))
|
||||||
|
+ role = accessibleAttached->role();
|
||||||
|
+ if (role == QAccessible::NoRole)
|
||||||
|
+ role = accessibleRole();
|
||||||
|
+
|
||||||
|
+ return role;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
QAccessible::Role QQuickPopup::accessibleRole() const
|
||||||
|
{
|
||||||
|
return QAccessible::Dialog;
|
||||||
|
diff --git a/src/quicktemplates/qquickpopup_p.h b/src/quicktemplates/qquickpopup_p.h
|
||||||
|
index ee9003d6272..7552b549bdd 100644
|
||||||
|
--- a/src/quicktemplates/qquickpopup_p.h
|
||||||
|
+++ b/src/quicktemplates/qquickpopup_p.h
|
||||||
|
@@ -419,7 +419,10 @@ protected:
|
||||||
|
virtual QFont defaultFont() const;
|
||||||
|
|
||||||
|
#if QT_CONFIG(accessibility)
|
||||||
|
+ QAccessible::Role effectiveAccessibleRole() const;
|
||||||
|
+private:
|
||||||
|
virtual QAccessible::Role accessibleRole() const;
|
||||||
|
+protected:
|
||||||
|
virtual void accessibilityActiveChanged(bool active);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/src/quicktemplates/qquickpopupitem.cpp b/src/quicktemplates/qquickpopupitem.cpp
|
||||||
|
index 43fc1bdc507..6a494626d4f 100644
|
||||||
|
--- a/src/quicktemplates/qquickpopupitem.cpp
|
||||||
|
+++ b/src/quicktemplates/qquickpopupitem.cpp
|
||||||
|
@@ -308,7 +308,7 @@ QFont QQuickPopupItem::defaultFont() const
|
||||||
|
QAccessible::Role QQuickPopupItem::accessibleRole() const
|
||||||
|
{
|
||||||
|
Q_D(const QQuickPopupItem);
|
||||||
|
- return d->popup->accessibleRole();
|
||||||
|
+ return d->popup->effectiveAccessibleRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QQuickPopupItem::accessibilityActiveChanged(bool active)
|
||||||
|
diff --git a/src/quicktemplates/qquicktextarea.cpp b/src/quicktemplates/qquicktextarea.cpp
|
||||||
|
index f16b88c07f5..dd4a908f5ad 100644
|
||||||
|
--- a/src/quicktemplates/qquicktextarea.cpp
|
||||||
|
+++ b/src/quicktemplates/qquicktextarea.cpp
|
||||||
|
@@ -438,7 +438,7 @@ void QQuickTextAreaPrivate::accessibilityActiveChanged(bool active)
|
||||||
|
Q_Q(QQuickTextArea);
|
||||||
|
QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
|
||||||
|
Q_ASSERT(accessibleAttached);
|
||||||
|
- accessibleAttached->setRole(accessibleRole());
|
||||||
|
+ accessibleAttached->setRole(effectiveAccessibleRole());
|
||||||
|
accessibleAttached->set_readOnly(q->isReadOnly());
|
||||||
|
accessibleAttached->setDescription(placeholder);
|
||||||
|
}
|
||||||
|
diff --git a/src/quicktemplates/qquicktextfield.cpp b/src/quicktemplates/qquicktextfield.cpp
|
||||||
|
index 15a6276465a..b7c2e032658 100644
|
||||||
|
--- a/src/quicktemplates/qquicktextfield.cpp
|
||||||
|
+++ b/src/quicktemplates/qquicktextfield.cpp
|
||||||
|
@@ -288,7 +288,7 @@ void QQuickTextFieldPrivate::accessibilityActiveChanged(bool active)
|
||||||
|
Q_Q(QQuickTextField);
|
||||||
|
QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true));
|
||||||
|
Q_ASSERT(accessibleAttached);
|
||||||
|
- accessibleAttached->setRole(accessibleRole());
|
||||||
|
+ accessibleAttached->setRole(effectiveAccessibleRole());
|
||||||
|
accessibleAttached->set_readOnly(m_readOnly);
|
||||||
|
accessibleAttached->set_passwordEdit((m_echoMode == QQuickTextField::Password || m_echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
|
||||||
|
accessibleAttached->setDescription(placeholder);
|
||||||
|
diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
|
||||||
|
index e7da38a5ceb..f51e7e87106 100644
|
||||||
|
--- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
|
||||||
|
+++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
|
||||||
|
@@ -56,6 +56,7 @@ private slots:
|
||||||
|
void commonTests();
|
||||||
|
|
||||||
|
void quickAttachedProperties();
|
||||||
|
+ void attachedWins();
|
||||||
|
void basicPropertiesTest();
|
||||||
|
void hitTest();
|
||||||
|
void checkableTest();
|
||||||
|
@@ -322,6 +323,31 @@ void tst_QQuickAccessible::quickAttachedProperties()
|
||||||
|
QTestAccessibility::clearEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Verify that a role can be explicitly set, and that the values from the
|
||||||
|
+// attached object are used even if the item has a default role - QTBUG-110114
|
||||||
|
+void tst_QQuickAccessible::attachedWins()
|
||||||
|
+{
|
||||||
|
+ QQmlEngine engine;
|
||||||
|
+ QQmlComponent component(&engine);
|
||||||
|
+ component.setData(R"(
|
||||||
|
+ import QtQuick
|
||||||
|
+ import QtQuick.Controls
|
||||||
|
+ Button {
|
||||||
|
+ text: "Button"
|
||||||
|
+ objectName: "button"
|
||||||
|
+ Accessible.role: Accessible.RadioButton
|
||||||
|
+ Accessible.description: "Radio Button"
|
||||||
|
+ })", QUrl());
|
||||||
|
+ auto button = std::unique_ptr<QObject>(component.create());
|
||||||
|
+ QVERIFY(button);
|
||||||
|
+
|
||||||
|
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(button.get());
|
||||||
|
+ QVERIFY(iface);
|
||||||
|
+
|
||||||
|
+ QCOMPARE(iface->role(), QAccessible::RadioButton);
|
||||||
|
+ QTestAccessibility::clearEvents();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
|
void tst_QQuickAccessible::basicPropertiesTest()
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.16.3
|
Loading…
Reference in New Issue