From bf9bdf5328172db65aafaee74d8fb9cbeaa9cc16 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 11 Jan 2012 16:31:35 +0100 Subject: Use events for accessibility updates. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The problem with the old updates is that it was impossible to send details about the update. For the Linux implementation to work properly with AT-SPI I need to know which state changed (currently I only get a generic "state changed" event) or which part of the text was changed for long texts (imagine a word processor sending updates). This also gives us more options when updating with events generated from not QObject based objects. Change-Id: If0b6c83c523092565eb48e79f3f6de5a1b905ea8 Reviewed-by: Jan-Arve Sæther --- src/gui/accessible/qaccessible.cpp | 70 +++++++++++++++++++---- src/gui/accessible/qaccessible.h | 28 ++++++++- src/gui/accessible/qaccessiblebridge.h | 3 +- src/gui/accessible/qplatformaccessibility_qpa.cpp | 24 ++------ src/gui/accessible/qplatformaccessibility_qpa.h | 2 +- 5 files changed, 93 insertions(+), 34 deletions(-) (limited to 'src/gui/accessible') diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index b9f80c3071..8610ef726d 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -654,13 +654,29 @@ void QAccessible::setRootObject(QObject *object) } /*! - Notifies accessibility clients about a change in \a object's - accessibility information. + \deprecated - \a reason specifies the cause of the change, for example, - \c ValueChange when the position of a slider has been changed. \a - child is the (1-based) index of the child element that has changed. - When \a child is 0, the object itself has changed. + Use the version with a single \l QAccessibleEvent paremeter instead. +*/ +void QAccessible::updateAccessibility(QObject *object, int child, Event reason) +{ + Q_ASSERT(object); + + qWarning("QAccessible::updateAccessibility is deprecated."); + + QAccessibleEvent event = QAccessibleEvent(reason, object, child); + updateAccessibility(event); +} + +/*! + Notifies about a change that might be relevant for accessibility clients. + + \a event gives the details about the change. + This includes the source of the change and what the actual change is. + There should be sufficient details delivered with this event to give meaningful notifications. + + For example, the type \c ValueChange indicates that the position of + a slider has been changed. Call this function whenever the state of your accessible object or one of its sub-elements has been changed either programmatically @@ -671,12 +687,10 @@ void QAccessible::setRootObject(QObject *object) the parameters of the call is expensive you can test isActive() to avoid unnecessary computations. */ -void QAccessible::updateAccessibility(QObject *object, int child, Event reason) +void QAccessible::updateAccessibility(const QAccessibleEvent &event) { - Q_ASSERT(object); - if (updateHandler) { - updateHandler(object, child, reason); + updateHandler(event); return; } @@ -684,9 +698,43 @@ void QAccessible::updateAccessibility(QObject *object, int child, Event reason) return; if (QPlatformAccessibility *pfAccessibility = platformAccessibility()) - pfAccessibility->notifyAccessibilityUpdate(object, child, reason); + pfAccessibility->notifyAccessibilityUpdate(event); } +/*! + \class QAccessibleEvent + \brief The QAccessibleEvent is use to notify about changes that are + relevant for accessibility in the application. + + \ingroup accessibility + \inmodule QtGui + + This class should be created on the stack and used as parameter for + \l QAccessible::updateAccessibility(). +*/ + +/*! + Returns the QAccessibleInterface associated with the event. + + The caller of this function takes ownership of the returned interface. +*/ +QAccessibleInterface *QAccessibleEvent::accessibleInterface() const +{ + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object); + if (!iface) + return 0; + + if (m_child >= 0) { + QAccessibleInterface *child = iface->child(m_child); + if (child) { + delete iface; + iface = child; + } else { + qWarning() << "Cannot creat accessible child interface for object: " << m_object << " index: " << m_child; + } + } + return iface; +} /*! \class QAccessibleInterface diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 6726172cac..dc74ac1814 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY class QAccessibleInterface; +class QAccessibleEvent; class QWindow; // We need to inherit QObject to expose the enums to QML. @@ -326,7 +327,7 @@ public: }; typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*); - typedef void(*UpdateHandler)(QObject*, int who, Event reason); + typedef void(*UpdateHandler)(const QAccessibleEvent &event); typedef void(*RootObjectHandler)(QObject*); static void installFactory(InterfaceFactory); @@ -335,7 +336,10 @@ public: static RootObjectHandler installRootObjectHandler(RootObjectHandler); static QAccessibleInterface *queryAccessibleInterface(QObject *); + static void updateAccessibility(QObject *object, int child, Event reason); + static void updateAccessibility(const QAccessibleEvent &event); + static bool isActive(); static void setRootObject(QObject *object); @@ -425,6 +429,28 @@ public: private: }; +class Q_GUI_EXPORT QAccessibleEvent +{ +public: + inline QAccessibleEvent(QAccessible::Event type, QObject *object, int child = -1) + : m_type(type), m_object(object), m_child(child) + { + Q_ASSERT(object); + } + + QAccessible::Event type() const { return m_type; } + QObject *object() const { return m_object; } + int child() const { return m_child; } + + QAccessibleInterface *accessibleInterface() const; + +private: + QAccessible::Event m_type; + QObject *m_object; + int m_child; +}; + + #define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface" Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid) diff --git a/src/gui/accessible/qaccessiblebridge.h b/src/gui/accessible/qaccessiblebridge.h index 3880f6291f..147bf30bd0 100644 --- a/src/gui/accessible/qaccessiblebridge.h +++ b/src/gui/accessible/qaccessiblebridge.h @@ -53,13 +53,14 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY class QAccessibleInterface; +class QAccessibleEvent; class QAccessibleBridge { public: virtual ~QAccessibleBridge() {} virtual void setRootObject(QAccessibleInterface *) = 0; - virtual void notifyAccessibilityUpdate(int, QAccessibleInterface*, int) = 0; + virtual void notifyAccessibilityUpdate(const QAccessibleEvent &event) = 0; }; struct Q_GUI_EXPORT QAccessibleBridgeFactoryInterface : public QFactoryInterface diff --git a/src/gui/accessible/qplatformaccessibility_qpa.cpp b/src/gui/accessible/qplatformaccessibility_qpa.cpp index bebef5cde5..9de11e7c1f 100644 --- a/src/gui/accessible/qplatformaccessibility_qpa.cpp +++ b/src/gui/accessible/qplatformaccessibility_qpa.cpp @@ -45,6 +45,8 @@ #include "qaccessiblebridge.h" #include +#include + QT_BEGIN_NAMESPACE /* accessiblebridge plugin discovery stuff */ @@ -73,33 +75,15 @@ QPlatformAccessibility::~QPlatformAccessibility() { } -void QPlatformAccessibility::notifyAccessibilityUpdate(QObject *o, - int who, - QAccessible::Event reason) +void QPlatformAccessibility::notifyAccessibilityUpdate(const QAccessibleEvent &event) { initialize(); if (!bridges() || bridges()->isEmpty()) return; - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(o); - if (!iface) - return; - - // updates for List/Table/Tree should send child - if (who) { - QAccessibleInterface *child = iface->child(who - 1); - if (child) { - delete iface; - iface = child; - who = 0; - } - } - for (int i = 0; i < bridges()->count(); ++i) - bridges()->at(i)->notifyAccessibilityUpdate(reason, iface, who); - delete iface; - + bridges()->at(i)->notifyAccessibilityUpdate(event); } void QPlatformAccessibility::setRootObject(QObject *o) diff --git a/src/gui/accessible/qplatformaccessibility_qpa.h b/src/gui/accessible/qplatformaccessibility_qpa.h index 22bb6651b1..364f87b0c9 100644 --- a/src/gui/accessible/qplatformaccessibility_qpa.h +++ b/src/gui/accessible/qplatformaccessibility_qpa.h @@ -57,7 +57,7 @@ public: QPlatformAccessibility(); virtual ~QPlatformAccessibility(); - virtual void notifyAccessibilityUpdate(QObject *o, int who, QAccessible::Event reason); + virtual void notifyAccessibilityUpdate(const QAccessibleEvent &event); virtual void setRootObject(QObject *o); virtual void initialize(); virtual void cleanup(); -- cgit v1.2.3