diff options
author | Michael Weghorn <[email protected]> | 2025-06-17 11:20:51 +0200 |
---|---|---|
committer | Michael Weghorn <[email protected]> | 2025-06-25 17:36:59 +0200 |
commit | db2792dd8609ab5ff4f3151e15036de7ffd538e9 (patch) | |
tree | 0032a6d4a5cf71b492e4c318b09df094e40d7953 | |
parent | bf869c72b353c00a7ed4d2d1bf0e2f668312b19a (diff) |
When setting the accessible name for a QQuickAbstractButton,
don't include the ampersand ('&') character that denotes the
mnemonic character, and don't escape literal ampersand characters
by doubling them.
Use the same helper function also used by widgets in qtbase
to strip those extra ampersand characters.
Add a corresponding test.
Fixes: QTBUG-134208
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I0da58564ef028cda3c1cc1cecbaacbb4e9d92c17
Reviewed-by: Volker Hilsheimer <[email protected]>
5 files changed, 78 insertions, 2 deletions
diff --git a/src/quicktemplates/qquickabstractbutton.cpp b/src/quicktemplates/qquickabstractbutton.cpp index b8061b43b9..13af8cb47d 100644 --- a/src/quicktemplates/qquickabstractbutton.cpp +++ b/src/quicktemplates/qquickabstractbutton.cpp @@ -15,6 +15,9 @@ #if QT_CONFIG(shortcut) # include <QtGui/private/qshortcutmap_p.h> #endif +#if QT_CONFIG(accessibility) +#include <QtGui/private/qaccessiblehelper_p.h> +#endif #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformtheme.h> #include <QtQuick/private/qquickevents_p_p.h> @@ -1291,7 +1294,9 @@ void QQuickAbstractButton::buttonChange(ButtonChange change) break; case ButtonTextChange: { const QString txt = text(); - maybeSetAccessibleName(txt); +#if QT_CONFIG(accessibility) + maybeSetAccessibleName(qt_accStripAmp(txt)); +#endif #if QT_CONFIG(shortcut) setShortcut(QKeySequence::mnemonic(txt)); #endif @@ -1330,7 +1335,7 @@ void QQuickAbstractButton::accessibilityActiveChanged(bool active) Q_D(QQuickAbstractButton); if (active) { - maybeSetAccessibleName(text()); + maybeSetAccessibleName(qt_accStripAmp(text())); setAccessibleProperty("pressed", d->pressed); setAccessibleProperty("checked", d->checked); setAccessibleProperty("checkable", d->checkable); diff --git a/tests/auto/quickcontrols/accessibility/data/accessibleName/button.qml b/tests/auto/quickcontrols/accessibility/data/accessibleName/button.qml new file mode 100644 index 0000000000..c985e72b78 --- /dev/null +++ b/tests/auto/quickcontrols/accessibility/data/accessibleName/button.qml @@ -0,0 +1,10 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls + +Button { + text: "Hello world" + id: button +} diff --git a/tests/auto/quickcontrols/accessibility/data/accessibleName/button2.qml b/tests/auto/quickcontrols/accessibility/data/accessibleName/button2.qml new file mode 100644 index 0000000000..5f1ceabea2 --- /dev/null +++ b/tests/auto/quickcontrols/accessibility/data/accessibleName/button2.qml @@ -0,0 +1,10 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls + +Button { + text: "Th&is && that" + id: button +} diff --git a/tests/auto/quickcontrols/accessibility/data/accessibleName/button3.qml b/tests/auto/quickcontrols/accessibility/data/accessibleName/button3.qml new file mode 100644 index 0000000000..d41d2ee1eb --- /dev/null +++ b/tests/auto/quickcontrols/accessibility/data/accessibleName/button3.qml @@ -0,0 +1,11 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls + +Button { + text: "Hello world" + Accessible.name: "Explicitly set accessible name" + id: button +} diff --git a/tests/auto/quickcontrols/accessibility/tst_accessibility.cpp b/tests/auto/quickcontrols/accessibility/tst_accessibility.cpp index fa1fdef007..4f4a486919 100644 --- a/tests/auto/quickcontrols/accessibility/tst_accessibility.cpp +++ b/tests/auto/quickcontrols/accessibility/tst_accessibility.cpp @@ -37,6 +37,7 @@ private slots: void sliderTest(); + void accessibleName(); void locale(); private: @@ -389,6 +390,45 @@ void tst_accessibility::sliderTest() #endif } +void tst_accessibility::accessibleName() +{ +#if QT_CONFIG(accessibility) + if (!QAccessible::isActive()) { + QPlatformAccessibility *accessibility = platformAccessibility(); + if (!accessibility) + QSKIP("No QPlatformAccessibility available."); + accessibility->setActive(true); + } + + QQmlComponent component(&engine); + + // verify that accessible name matches the button text if none was set explicitly + component.loadUrl(testFileUrl("accessibleName/button.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + QAccessibleInterface *buttonAcc = QAccessible::queryAccessibleInterface(object.get()); + QVERIFY(buttonAcc); + QCOMPARE(buttonAcc->text(QAccessible::Name), "Hello world"); + + // verify that ampersand ('&') for mnemonic and to escape literal ampersand in button + // text are not contained in accessible name + component.loadUrl(testFileUrl("accessibleName/button2.qml")); + QScopedPointer<QObject> object2(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + QAccessibleInterface *button2Acc = QAccessible::queryAccessibleInterface(object2.get()); + QVERIFY(button2Acc); + QCOMPARE(button2Acc->text(QAccessible::Name), "This & that"); + + // verify that explicitly set accesible name is used + component.loadUrl(testFileUrl("accessibleName/button3.qml")); + QScopedPointer<QObject> object3(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + QAccessibleInterface *button3Acc = QAccessible::queryAccessibleInterface(object3.get()); + QVERIFY(button3Acc); + QCOMPARE(button3Acc->text(QAccessible::Name), "Explicitly set accessible name"); +#endif +} + void tst_accessibility::locale() { #if QT_CONFIG(accessibility) |