diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp index 04fdfe14c3..373d0a71c0 100644 --- a/src/gui/accessible/linux/atspiadaptor.cpp +++ b/src/gui/accessible/linux/atspiadaptor.cpp @@ -167,6 +167,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const " \n" " \n" " \n" + " \n" + " \n" + " \n" " \n" ); @@ -1467,6 +1470,26 @@ void AtSpiAdaptor::registerApplication() delete registry; } +namespace { +QString accessibleIdForAccessible(QAccessibleInterface *accessible) +{ + QString result; + while (accessible) { + if (!result.isEmpty()) + result.prepend(u'.'); + if (auto obj = accessible->object()) { + const QString name = obj->objectName(); + if (!name.isEmpty()) + result.prepend(name); + else + result.prepend(QString::fromUtf8(obj->metaObject()->className())); + } + accessible = accessible->parent(); + } + return result; +} +} // namespace + // Accessible bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection) { @@ -1553,6 +1576,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS children << ref; } connection.send(message.createReply(QVariant::fromValue(children))); + } else if (function == "GetAccessibleId"_L1) { + sendReply(connection, message, + QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface)))); } else { qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path(); return false; diff --git a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp index beb0a0805a..d07258417f 100644 --- a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp +++ b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp @@ -154,6 +154,7 @@ void tst_QAccessibilityLinux::initTestCase() QVERIFY(!address.isEmpty()); m_window = new AccessibleTestWindow(); + m_window->setObjectName("mainWindow"_L1); m_window->show(); QVERIFY(QTest::qWaitForWindowExposed(m_window)); @@ -211,8 +212,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state) void tst_QAccessibilityLinux::testLabel() { QLabel *l = new QLabel(m_window); + l->setObjectName("theObjectName"_L1); l->setText("Hello A11y"); m_window->addWidget(l); + auto a11yEmpty = new QLabel(m_window); + m_window->addWidget(l); // Application QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT)); @@ -224,6 +228,8 @@ void tst_QAccessibilityLinux::testLabel() QCOMPARE(getChildren(labelInterface).count(), 0); QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label")); QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u); + QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(), + "mainWindow.theObjectName"_L1); QCOMPARE(getParent(labelInterface), mainWindow->path()); QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE)); QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY)); @@ -231,7 +237,12 @@ void tst_QAccessibilityLinux::testLabel() l->setText("New text"); QCOMPARE(labelInterface->property("Name").toString(), l->text()); + auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible"); + QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(), + "mainWindow.QLabel"_L1); + m_window->clearChildren(); + delete a11yEmptyInterface; delete labelInterface; }