From bbacf3d79d5067c4f9351400b5c1e0028cd093a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 3 Sep 2014 13:47:42 +0200 Subject: [PATCH] a11y: Don't try to update accessibility if there's no interface Change-Id: I970729e65ba0eb857e6974f9947f27ae8e6410c3 Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.cpp | 15 +++++++---- .../qaccessibility/tst_qaccessibility.cpp | 26 ++++++------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 50f023ec78..1d70598c39 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -861,15 +861,20 @@ void QAccessible::setRootObject(QObject *object) */ void QAccessible::updateAccessibility(QAccessibleEvent *event) { - if (!isActive()) + // NOTE: Querying for the accessibleInterface below will result in + // resolving and caching the interface, which in some cases will + // cache the wrong information as updateAccessibility is called + // during construction of widgets. If you see cases where the + // cache seems wrong, this call is "to blame", but the code that + // caches dynamic data should be updated to handle change events. + if (!isActive() || !event->accessibleInterface()) return; #ifndef QT_NO_ACCESSIBILITY if (event->type() == QAccessible::TableModelChanged) { - if (QAccessibleInterface *iface = event->accessibleInterface()) { - if (iface->tableInterface()) - iface->tableInterface()->modelChange(static_cast(event)); - } + QAccessibleInterface *iface = event->accessibleInterface(); + if (iface && iface->tableInterface()) + iface->tableInterface()->modelChange(static_cast(event)); } if (updateHandler) { diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index ac90f6ea72..653cc6b9d9 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -939,29 +939,19 @@ void tst_QAccessibility::mainWindowTest() window.show(); QTRY_VERIFY(QGuiApplication::focusWindow() == &window); -// We currently don't have an accessible interface for QWindow -// the active state is either in the QMainWindow or QQuickView -// QAccessibleInterface *windowIface(QAccessible::queryAccessibleInterface(&window)); -// QVERIFY(windowIface->state().active); + // We currently don't have an accessible interface for QWindow + // the active state is either in the QMainWindow or QQuickView + QAccessibleInterface *windowIface(QAccessible::queryAccessibleInterface(&window)); + QVERIFY(!windowIface); QAccessible::State activeState; activeState.active = true; + + // We should still not crash if we somehow end up sending state change events + // Note that we do not QVERIFY_EVENT, as that relies on the updateHandler being + // called, which does not happen/make sense when there's no interface for the event. QAccessibleStateChangeEvent active(&window, activeState); - QVERIFY_EVENT(&active); - - QWindow child; - child.setParent(&window); - child.setGeometry(10, 10, 20, 20); - child.show(); - - child.requestActivate(); - QTRY_VERIFY(QGuiApplication::focusWindow() == &child); - QAccessibleStateChangeEvent deactivate(&window, activeState); - QVERIFY_EVENT(&deactivate); // deactivation of parent - - QAccessibleStateChangeEvent activeChild(&child, activeState); - QVERIFY_EVENT(&activeChild); } }