Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
dbusconnection.cpp
Go to the documentation of this file.
1
// Copyright (C) 2022 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
5
6
#
include
"dbusconnection_p.h"
7
8
#
include
<
QtDBus
/
QDBusMessage
>
9
#
include
<
QtDBus
/
QDBusServiceWatcher
>
10
#
include
<
qdebug
.
h
>
11
12
#
include
<
QDBusConnectionInterface
>
13
14
#
include
<
QtGui
/
qguiapplication
.
h
>
15
#
include
<
qpa
/
qplatformnativeinterface
.
h
>
16
17
QT_BEGIN_NAMESPACE
18
19
using
namespace
Qt::StringLiterals;
20
using
namespace
QtGuiPrivate;
// for D-Bus accessibility wrappers
21
22
/* note: do not change these to QStringLiteral;
23
we are unloaded before QtDBus is done using the strings.
24
*/
25
#
define
A11Y_SERVICE
"org.a11y.Bus"_L1
26
#
define
A11Y_PATH
"/org/a11y/bus"_L1
27
28
/*!
29
\class QAtSpiDBusConnection
30
\internal
31
\brief Connects to the accessibility dbus.
32
33
This is usually a different bus from the session bus.
34
*/
35
QAtSpiDBusConnection
::QAtSpiDBusConnection(QObject *parent)
36
: QObject(parent), m_a11yConnection(QString()), m_enabled(
false
)
37
{
38
// If the bus is explicitly set via env var it overrides everything else.
39
QByteArray addressEnv = qgetenv(
"AT_SPI_BUS_ADDRESS"
);
40
if
(!addressEnv.isEmpty()) {
41
m_enabled =
true
;
42
connectA11yBus(QString::fromLocal8Bit(addressEnv));
43
return
;
44
}
45
46
// Start monitoring if "org.a11y.Bus" is registered as DBus service.
47
QDBusConnection c = QDBusConnection::sessionBus();
48
if
(!c.isConnected()) {
49
return
;
50
}
51
52
m_a11yStatus =
new
OrgA11yStatusInterface(
A11Y_SERVICE
,
A11Y_PATH
, c,
this
);
53
m_dbusProperties =
new
OrgFreedesktopDBusPropertiesInterface(
A11Y_SERVICE
,
A11Y_PATH
, c,
this
);
54
55
dbusWatcher =
new
QDBusServiceWatcher(
A11Y_SERVICE
, c, QDBusServiceWatcher::WatchForRegistration,
this
);
56
connect(dbusWatcher, &QDBusServiceWatcher::serviceRegistered,
57
this
, &
QAtSpiDBusConnection
::checkEnabledState);
58
59
// If it is registered already, setup a11y right away
60
if
(c.interface()->isServiceRegistered(
A11Y_SERVICE
))
61
checkEnabledState();
62
63
// Subscribe to updates about a11y enabled state.
64
connect(m_dbusProperties, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged,
65
this
, [
this
](
const
QString &interface_name) {
66
if
(interface_name == QLatin1StringView(OrgA11yStatusInterface::staticInterfaceName()))
67
checkEnabledState();
68
});
69
70
if
(QGuiApplication::platformName().startsWith(
"xcb"_L1
)) {
71
// In addition try if there is an xatom exposing the bus address, this allows applications run as root to work
72
QString address = getAddressFromXCB();
73
if
(!address.isEmpty()) {
74
m_enabled =
true
;
75
connectA11yBus(address);
76
}
77
}
78
}
79
80
QString
QAtSpiDBusConnection
::getAddressFromXCB()
81
{
82
QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
83
if
(!app)
84
return
QString();
85
QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();
86
QByteArray *addressByteArray =
reinterpret_cast
<QByteArray*>(
87
platformNativeInterface->nativeResourceForIntegration(QByteArrayLiteral(
"AtspiBus"
)));
88
if
(addressByteArray) {
89
QString address = QString::fromLatin1(*addressByteArray);
90
delete
addressByteArray;
91
return
address;
92
}
93
return
QString();
94
}
95
96
void
QAtSpiDBusConnection
::checkEnabledState()
97
{
98
//The variable was introduced because on some embedded platforms there are custom accessibility
99
//clients which don't set Status.ScreenReaderEnabled to true. The variable is also useful for
100
//debugging.
101
static
const
bool
a11yAlwaysOn = qEnvironmentVariableIsSet(
"QT_LINUX_ACCESSIBILITY_ALWAYS_ON"
);
102
103
bool
enabled = a11yAlwaysOn || m_a11yStatus->screenReaderEnabled() || m_a11yStatus->isEnabled();
104
105
if
(enabled != m_enabled) {
106
m_enabled = enabled;
107
if
(m_a11yConnection.isConnected()) {
108
emit enabledChanged(m_enabled);
109
}
else
{
110
QDBusConnection c = QDBusConnection::sessionBus();
111
QDBusMessage m = QDBusMessage::createMethodCall(
A11Y_SERVICE
,
A11Y_PATH
,
A11Y_SERVICE
,
112
"GetAddress"_L1
);
113
c.callWithCallback(m,
this
, SLOT(connectA11yBus(QString)), SLOT(dbusError(QDBusError)));
114
}
115
}
116
}
117
118
void
QAtSpiDBusConnection
::serviceUnregistered()
119
{
120
emit enabledChanged(
false
);
121
}
122
123
void
QAtSpiDBusConnection
::connectA11yBus(
const
QString &address)
124
{
125
if
(address.isEmpty()) {
126
qWarning(
"Could not find Accessibility DBus address."
);
127
return
;
128
}
129
m_a11yConnection = QDBusConnection(QDBusConnection::connectToBus(address,
"a11y"_L1
));
130
131
if
(m_enabled)
132
emit enabledChanged(
true
);
133
}
134
135
void
QAtSpiDBusConnection
::dbusError(
const
QDBusError &error)
136
{
137
qWarning() <<
"Accessibility encountered a DBus error:"
<< error;
138
}
139
140
/*!
141
Returns the DBus connection that got established.
142
Or an invalid connection if not yet connected.
143
*/
144
QDBusConnection
QAtSpiDBusConnection
::
connection
()
const
145
{
146
return
m_a11yConnection;
147
}
148
149
QT_END_NAMESPACE
150
151
#
include
"moc_dbusconnection_p.cpp"
QAtSpiDBusConnection
Connects to the accessibility dbus.
Definition
dbusconnection_p.h:34
QAtSpiDBusConnection::connection
QDBusConnection connection() const
Returns the DBus connection that got established.
Definition
dbusconnection.cpp:144
A11Y_PATH
#define A11Y_PATH
Definition
dbusconnection.cpp:26
A11Y_SERVICE
#define A11Y_SERVICE
Definition
dbusconnection.cpp:25
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtbase
src
gui
accessible
linux
dbusconnection.cpp
Generated on
for Qt by
1.18.0