A11y: query a11y bus address from X display
Attempt to get the accessibility bus address from the X display, to match libatspi's behavior. This allows the accessibility bus to be found when an application is running as root. [ChangeLog][QtGui] Linux accessibility (using XCB) will now works for applications launched as root Done-with: Mike Gorse Change-Id: I49a263571b328cbd1fd90cb7f5cb40919d2a4951 Task-number: QTBUG-43674 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com> Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>bb10
parent
4dc459837b
commit
d23562da1c
|
|
@ -42,6 +42,9 @@
|
|||
#include <QDBusConnectionInterface>
|
||||
#include "bus_interface.h"
|
||||
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <qplatformnativeinterface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QString A11Y_SERVICE = QStringLiteral("org.a11y.Bus");
|
||||
|
|
@ -65,6 +68,29 @@ DBusConnection::DBusConnection(QObject *parent)
|
|||
// If it is registered already, setup a11y right away
|
||||
if (c.interface()->isServiceRegistered(A11Y_SERVICE))
|
||||
serviceRegistered();
|
||||
|
||||
// In addition try if there is an xatom exposing the bus address, this allows applications run as root to work
|
||||
QString address = getAddressFromXCB();
|
||||
if (!address.isEmpty()) {
|
||||
m_enabled = true;
|
||||
connectA11yBus(address);
|
||||
}
|
||||
}
|
||||
|
||||
QString DBusConnection::getAddressFromXCB()
|
||||
{
|
||||
QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
|
||||
if (!app)
|
||||
return QString();
|
||||
QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();
|
||||
QByteArray *addressByteArray = reinterpret_cast<QByteArray*>(
|
||||
platformNativeInterface->nativeResourceForIntegration(QByteArrayLiteral("AtspiBus")));
|
||||
if (addressByteArray) {
|
||||
QString address = QString::fromLatin1(*addressByteArray);
|
||||
delete addressByteArray;
|
||||
return address;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
// We have the a11y registry on the session bus.
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ Q_SIGNALS:
|
|||
void enabledChanged(bool enabled);
|
||||
|
||||
private Q_SLOTS:
|
||||
QString getAddressFromXCB();
|
||||
void serviceRegistered();
|
||||
void serviceUnregistered();
|
||||
void connectA11yBus(const QString &address);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ static int resourceType(const QByteArray &key)
|
|||
QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"),
|
||||
QByteArrayLiteral("rootwindow"),
|
||||
QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled"),
|
||||
QByteArrayLiteral("nofonthinting")
|
||||
QByteArrayLiteral("nofonthinting"),
|
||||
QByteArrayLiteral("atspibus")
|
||||
};
|
||||
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
|
||||
const QByteArray *result = std::find(names, end, key);
|
||||
|
|
@ -175,6 +176,9 @@ void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resour
|
|||
case Display:
|
||||
result = display();
|
||||
break;
|
||||
case AtspiBus:
|
||||
result = atspiBus();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -402,6 +406,27 @@ void *QXcbNativeInterface::display()
|
|||
#endif
|
||||
}
|
||||
|
||||
void *QXcbNativeInterface::atspiBus()
|
||||
{
|
||||
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||
QXcbConnection *defaultConnection = integration->defaultConnection();
|
||||
if (defaultConnection) {
|
||||
xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS");
|
||||
xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(defaultConnection->xcb_connection(), false,
|
||||
defaultConnection->rootWindow(),
|
||||
atspiBusAtom,
|
||||
XCB_ATOM_STRING, 0, 128));
|
||||
xcb_get_property_reply_t *reply = Q_XCB_CALL(xcb_get_property_reply(defaultConnection->xcb_connection(), cookie, 0));
|
||||
Q_ASSERT(!reply->bytes_after);
|
||||
char *data = (char *)xcb_get_property_value(reply);
|
||||
int length = xcb_get_property_value_length(reply);
|
||||
QByteArray *busAddress = new QByteArray(data, length);
|
||||
free(reply);
|
||||
return busAddress;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time)
|
||||
{
|
||||
static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ public:
|
|||
RootWindow,
|
||||
ScreenSubpixelType,
|
||||
ScreenAntialiasingEnabled,
|
||||
NoFontHinting
|
||||
NoFontHinting,
|
||||
AtspiBus
|
||||
};
|
||||
|
||||
QXcbNativeInterface();
|
||||
|
|
@ -98,6 +99,7 @@ public:
|
|||
void *x11Screen();
|
||||
void *rootWindow();
|
||||
void *display();
|
||||
void *atspiBus();
|
||||
static void setStartupId(const char *);
|
||||
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
|
||||
static void setAppUserTime(QScreen *screen, xcb_timestamp_t time);
|
||||
|
|
|
|||
Loading…
Reference in New Issue