diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2022-08-26 14:51:04 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2022-08-27 03:38:16 +0000 |
commit | 0c0eadc484ab7143801593ccdbe8e96eeb9f6cf7 (patch) | |
tree | c2046c035d0535a0091b1711ccb18f44b7e9ebb7 /tests/auto/other | |
parent | 063344c8b99d046be92fcbc2c631a79c59ad8a6e (diff) |
a11y: Prevent one case of losing a11y interface when setting event child
9a369a25ddfac9352cabde65c8476c7433dc6c3a added a
QAccessibleEvent ctor that takes a QAccessibleInterface*
instead of a QObject*.
Retrieving the QAccessibleInterface* later is done using the
interface's unique ID stored in the m_uniqueId member.
However, the fact that m_uniqueId is a member
of the union alongside with m_child means that setting
a child via QAccessibleEvent::setChild also overwrites
the stored unique ID, which breaks retrieving the accessible
interface later.
Fix this for the case where the QAccessibleInterface has
an associated QObject by assigning m_object in the ctor as well.
This means that a QAccessibleEvent created using either of the two
constructors (the one taking the QObject* and the one taking
the QAccessibleInterface* associated with the object) now behaves
the same.
Fixing the case where there is no associated QObject would require
further changes (e.g. adding a member for the QAccessibleInterface*
or making the m_uniqueId member a separate member instead of having
it in a union with m_child). However, I see no way to do so without
breaking the ABI, so that is left unchanged.
This also adds a corresponding test case.
Fixes: QTBUG-105988
Pick-to: 6.4
Change-Id: I71a548af0277a5034e9e207f066fa3e25c5393f3
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'tests/auto/other')
-rw-r--r-- | tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 89ef57e29b..8479985c0e 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -163,6 +163,7 @@ public slots: void cleanup(); private slots: void eventTest(); + void eventWithChildTest(); void customWidget(); void deletedWidget(); void subclassedWidget(); @@ -353,6 +354,33 @@ void tst_QAccessibility::eventTest() QTestAccessibility::clearEvents(); } +void tst_QAccessibility::eventWithChildTest() +{ + // make sure that QAccessibleEvent created using either of the two QAccessibleEvent + // behaves the same when the same underlying QObject is used + QWidget widget; + QWidget childWidget(&widget); + + // QAccessibleEvent constructor called with the QObject* + QAccessibleEvent event1(&widget, QAccessible::Focus); + + // QAccessibleEvent constructor called with the QAccessibleInterface* for the same QObject* + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&widget); + QAccessibleEvent event2(iface, QAccessible::Focus); + + QVERIFY(event1.accessibleInterface() != nullptr); + QVERIFY(event2.accessibleInterface() != nullptr); + QCOMPARE(event1.accessibleInterface(), event2.accessibleInterface()); + + // set same child for both + event1.setChild(0); + event2.setChild(0); + + QVERIFY(event1.accessibleInterface() != nullptr); + QVERIFY(event2.accessibleInterface() != nullptr); + QCOMPARE(event1.accessibleInterface(), event2.accessibleInterface()); +} + void tst_QAccessibility::customWidget() { { |