From 463898f0765b83f6c391f6802a0ee06796f9f6d2 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 5 Nov 2019 12:51:02 +0100 Subject: Respect user-set Accessible.name Check if the user has set Accessible.name before setting it to the control's text/title/etc. Fixes: QTBUG-66583 Change-Id: I8b2c8ab3f8a8ae8e76c8e6a241260b7f90eca254 Reviewed-by: Liang Qi --- src/quicktemplates2/qquickabstractbutton.cpp | 4 ++-- src/quicktemplates2/qquickcombobox.cpp | 6 +++--- src/quicktemplates2/qquickcontrol.cpp | 8 +++++--- src/quicktemplates2/qquickcontrol_p.h | 2 +- src/quicktemplates2/qquickdialog.cpp | 3 +-- src/quicktemplates2/qquickgroupbox.cpp | 4 ++-- src/quicktemplates2/qquicklabel.cpp | 17 +++++++++++++---- src/quicktemplates2/qquicklabel_p_p.h | 1 + src/quicktemplates2/qquickpage.cpp | 4 ++-- src/quicktemplates2/qquickpopup.cpp | 4 ++-- src/quicktemplates2/qquickpopup_p.h | 2 +- src/quicktemplates2/qquickpopupitem.cpp | 25 +++++++++++++++++++++++++ src/quicktemplates2/qquicktooltip.cpp | 4 ++-- 13 files changed, 60 insertions(+), 24 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index e9fc2f36..969ab173 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -1126,7 +1126,7 @@ void QQuickAbstractButton::buttonChange(ButtonChange change) break; case ButtonTextChange: { const QString txt = text(); - setAccessibleName(txt); + maybeSetAccessibleName(txt); #if QT_CONFIG(shortcut) setShortcut(QKeySequence::mnemonic(txt)); #endif @@ -1152,7 +1152,7 @@ void QQuickAbstractButton::accessibilityActiveChanged(bool active) Q_D(QQuickAbstractButton); if (active) { - setAccessibleName(text()); + maybeSetAccessibleName(text()); setAccessibleProperty("pressed", d->pressed); setAccessibleProperty("checked", d->checked); setAccessibleProperty("checkable", d->checkable); diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index ae341192..86150a0f 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -472,7 +472,7 @@ void QQuickComboBoxPrivate::updateCurrentText(bool hasDelegateModelObject) if (currentText != text) { currentText = text; if (!hasDisplayText) - q->setAccessibleName(text); + q->maybeSetAccessibleName(text); emit q->currentTextChanged(); } if (!hasDisplayText && displayText != text) { @@ -1051,7 +1051,7 @@ void QQuickComboBox::setDisplayText(const QString &text) return; d->displayText = text; - setAccessibleName(text); + maybeSetAccessibleName(text); emit displayTextChanged(); } @@ -1970,7 +1970,7 @@ void QQuickComboBox::accessibilityActiveChanged(bool active) QQuickControl::accessibilityActiveChanged(active); if (active) { - setAccessibleName(d->hasDisplayText ? d->displayText : d->currentText); + maybeSetAccessibleName(d->hasDisplayText ? d->displayText : d->currentText); setAccessibleProperty("editable", isEditable()); } } diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index d107fef1..7e249dae 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -2282,11 +2282,13 @@ QString QQuickControl::accessibleName() const return QString(); } -void QQuickControl::setAccessibleName(const QString &name) +void QQuickControl::maybeSetAccessibleName(const QString &name) { #if QT_CONFIG(accessibility) - if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) - accessibleAttached->setName(name); + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) { + if (!accessibleAttached->wasNameExplicitlySet()) + accessibleAttached->setNameImplicitly(name); + } #else Q_UNUSED(name) #endif diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 3fe20f3b..d35630a7 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -287,7 +287,7 @@ protected: // helper functions which avoid to check QT_CONFIG(accessibility) QString accessibleName() const; - void setAccessibleName(const QString &name); + void maybeSetAccessibleName(const QString &name); QVariant accessibleProperty(const char *propertyName); bool setAccessibleProperty(const char *propertyName, const QVariant &value); diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp index 43f6b6a5..a13b42ee 100644 --- a/src/quicktemplates2/qquickdialog.cpp +++ b/src/quicktemplates2/qquickdialog.cpp @@ -219,7 +219,6 @@ void QQuickDialog::setTitle(const QString &title) { Q_D(QQuickDialog); d->popupItem->setTitle(title); - setAccessibleName(title); } /*! @@ -536,7 +535,7 @@ void QQuickDialog::accessibilityActiveChanged(bool active) QQuickPopup::accessibilityActiveChanged(active); if (active) - setAccessibleName(d->popupItem->title()); + maybeSetAccessibleName(d->popupItem->title()); } #endif diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index a5da8a6f..3dbf3174 100644 --- a/src/quicktemplates2/qquickgroupbox.cpp +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -167,7 +167,7 @@ void QQuickGroupBox::setTitle(const QString &title) return; d->title = title; - setAccessibleName(title); + maybeSetAccessibleName(title); emit titleChanged(); } @@ -283,7 +283,7 @@ void QQuickGroupBox::accessibilityActiveChanged(bool active) QQuickFrame::accessibilityActiveChanged(active); if (active) - setAccessibleName(d->title); + maybeSetAccessibleName(d->title); } #endif diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index 29f3538d..9937436c 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -248,9 +248,7 @@ void QQuickLabelPrivate::updatePalette(const QPalette &palette) void QQuickLabelPrivate::textChanged(const QString &text) { #if QT_CONFIG(accessibility) - Q_Q(QQuickLabel); - if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(q)) - accessibleAttached->setName(text); + maybeSetAccessibleName(text); #else Q_UNUSED(text) #endif @@ -266,13 +264,24 @@ void QQuickLabelPrivate::accessibilityActiveChanged(bool active) QQuickAccessibleAttached *accessibleAttached = qobject_cast(qmlAttachedPropertiesObject(q, true)); Q_ASSERT(accessibleAttached); accessibleAttached->setRole(accessibleRole()); - accessibleAttached->setName(text); + maybeSetAccessibleName(text); } QAccessible::Role QQuickLabelPrivate::accessibleRole() const { return QAccessible::StaticText; } + +void QQuickLabelPrivate::maybeSetAccessibleName(const QString &name) +{ + Q_Q(QQuickLabel); + auto accessibleAttached = qobject_cast( + qmlAttachedPropertiesObject(q, true)); + if (accessibleAttached) { + if (!accessibleAttached->wasNameExplicitlySet()) + accessibleAttached->setNameImplicitly(name); + } +} #endif static inline QString backgroundName() { return QStringLiteral("background"); } diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h index e1010698..ce70c168 100644 --- a/src/quicktemplates2/qquicklabel_p_p.h +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -111,6 +111,7 @@ public: #if QT_CONFIG(accessibility) void accessibilityActiveChanged(bool active) override; QAccessible::Role accessibleRole() const override; + void maybeSetAccessibleName(const QString &name); #endif void cancelBackground(); diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 0d2a7e3e..0a72bad7 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -285,7 +285,7 @@ void QQuickPage::setTitle(const QString &title) return; d->title = title; - setAccessibleName(title); + maybeSetAccessibleName(title); emit titleChanged(); } @@ -473,7 +473,7 @@ void QQuickPage::accessibilityActiveChanged(bool active) QQuickPane::accessibilityActiveChanged(active); if (active) - setAccessibleName(d->title); + maybeSetAccessibleName(d->title); } #endif diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 5b945843..ecb2568e 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -2697,10 +2697,10 @@ QString QQuickPopup::accessibleName() const return d->popupItem->accessibleName(); } -void QQuickPopup::setAccessibleName(const QString &name) +void QQuickPopup::maybeSetAccessibleName(const QString &name) { Q_D(QQuickPopup); - d->popupItem->setAccessibleName(name); + d->popupItem->maybeSetAccessibleName(name); } QVariant QQuickPopup::accessibleProperty(const char *propertyName) diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h index 12dbd247..dc3ebf6f 100644 --- a/src/quicktemplates2/qquickpopup_p.h +++ b/src/quicktemplates2/qquickpopup_p.h @@ -459,7 +459,7 @@ protected: #endif QString accessibleName() const; - void setAccessibleName(const QString &name); + void maybeSetAccessibleName(const QString &name); QVariant accessibleProperty(const char *propertyName); bool setAccessibleProperty(const char *propertyName, const QVariant &value); diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index 16d8c4f6..fcf23db5 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -45,6 +45,10 @@ #include #include +#if QT_CONFIG(accessibility) +#include +#endif + QT_BEGIN_NAMESPACE class QQuickPopupItemPrivate : public QQuickPagePrivate @@ -401,7 +405,28 @@ QAccessible::Role QQuickPopupItem::accessibleRole() const void QQuickPopupItem::accessibilityActiveChanged(bool active) { Q_D(const QQuickPopupItem); + // Can't just use d->popup->accessibleName() here, because that refers to the accessible + // name of us, the popup item, which is not what we want. + const QQuickAccessibleAttached *popupAccessibleAttached = QQuickControlPrivate::accessibleAttached(d->popup); + const QString oldPopupName = popupAccessibleAttached ? popupAccessibleAttached->name() : QString(); + const bool wasNameExplicitlySetOnPopup = popupAccessibleAttached && popupAccessibleAttached->wasNameExplicitlySet(); + QQuickPage::accessibilityActiveChanged(active); + + QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this); + const QString ourName = accessibleAttached ? accessibleAttached->name() : QString(); + if (wasNameExplicitlySetOnPopup && accessibleAttached && ourName != oldPopupName) { + // The user set Accessible.name on the Popup. Since the Popup and its popup item + // have different accessible attached properties, the popup item doesn't know that + // a name was set on the Popup by the user, and that it should use that, rather than + // whatever QQuickPage sets. That's why we need to do it here. + // To avoid it being overridden by the call to accessibilityActiveChanged() below, + // we set it explicitly. It's safe to do this as the popup item is an internal implementation detail. + accessibleAttached->setName(oldPopupName); + } + + // This allows the different popup types to set a name on their popup item accordingly. + // For example: Dialog uses its title and ToolTip uses its text. d->popup->accessibilityActiveChanged(active); } #endif diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp index 5c7eb46e..9ea0160e 100644 --- a/src/quicktemplates2/qquicktooltip.cpp +++ b/src/quicktemplates2/qquicktooltip.cpp @@ -188,7 +188,7 @@ void QQuickToolTip::setText(const QString &text) return; d->text = text; - setAccessibleName(text); + maybeSetAccessibleName(text); emit textChanged(); } @@ -351,7 +351,7 @@ void QQuickToolTip::accessibilityActiveChanged(bool active) QQuickPopup::accessibilityActiveChanged(active); if (active) - setAccessibleName(d->text); + maybeSetAccessibleName(d->text); } #endif -- cgit v1.2.3