diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 510931b4760..87b29d8662c 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -688,6 +688,11 @@ void QAccessible::installActivationObserver(QAccessible::ActivationObserver *obs if (qAccessibleActivationObservers()->contains(observer)) return; qAccessibleActivationObservers()->append(observer); + + // Make sure the newly added observer gets a callback on the next + // QPlatformAccessibility::setActive() callback + if (QPlatformAccessibility *pfAccessibility = platformAccessibility()) + pfAccessibility->clearActiveNotificationState(); } /*! @@ -701,6 +706,17 @@ void QAccessible::removeActivationObserver(ActivationObserver *observer) qAccessibleActivationObservers()->removeAll(observer); } +/*! + \internal + + Sends accessibility activation notifications to all registered observers. +*/ +void qAccessibleNotifyActivationObservers(bool active) +{ + for (int i = 0; i < qAccessibleActivationObservers()->size(); ++i) + qAccessibleActivationObservers()->at(i)->accessibilityActiveChanged(active); +} + /*! If a QAccessibleInterface implementation exists for the given \a object, this function returns a pointer to the implementation; otherwise it @@ -870,11 +886,10 @@ bool QAccessible::isActive() */ void QAccessible::setActive(bool active) { - for (int i = 0; i < qAccessibleActivationObservers()->size() ;++i) - qAccessibleActivationObservers()->at(i)->accessibilityActiveChanged(active); + if (QPlatformAccessibility *pfAccessibility = platformAccessibility()) + pfAccessibility->setActive(active); } - /*! Sets the root object of the accessible objects of this application to \a object. All other accessible objects are reachable using object diff --git a/src/gui/accessible/qplatformaccessibility.cpp b/src/gui/accessible/qplatformaccessibility.cpp index ae7635ff7c9..4dd32a911c7 100644 --- a/src/gui/accessible/qplatformaccessibility.cpp +++ b/src/gui/accessible/qplatformaccessibility.cpp @@ -35,7 +35,6 @@ Q_GLOBAL_STATIC(QList, bridges) \sa QAccessible */ QPlatformAccessibility::QPlatformAccessibility() - : m_active(false) { } @@ -99,10 +98,25 @@ void QPlatformAccessibility::cleanup() qDeleteAll(*bridges()); } +void qAccessibleNotifyActivationObservers(bool active); // qaccessible.cpp + void QPlatformAccessibility::setActive(bool active) { m_active = active; - QAccessible::setActive(active); + + // Send activeChanged notifications if the new active status differs from + // the notifed one. + if ((active && m_activeNotificationState != std::optional{true}) || + (!active && m_activeNotificationState != std::optional{false})) { + qAccessibleNotifyActivationObservers(active); + } + + m_activeNotificationState = active; +} + +void QPlatformAccessibility::clearActiveNotificationState() +{ + m_activeNotificationState = std::nullopt; } #endif // QT_CONFIG(accessibility) diff --git a/src/gui/accessible/qplatformaccessibility.h b/src/gui/accessible/qplatformaccessibility.h index 004fcfb40fc..d262c2f6585 100644 --- a/src/gui/accessible/qplatformaccessibility.h +++ b/src/gui/accessible/qplatformaccessibility.h @@ -19,6 +19,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE @@ -35,9 +37,11 @@ public: inline bool isActive() const { return m_active; } void setActive(bool active); + void clearActiveNotificationState(); private: - bool m_active; + bool m_active = false; + std::optional m_activeNotificationState = std::nullopt; }; QT_END_NAMESPACE