Warning, file /libraries/libqaccessibilityclient/src/qaccessibilityclient/registry_p.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2012 Frederik Gladhorn <gladhorn@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "registry_p.h" 0008 #include "registry.h" 0009 0010 #include <QDBusMessage> 0011 #include <QDBusArgument> 0012 #include <QDBusReply> 0013 #include <QDBusPendingCall> 0014 #include <QDBusInterface> 0015 #include <QDBusArgument> 0016 #include <QDBusMetaType> 0017 0018 #include <QDebug> 0019 #include <QDBusMessage> 0020 #include <QStringList> 0021 #include <qurl.h> 0022 0023 #include "atspi/atspi-constants.h" 0024 0025 #include <QString> 0026 #include <QHash> 0027 0028 // interface names from at-spi2-core/atspi/atspi-misc-private.h 0029 #define ATSPI_DBUS_NAME_REGISTRY "org.a11y.atspi.Registry" 0030 #define ATSPI_DBUS_PATH_REGISTRY "/org/a11y/atspi/registry" 0031 #define ATSPI_DBUS_INTERFACE_REGISTRY "org.a11y.atspi.Registry" 0032 0033 #define ATSPI_DBUS_PATH_NULL "/org/a11y/atspi/null" 0034 #define ATSPI_DBUS_PATH_ROOT "/org/a11y/atspi/accessible/root" 0035 0036 #define ATSPI_DBUS_PATH_DEC "/org/a11y/atspi/registry/deviceeventcontroller" 0037 #define ATSPI_DBUS_INTERFACE_DEC "org.a11y.atspi.DeviceEventController" 0038 #define ATSPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER "org.a11y.atspi.DeviceEventListener" 0039 0040 #define ATSPI_DBUS_INTERFACE_CACHE "org.a11y.atspi.Cache" 0041 #define ATSPI_DBUS_INTERFACE_ACCESSIBLE "org.a11y.atspi.Accessible" 0042 #define ATSPI_DBUS_INTERFACE_ACTION "org.a11y.atspi.Action" 0043 #define ATSPI_DBUS_INTERFACE_APPLICATION "org.a11y.atspi.Application" 0044 #define ATSPI_DBUS_INTERFACE_COLLECTION "org.a11y.atspi.Collection" 0045 #define ATSPI_DBUS_INTERFACE_COMPONENT "org.a11y.atspi.Component" 0046 #define ATSPI_DBUS_INTERFACE_DOCUMENT "org.a11y.atspi.Document" 0047 #define ATSPI_DBUS_INTERFACE_EDITABLE_TEXT "org.a11y.atspi.EditableText" 0048 #define ATSPI_DBUS_INTERFACE_EVENT_KEYBOARD "org.a11y.atspi.Event.Keyboard" 0049 #define ATSPI_DBUS_INTERFACE_EVENT_MOUSE "org.a11y.atspi.Event.Mouse" 0050 #define ATSPI_DBUS_INTERFACE_EVENT_OBJECT "org.a11y.atspi.Event.Object" 0051 #define ATSPI_DBUS_INTERFACE_HYPERLINK "org.a11y.atspi.Hyperlink" 0052 #define ATSPI_DBUS_INTERFACE_HYPERTEXT "org.a11y.atspi.Hypertext" 0053 #define ATSPI_DBUS_INTERFACE_IMAGE "org.a11y.atspi.Image" 0054 #define ATSPI_DBUS_INTERFACE_SELECTION "org.a11y.atspi.Selection" 0055 #define ATSPI_DBUS_INTERFACE_TABLE "org.a11y.atspi.Table" 0056 #define ATSPI_DBUS_INTERFACE_TEXT "org.a11y.atspi.Text" 0057 #define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value" 0058 #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket" 0059 0060 // missing from at-spi2-core: 0061 #define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window" 0062 #define ATSPI_DBUS_INTERFACE_EVENT_FOCUS "org.a11y.atspi.Event.Focus" 0063 0064 #define QSPI_OBJECT_PATH_ACCESSIBLE "/org/a11y/atspi/accessible" 0065 #define QSPI_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/" 0066 #define QSPI_OBJECT_PATH_ROOT QSPI_OBJECT_PATH_PREFIX "root" 0067 0068 #define QSPI_REGISTRY_NAME "org.a11y.atspi.Registry" 0069 0070 //#define ATSPI_DEBUG 0071 0072 using namespace QAccessibleClient; 0073 0074 QString RegistryPrivate::ACCESSIBLE_OBJECT_SCHEME_STRING = QLatin1String("accessibleobject"); 0075 0076 RegistryPrivate::RegistryPrivate(Registry *qq) 0077 :q(qq) 0078 , m_subscriptions(Registry::NoEventListeners) 0079 , m_cache(nullptr) 0080 { 0081 qDBusRegisterMetaType<QVector<quint32> >(); 0082 0083 connect(&conn, SIGNAL(connectionFetched()), this, SLOT(connectionFetched())); 0084 connect(&m_actionMapper, SIGNAL(mappedString(QString)), this, SLOT(actionTriggered(QString))); 0085 init(); 0086 } 0087 0088 void RegistryPrivate::init() 0089 { 0090 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_CACHE)] = AccessibleObject::CacheInterface; 0091 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_ACCESSIBLE)] = AccessibleObject::AccessibleInterface; 0092 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_ACTION)] = AccessibleObject::ActionInterface; 0093 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_APPLICATION)] = AccessibleObject::ApplicationInterface; 0094 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_COLLECTION)] = AccessibleObject::CollectionInterface; 0095 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_COMPONENT)] = AccessibleObject::ComponentInterface; 0096 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_DOCUMENT)] = AccessibleObject::DocumentInterface; 0097 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_EDITABLE_TEXT)] = AccessibleObject::EditableTextInterface; 0098 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_KEYBOARD)] = AccessibleObject::EventKeyboardInterface; 0099 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_MOUSE)] = AccessibleObject::EventMouseInterface; 0100 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT)] = AccessibleObject::EventObjectInterface; 0101 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_HYPERLINK)] = AccessibleObject::HyperlinkInterface; 0102 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_HYPERTEXT)] = AccessibleObject::HypertextInterface; 0103 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_IMAGE)] = AccessibleObject::ImageInterface; 0104 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_SELECTION)] = AccessibleObject::SelectionInterface; 0105 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_TABLE)] = AccessibleObject::TableInterface; 0106 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_TEXT)] = AccessibleObject::TextInterface; 0107 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_VALUE)] = AccessibleObject::ValueInterface; 0108 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_SOCKET)] = AccessibleObject::SocketInterface; 0109 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_WINDOW)] = AccessibleObject::EventWindowInterface; 0110 interfaceHash[QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_FOCUS)] = AccessibleObject::EventFocusInterface; 0111 } 0112 0113 bool RegistryPrivate::isEnabled() const 0114 { 0115 if (conn.status() != DBusConnection::Connected) 0116 return false; 0117 QDBusMessage message = QDBusMessage::createMethodCall( 0118 QLatin1String("org.a11y.Bus"), QLatin1String("/org/a11y/bus"), QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get")); 0119 message.setArguments(QVariantList() << QLatin1String("org.a11y.Status") << QLatin1String("IsEnabled")); 0120 QDBusReply<QVariant> reply = QDBusConnection::sessionBus().call(message); 0121 if (!reply.isValid()) 0122 return false; 0123 return reply.value().toBool(); 0124 } 0125 0126 void RegistryPrivate::setEnabled(bool enable) 0127 { 0128 QDBusMessage message = QDBusMessage::createMethodCall( 0129 QLatin1String("org.a11y.Bus"), QLatin1String("/org/a11y/bus"), QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Set")); 0130 message.setArguments(QVariantList() << QLatin1String("org.a11y.Status") << QLatin1String("IsEnabled") << QVariant::fromValue(QDBusVariant(enable))); 0131 QDBusMessage reply = QDBusConnection::sessionBus().call(message); 0132 if (reply.type() == QDBusMessage::ErrorMessage) { 0133 qWarning() << "Could not set org.a11y.Status.isEnabled." << reply.errorName() << reply.errorMessage(); 0134 } 0135 } 0136 0137 bool RegistryPrivate::isScreenReaderEnabled() const 0138 { 0139 if (conn.status() != DBusConnection::Connected) 0140 return false; 0141 QDBusMessage message = QDBusMessage::createMethodCall( 0142 QLatin1String("org.a11y.Bus"), QLatin1String("/org/a11y/bus"), QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get")); 0143 message.setArguments(QVariantList() << QLatin1String("org.a11y.Status") << QLatin1String("ScreenReaderEnabled")); 0144 QDBusReply<QVariant> reply = QDBusConnection::sessionBus().call(message); 0145 if (!reply.isValid()) 0146 return false; 0147 return reply.value().toBool(); 0148 } 0149 0150 void RegistryPrivate::setScreenReaderEnabled(bool enable) 0151 { 0152 QDBusMessage message = QDBusMessage::createMethodCall( 0153 QLatin1String("org.a11y.Bus"), QLatin1String("/org/a11y/bus"), QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Set")); 0154 message.setArguments(QVariantList() << QLatin1String("org.a11y.Status") << QLatin1String("ScreenReaderEnabled") << QVariant::fromValue(QDBusVariant(enable))); 0155 QDBusMessage reply = QDBusConnection::sessionBus().call(message); 0156 if (reply.type() == QDBusMessage::ErrorMessage) { 0157 qWarning() << "Could not set org.a11y.Status.ScreenReaderEnabled." << reply.errorName() << reply.errorMessage(); 0158 } 0159 } 0160 0161 AccessibleObject RegistryPrivate::fromUrl(const QUrl &url) const 0162 { 0163 Q_ASSERT(url.scheme() == ACCESSIBLE_OBJECT_SCHEME_STRING); 0164 if (url.scheme() != ACCESSIBLE_OBJECT_SCHEME_STRING) 0165 return AccessibleObject(); 0166 QString path = url.path(); 0167 QString service = url.fragment(); 0168 return accessibleFromPath(service, path); 0169 } 0170 0171 void RegistryPrivate::connectionFetched() 0172 { 0173 Q_ASSERT(conn.status() == DBusConnection::Connected); 0174 0175 QDBusConnection session = QDBusConnection::sessionBus(); 0176 if (session.isConnected()) { 0177 bool connected = session.connect(QLatin1String("org.a11y.Bus"), QLatin1String("/org/a11y/bus"), QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("PropertiesChanged"), this, SLOT(a11yConnectionChanged(QString,QVariantMap,QStringList))); 0178 if (!connected) 0179 qWarning() << Q_FUNC_INFO << "Failed to connect with signal org.a11y.Status.PropertiesChanged on org.a11y.Bus"; 0180 } 0181 0182 if (m_pendingSubscriptions > 0) { 0183 subscribeEventListeners(m_pendingSubscriptions); 0184 m_pendingSubscriptions = {}; 0185 } 0186 } 0187 0188 void RegistryPrivate::subscribeEventListeners(const Registry::EventListeners &listeners) 0189 { 0190 if (conn.isFetchingConnection()) { 0191 m_pendingSubscriptions = listeners; 0192 return; 0193 } 0194 0195 Registry::EventListeners addedListeners = listeners & ~m_subscriptions; 0196 Registry::EventListeners removedListeners = m_subscriptions & ~listeners; 0197 0198 QStringList newSubscriptions; 0199 QStringList removedSubscriptions; 0200 0201 if (removedListeners.testFlag(Registry::Window)) { 0202 removedSubscriptions << QLatin1String("window:"); 0203 } else if (addedListeners.testFlag(Registry::Window)) { 0204 // subscribe all window events 0205 newSubscriptions << QLatin1String("window:"); 0206 0207 bool created = conn.connection().connect( 0208 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Create"), 0209 this, SLOT(slotWindowCreate(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0210 bool destroyed = conn.connection().connect( 0211 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Destroy"), 0212 this, SLOT(slotWindowDestroy(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0213 0214 bool closed = conn.connection().connect( 0215 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Close"), 0216 this, SLOT(slotWindowClose(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0217 bool reparented = conn.connection().connect( 0218 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Reparent"), 0219 this, SLOT(slotWindowReparent(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0220 0221 bool minimized = conn.connection().connect( 0222 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Minimize"), 0223 this, SLOT(slotWindowMinimize(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0224 bool maximized = conn.connection().connect( 0225 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Maximize"), 0226 this, SLOT(slotWindowMaximize(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0227 bool restored = conn.connection().connect( 0228 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Restore"), 0229 this, SLOT(slotWindowRestore(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0230 0231 bool activated = conn.connection().connect( 0232 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Activate"), 0233 this, SLOT(slotWindowActivate(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0234 bool deactivated = conn.connection().connect( 0235 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Deactivate"), 0236 this, SLOT(slotWindowDeactivate(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0237 0238 bool desktopCreated = conn.connection().connect( 0239 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("DesktopCreate"), 0240 this, SLOT(slotWindowDesktopCreate(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0241 bool desktopDestroyed = conn.connection().connect( 0242 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("DesktopDestroy"), 0243 this, SLOT(slotWindowDesktopDestroy(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0244 bool raised = conn.connection().connect( 0245 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Raise"), 0246 this, SLOT(slotWindowRaise(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0247 bool lowered = conn.connection().connect( 0248 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Lower"), 0249 this, SLOT(slotWindowLower(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0250 bool moved = conn.connection().connect( 0251 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Move"), 0252 this, SLOT(slotWindowMove(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0253 bool resized = conn.connection().connect( 0254 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Resize"), 0255 this, SLOT(slotWindowResize(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0256 bool shaded = conn.connection().connect( 0257 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Shade"), 0258 this, SLOT(slotWindowShade(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0259 bool unshaded = conn.connection().connect( 0260 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Window"), QLatin1String("Unshade"), 0261 this, SLOT(slotWindowUnshade(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0262 0263 if (!created || !destroyed || !closed || !reparented || !minimized || !maximized || !restored || 0264 !activated || !deactivated || !desktopCreated || !desktopDestroyed || 0265 !raised || !lowered || !moved || !resized || !shaded || !unshaded 0266 ) { 0267 qWarning() << "Could not subscribe to Window event(s)." 0268 << "created:" << created << "destroyed:" << destroyed 0269 << "closed:" << closed << "reparented:" << reparented 0270 << "minimized:" << minimized << "maximized:" << maximized << "restored:" << restored 0271 << "activated:" << activated << "deactivated:" << deactivated 0272 << "desktopCreated:" << desktopCreated << "desktopDestroyed:" << desktopDestroyed 0273 << "raised:" << raised << "lowered:" << lowered 0274 << "moved:" << moved << "resized:" << resized 0275 << "shaded:" << shaded << "unshaded:" << unshaded 0276 ; 0277 } 0278 } 0279 0280 if (removedListeners.testFlag(Registry::ChildrenChanged)) { 0281 removedSubscriptions << QLatin1String("object:children-changed"); 0282 } else if (addedListeners.testFlag(Registry::ChildrenChanged)) { 0283 newSubscriptions << QLatin1String("object:children-changed"); 0284 bool success = conn.connection().connect( 0285 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("ChildrenChanged"), 0286 this, SLOT(slotChildrenChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0287 if (!success) qWarning() << "Could not subscribe to accessibility ChildrenChanged events."; 0288 } 0289 0290 if (removedListeners.testFlag(Registry::VisibleDataChanged)) { 0291 removedSubscriptions << QLatin1String("object:visibledata-changed"); 0292 } else if (addedListeners.testFlag(Registry::VisibleDataChanged)) { 0293 newSubscriptions << QLatin1String("object:visibledata-changed"); 0294 bool success = conn.connection().connect( 0295 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("VisibleDataChanged"), 0296 this, SLOT(slotVisibleDataChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0297 if (!success) qWarning() << "Could not subscribe to accessibility VisibleDataChanged events."; 0298 } 0299 0300 if (removedListeners.testFlag(Registry::SelectionChanged)) { 0301 removedSubscriptions << QLatin1String("object:selection-changed"); 0302 } else if (addedListeners.testFlag(Registry::SelectionChanged)) { 0303 newSubscriptions << QLatin1String("object:selection-changed"); 0304 bool success = conn.connection().connect( 0305 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("SelectionChanged"), 0306 this, SLOT(slotSelectionChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0307 if (!success) qWarning() << "Could not subscribe to accessibility SelectionChanged events."; 0308 } 0309 0310 0311 if (removedListeners.testFlag(Registry::ModelChanged)) { 0312 removedSubscriptions << QLatin1String("object:model-changed"); 0313 } else if (addedListeners.testFlag(Registry::ModelChanged)) { 0314 newSubscriptions << QLatin1String("object:model-changed"); 0315 bool success = conn.connection().connect( 0316 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("ModelChanged"), 0317 this, SLOT(slotModelChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0318 if (!success) qWarning() << "Could not subscribe to accessibility ModelChanged events."; 0319 } 0320 0321 // we need state-changed-focus for focus events 0322 if ((removedListeners.testFlag(Registry::StateChanged) || removedListeners.testFlag(Registry::Focus)) 0323 && (!(addedListeners.testFlag(Registry::StateChanged) || addedListeners.testFlag(Registry::Focus)))) { 0324 removedSubscriptions << QLatin1String("object:state-changed"); 0325 } else if (addedListeners.testFlag(Registry::StateChanged) || addedListeners.testFlag(Registry::Focus)) { 0326 if (listeners.testFlag(Registry::Focus)) newSubscriptions << QLatin1String("focus:"); 0327 newSubscriptions << QLatin1String("object:state-changed"); 0328 bool success = conn.connection().connect( 0329 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("StateChanged"), 0330 this, SLOT(slotStateChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0331 if (!success) qWarning() << "Could not subscribe to accessibility Focus events."; 0332 } 0333 0334 if (removedListeners.testFlag(Registry::TextChanged)) { 0335 removedSubscriptions << QLatin1String("object:text-changed"); 0336 } else if (addedListeners.testFlag(Registry::TextChanged)) { 0337 newSubscriptions << QLatin1String("object:text-changed"); 0338 bool success = conn.connection().connect( 0339 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("TextChanged"), 0340 this, SLOT(slotTextChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0341 if (!success) qWarning() << "Could not subscribe to accessibility TextChanged events."; 0342 } 0343 0344 if (removedListeners.testFlag(Registry::TextCaretMoved)) { 0345 removedSubscriptions << QLatin1String("object:text-caret-moved"); 0346 } else if (addedListeners.testFlag(Registry::TextCaretMoved)) { 0347 newSubscriptions << QLatin1String("object:text-caret-moved"); 0348 bool success = conn.connection().connect( 0349 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("TextCaretMoved"), 0350 this, SLOT(slotTextCaretMoved(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0351 if (!success) qWarning() << "Could not subscribe to accessibility TextCaretMoved events."; 0352 } 0353 0354 if (removedListeners.testFlag(Registry::TextSelectionChanged)) { 0355 removedSubscriptions << QLatin1String("object:text-selection-changed"); 0356 } else if (addedListeners.testFlag(Registry::TextSelectionChanged)) { 0357 newSubscriptions << QLatin1String("object:text-selection-changed"); 0358 bool success = conn.connection().connect( 0359 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("TextSelectionChanged"), 0360 this, SLOT(slotTextSelectionChanged(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0361 if (!success) qWarning() << "Could not subscribe to accessibility TextSelectionChanged events."; 0362 } 0363 0364 if (removedListeners.testFlag(Registry::PropertyChanged)) { 0365 removedSubscriptions << QLatin1String("object:property-change"); 0366 } else if (addedListeners.testFlag(Registry::PropertyChanged )) { 0367 newSubscriptions << QLatin1String("object:property-change"); 0368 bool success = conn.connection().connect( 0369 QString(), QLatin1String(""), QLatin1String("org.a11y.atspi.Event.Object"), QLatin1String("PropertyChange"), 0370 this, SLOT(slotPropertyChange(QString,int,int,QDBusVariant,QAccessibleClient::QSpiObjectReference))); 0371 if (!success) qWarning() << "Could not subscribe to accessibility PropertyChange events."; 0372 } 0373 0374 for (const QString &subscription : std::as_const(newSubscriptions)) { 0375 QDBusMessage m = QDBusMessage::createMethodCall(QLatin1String("org.a11y.atspi.Registry"), 0376 QLatin1String("/org/a11y/atspi/registry"), 0377 QLatin1String("org.a11y.atspi.Registry"), QLatin1String("RegisterEvent")); 0378 m.setArguments(QVariantList() << subscription); 0379 0380 QDBusPendingCall async = conn.connection().asyncCall(m); 0381 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); 0382 QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(slotSubscribeEventListenerFinished(QDBusPendingCallWatcher*))); 0383 } 0384 0385 for (const QString &subscription : std::as_const(removedSubscriptions)) { 0386 QDBusMessage m = QDBusMessage::createMethodCall(QLatin1String("org.a11y.atspi.Registry"), 0387 QLatin1String("/org/a11y/atspi/registry"), 0388 QLatin1String("org.a11y.atspi.Registry"), QLatin1String("DeregisterEvent")); 0389 m.setArguments(QVariantList() << subscription); 0390 conn.connection().asyncCall(m); 0391 } 0392 0393 m_subscriptions = listeners; 0394 0395 // accerciser 0396 // (u':1.7', u'Object:StateChanged:'), 0397 // (u':1.7', u'Object:BoundsChanged:'), 0398 // (u':1.7', u'Object:VisibleDataChanged:'), 0399 // (u':1.7', u'Object:StateChanged:'), 0400 // orca 0401 // [(u':1.8', u'Object:ChildrenChanged:'), 0402 // (u':1.8', u'Mouse:Button:'), 0403 // (u':1.8', u'Mouse:Abs:'), 0404 // (u':1.8', u'Object:StateChanged:Selected'), 0405 // (u':1.8', u'Object:StateChanged:Expanded'), 0406 // (u':1.8', u'Object:ValueChanged:'), 0407 // (u':1.8', u'Object:StateChanged:Focused'), 0408 // (u':1.8', u'Object:StateChanged:Active'), 0409 // (u':1.8', u'Window:Create:'), 0410 // (u':1.8', u'Object:TextAttributesChanged:'), 0411 // (u':1.8', u'Object:TextCaretMoved:'), 0412 // (u':1.8', u'Object:SelectionChanged:'), 0413 // (u':1.8', u'Focus::'), 0414 // (u':1.8', u'Object:ActiveDescendantChanged:'), 0415 // (u':1.8', u'Object:PropertyChange:AccessibleName'), 0416 // (u':1.8', u'Window:Activate:'), 0417 // (u':1.8', u'Window:Deactivate:'), 0418 // (u':1.8', u'Mouse:Button:'), 0419 // (u':1.8', u'Object:StateChanged:Indeterminate'), 0420 // (u':1.8', u'Object:LinkSelected:'), 0421 // (u':1.8', u'Object:TextChanged:Insert'), 0422 // (u':1.8', u'Object:PropertyChange:AccessibleValue'), 0423 // (u':1.8', u'Object:TextSelectionChanged:'), 0424 // // (u':1.8', u'Object:StateChanged:Showing'), 0425 // (u':1.8', u'Object:TextChanged:Delete'), 0426 // (u':1.8', u'Object:StateChanged:Pressed'), 0427 // (u':1.8', u'Object:StateChanged:Checked'), 0428 // (u':1.8', u'Object:ChildrenChanged:Remove')] 0429 0430 } 0431 0432 Registry::EventListeners RegistryPrivate::eventListeners() const 0433 { 0434 return m_subscriptions | m_pendingSubscriptions; 0435 } 0436 0437 void RegistryPrivate::slotSubscribeEventListenerFinished(QDBusPendingCallWatcher *call) 0438 { 0439 if (call->isError()) { 0440 qWarning() << "Could not subscribe to accessibility event: " << call->error().type() << call->error().message(); 0441 } 0442 call->deleteLater(); 0443 } 0444 0445 void RegistryPrivate::a11yConnectionChanged(const QString &interface,const QVariantMap &changedProperties, const QStringList &invalidatedProperties) 0446 { 0447 //qDebug() << Q_FUNC_INFO << "interface=" << interface << "changedProperties=" << changedProperties << "invalidatedProperties=" << invalidatedProperties; 0448 if (conn.status() != DBusConnection::Connected) 0449 return; 0450 if (interface == QLatin1String("org.a11y.Status")) { 0451 QVariantMap::ConstIterator IsEnabledIt = changedProperties.constFind(QLatin1String("IsEnabled")); 0452 if (IsEnabledIt != changedProperties.constEnd()) 0453 Q_EMIT q->enabledChanged(IsEnabledIt.value().toBool()); 0454 else if (invalidatedProperties.contains(QLatin1String("IsEnabled"))) 0455 Q_EMIT q->enabledChanged(isEnabled()); 0456 0457 QVariantMap::ConstIterator ScreenReaderEnabledIt = changedProperties.constFind(QLatin1String("ScreenReaderEnabled")); 0458 if (ScreenReaderEnabledIt != changedProperties.constEnd()) 0459 Q_EMIT q->screenReaderEnabledChanged(ScreenReaderEnabledIt.value().toBool()); 0460 else if (invalidatedProperties.contains(QLatin1String("ScreenReaderEnabled"))) 0461 Q_EMIT q->screenReaderEnabledChanged(isScreenReaderEnabled()); 0462 } 0463 } 0464 0465 AccessibleObject RegistryPrivate::parentAccessible(const AccessibleObject &object) const 0466 { 0467 QVariant parent = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("Parent")); 0468 if (!parent.isValid()) 0469 return AccessibleObject(); 0470 const QDBusArgument arg = parent.value<QDBusArgument>(); 0471 QSpiObjectReference ref; 0472 arg >> ref; 0473 0474 if (ref.path.path() == object.d->path) { 0475 qWarning() << "WARNING: Accessible claims to be its own parent: " << object; 0476 return AccessibleObject(); 0477 } 0478 0479 if (ref.service.isEmpty() || ref.path.path().isEmpty()) 0480 return AccessibleObject(); 0481 0482 return AccessibleObject(const_cast<RegistryPrivate*>(this), ref.service, ref.path.path()); 0483 } 0484 0485 int RegistryPrivate::childCount(const AccessibleObject &object) const 0486 { 0487 QVariant childCount = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("ChildCount")); 0488 return childCount.toInt(); 0489 } 0490 0491 int RegistryPrivate::indexInParent(const AccessibleObject &object) const 0492 { 0493 QDBusMessage message = QDBusMessage::createMethodCall ( 0494 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetIndexInParent")); 0495 0496 QDBusReply<int> reply = conn.connection().call(message); 0497 if (!reply.isValid()) { 0498 QDBusReply<uint> reply2 = conn.connection().call(message); 0499 if (reply2.isValid()) { 0500 qWarning() << "Found old api returning uint in GetIndexInParent." << reply.error().message(); 0501 return static_cast<int>(reply.value()); 0502 } 0503 qWarning() << "Could not access index in parent." << reply.error().message(); 0504 return -1; 0505 } 0506 return reply.value(); 0507 } 0508 0509 AccessibleObject RegistryPrivate::child(const AccessibleObject &object, int index) const 0510 { 0511 QDBusMessage message = QDBusMessage::createMethodCall ( 0512 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetChildAtIndex")); 0513 QVariantList args; 0514 args << index; 0515 message.setArguments(args); 0516 0517 QDBusReply<QSpiObjectReference> reply = conn.connection().call(message); 0518 if (!reply.isValid()) { 0519 qWarning() << "Could not access child." << reply.error().message(); 0520 return AccessibleObject(); 0521 } 0522 const QSpiObjectReference child = reply.value(); 0523 return AccessibleObject(const_cast<RegistryPrivate*>(this), child.service, child.path.path()); 0524 } 0525 0526 QList<AccessibleObject> RegistryPrivate::children(const AccessibleObject &object) const 0527 { 0528 QList<AccessibleObject> accs; 0529 0530 QDBusMessage message = QDBusMessage::createMethodCall ( 0531 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetChildren")); 0532 0533 QDBusReply<QSpiObjectReferenceList> reply = conn.connection().call(message, QDBus::Block, 500); 0534 if (!reply.isValid()) { 0535 qWarning() << "Could not access children." << reply.error().message(); 0536 return accs; 0537 } 0538 0539 const QSpiObjectReferenceList children = reply.value(); 0540 for (const QSpiObjectReference &child : children) { 0541 accs.append(AccessibleObject(const_cast<RegistryPrivate*>(this), child.service, child.path.path())); 0542 } 0543 0544 return accs; 0545 } 0546 0547 QList<AccessibleObject> RegistryPrivate::topLevelAccessibles() const 0548 { 0549 QString service = QLatin1String("org.a11y.atspi.Registry"); 0550 QString path = QLatin1String("/org/a11y/atspi/accessible/root"); 0551 return children(AccessibleObject(const_cast<RegistryPrivate*>(this), service, path)); 0552 } 0553 0554 QString RegistryPrivate::accessibleId(const AccessibleObject &object) const 0555 { 0556 if (!object.isValid()) 0557 return QString(); 0558 return getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("AccessibleId")).toString(); 0559 } 0560 0561 QString RegistryPrivate::name(const AccessibleObject &object) const 0562 { 0563 if (!object.isValid()) 0564 return QString(); 0565 return getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("Name")).toString(); 0566 } 0567 0568 QString RegistryPrivate::description(const AccessibleObject &object) const 0569 { 0570 if (!object.isValid()) 0571 return QString(); 0572 return getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("Description")).toString(); 0573 } 0574 0575 AccessibleObject::Role RegistryPrivate::role(const AccessibleObject &object) const 0576 { 0577 if (!object.isValid()) 0578 return AccessibleObject::NoRole; 0579 0580 QDBusMessage message = QDBusMessage::createMethodCall ( 0581 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetRole")); 0582 0583 QDBusReply<uint> reply = conn.connection().call(message); 0584 if (!reply.isValid()) { 0585 qWarning() << "Could not access role." << reply.error().message(); 0586 return AccessibleObject::NoRole; 0587 } 0588 return atspiRoleToRole(static_cast<AtspiRole>(reply.value())); 0589 } 0590 0591 AccessibleObject::Role RegistryPrivate::atspiRoleToRole(AtspiRole role) 0592 { 0593 switch (role) { 0594 case ATSPI_ROLE_INVALID: return AccessibleObject::NoRole; 0595 // case ATSPI_ROLE_ACCELERATOR_LABEL: return AccessibleObject::; 0596 // case ATSPI_ROLE_ALERT: return AccessibleObject::; 0597 // case ATSPI_ROLE_ANIMATION: return AccessibleObject::; 0598 // case ATSPI_ROLE_ARROW: return AccessibleObject::; 0599 // case ATSPI_ROLE_CALENDAR: return AccessibleObject::; 0600 // case ATSPI_ROLE_CANVAS: return AccessibleObject::; 0601 case ATSPI_ROLE_CHECK_BOX: return AccessibleObject::CheckBox; 0602 case ATSPI_ROLE_CHECK_MENU_ITEM: return AccessibleObject::CheckableMenuItem; 0603 // case ATSPI_ROLE_COLOR_CHOOSER: return AccessibleObject::; 0604 case ATSPI_ROLE_COLUMN_HEADER: return AccessibleObject::ColumnHeader; 0605 case ATSPI_ROLE_COMBO_BOX: return AccessibleObject::ComboBox; 0606 // case ATSPI_ROLE_DATE_EDITOR: return AccessibleObject::; 0607 // case ATSPI_ROLE_DESKTOP_ICON: return AccessibleObject::; 0608 case ATSPI_ROLE_DESKTOP_FRAME: return AccessibleObject::DesktopFrame; 0609 // case ATSPI_ROLE_DIAL: return AccessibleObject::; 0610 case ATSPI_ROLE_DIALOG: return AccessibleObject::Dialog; 0611 // case ATSPI_ROLE_DIRECTORY_PANE: return AccessibleObject::; 0612 // case ATSPI_ROLE_DRAWING_AREA: return AccessibleObject::; 0613 // case ATSPI_ROLE_FILE_CHOOSER: return AccessibleObject::; 0614 case ATSPI_ROLE_FILLER: return AccessibleObject::Filler; 0615 // case ATSPI_ROLE_FOCUS_TRAVERSABLE: return AccessibleObject::; 0616 // case ATSPI_ROLE_FONT_CHOOSER: return AccessibleObject::; 0617 case ATSPI_ROLE_FRAME: return AccessibleObject::Frame; 0618 // case ATSPI_ROLE_GLASS_PANE: return AccessibleObject::; 0619 // case ATSPI_ROLE_HTML_CONTAINER: return AccessibleObject::; 0620 case ATSPI_ROLE_ICON: return AccessibleObject::Icon; 0621 // case ATSPI_ROLE_IMAGE: return AccessibleObject::; 0622 // case ATSPI_ROLE_INTERNAL_FRAME: return AccessibleObject::; 0623 case ATSPI_ROLE_LABEL: return AccessibleObject::Label; 0624 // case ATSPI_ROLE_LAYERED_PANE: return AccessibleObject::; 0625 case ATSPI_ROLE_LIST: return AccessibleObject::ListView; 0626 case ATSPI_ROLE_LIST_ITEM: return AccessibleObject::ListItem; 0627 case ATSPI_ROLE_MENU: return AccessibleObject::Menu; 0628 case ATSPI_ROLE_MENU_BAR: return AccessibleObject::MenuBar; 0629 case ATSPI_ROLE_MENU_ITEM: return AccessibleObject::MenuItem; 0630 // case ATSPI_ROLE_OPTION_PANE: return AccessibleObject::; 0631 case ATSPI_ROLE_PAGE_TAB: return AccessibleObject::Tab; 0632 case ATSPI_ROLE_PAGE_TAB_LIST: return AccessibleObject::TabContainer; 0633 // case ATSPI_ROLE_PANEL: return AccessibleObject::; 0634 case ATSPI_ROLE_PASSWORD_TEXT: return AccessibleObject::PasswordText; 0635 case ATSPI_ROLE_POPUP_MENU: return AccessibleObject::PopupMenu; 0636 case ATSPI_ROLE_PROGRESS_BAR: return AccessibleObject::ProgressBar; 0637 case ATSPI_ROLE_PUSH_BUTTON: return AccessibleObject::Button; 0638 case ATSPI_ROLE_RADIO_BUTTON: return AccessibleObject::RadioButton; 0639 case ATSPI_ROLE_RADIO_MENU_ITEM: return AccessibleObject::RadioMenuItem; 0640 // case ATSPI_ROLE_ROOT_PANE: return AccessibleObject::; 0641 case ATSPI_ROLE_ROW_HEADER: return AccessibleObject::RowHeader; 0642 case ATSPI_ROLE_SCROLL_BAR: return AccessibleObject::ScrollBar; 0643 case ATSPI_ROLE_SCROLL_PANE: return AccessibleObject::ScrollArea; 0644 case ATSPI_ROLE_SEPARATOR: return AccessibleObject::Separator; 0645 case ATSPI_ROLE_SLIDER: return AccessibleObject::Slider; 0646 case ATSPI_ROLE_SPIN_BUTTON: return AccessibleObject::SpinButton; 0647 // case ATSPI_ROLE_SPLIT_PANE: return AccessibleObject::; 0648 case ATSPI_ROLE_STATUS_BAR: return AccessibleObject::StatusBar; 0649 case ATSPI_ROLE_TABLE: return AccessibleObject::TableView; 0650 case ATSPI_ROLE_TABLE_CELL: return AccessibleObject::TableCell; 0651 case ATSPI_ROLE_TABLE_COLUMN_HEADER: return AccessibleObject::TableColumnHeader; 0652 case ATSPI_ROLE_TABLE_ROW_HEADER: return AccessibleObject::TableRowHeader; 0653 // case ATSPI_ROLE_TEAROFF_MENU_ITEM: return AccessibleObject::; 0654 case ATSPI_ROLE_TERMINAL: return AccessibleObject::Terminal; 0655 case ATSPI_ROLE_TEXT: return AccessibleObject::Text; 0656 case ATSPI_ROLE_TOGGLE_BUTTON: return AccessibleObject::ToggleButton; 0657 case ATSPI_ROLE_TOOL_BAR: return AccessibleObject::ToolBar; 0658 case ATSPI_ROLE_TOOL_TIP: return AccessibleObject::ToolTip; 0659 case ATSPI_ROLE_TREE: return AccessibleObject::TreeView; 0660 case ATSPI_ROLE_TREE_TABLE: return AccessibleObject::TreeView; 0661 case ATSPI_ROLE_UNKNOWN: return AccessibleObject::NoRole; 0662 // case ATSPI_ROLE_VIEWPORT: return AccessibleObject::; 0663 case ATSPI_ROLE_WINDOW: return AccessibleObject::Window; 0664 // case ATSPI_ROLE_EXTENDED: return AccessibleObject::; 0665 // case ATSPI_ROLE_HEADER: return AccessibleObject::; 0666 // case ATSPI_ROLE_FOOTER: return AccessibleObject::; 0667 // case ATSPI_ROLE_PARAGRAPH: return AccessibleObject::; 0668 // case ATSPI_ROLE_RULER: return AccessibleObject::; 0669 // case ATSPI_ROLE_APPLICATION: return AccessibleObject::; 0670 // case ATSPI_ROLE_AUTOCOMPLETE: return AccessibleObject::; 0671 // case ATSPI_ROLE_EDITBAR: return AccessibleObject::; 0672 // case ATSPI_ROLE_EMBEDDED: return AccessibleObject::; 0673 // case ATSPI_ROLE_ENTRY: return AccessibleObject::; 0674 // case ATSPI_ROLE_CHART: return AccessibleObject::; 0675 // case ATSPI_ROLE_CAPTION: return AccessibleObject::; 0676 // case ATSPI_ROLE_DOCUMENT_FRAME: return AccessibleObject::; 0677 // case ATSPI_ROLE_HEADING: return AccessibleObject::; 0678 // case ATSPI_ROLE_PAGE: return AccessibleObject::; 0679 // case ATSPI_ROLE_SECTION: return AccessibleObject::; 0680 // case ATSPI_ROLE_REDUNDANT_OBJECT: return AccessibleObject::; 0681 // case ATSPI_ROLE_FORM: return AccessibleObject::; 0682 // case ATSPI_ROLE_LINK: return AccessibleObject::; 0683 // case ATSPI_ROLE_INPUT_METHOD_WINDOW: return AccessibleObject::; 0684 case ATSPI_ROLE_TABLE_ROW: return AccessibleObject::TableRow; 0685 case ATSPI_ROLE_TREE_ITEM: return AccessibleObject::TreeItem; 0686 // case ATSPI_ROLE_DOCUMENT_SPREADSHEET: return AccessibleObject::; 0687 // case ATSPI_ROLE_DOCUMENT_PRESENTATION: return AccessibleObject::; 0688 // case ATSPI_ROLE_DOCUMENT_TEXT: return AccessibleObject::; 0689 // case ATSPI_ROLE_DOCUMENT_WEB: return AccessibleObject::; 0690 // case ATSPI_ROLE_DOCUMENT_EMAIL: return AccessibleObject::; 0691 // case ATSPI_ROLE_COMMENT: return AccessibleObject::; 0692 // case ATSPI_ROLE_LIST_BOX: return AccessibleObject::; 0693 // case ATSPI_ROLE_GROUPING: return AccessibleObject::; 0694 // case ATSPI_ROLE_IMAGE_MAP: return AccessibleObject::; 0695 // case ATSPI_ROLE_NOTIFICATION: return AccessibleObject::; 0696 // case ATSPI_ROLE_INFO_BAR: return AccessibleObject::; 0697 // case ATSPI_ROLE_LAST_DEFINED: return AccessibleObject::; 0698 } 0699 return AccessibleObject::NoRole; 0700 } 0701 0702 QString RegistryPrivate::roleName(const AccessibleObject &object) const 0703 { 0704 QDBusMessage message = QDBusMessage::createMethodCall ( 0705 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetRoleName")); 0706 0707 QDBusReply<QString> reply = conn.connection().call(message); 0708 if (!reply.isValid()) { 0709 qWarning() << "Could not access roleName." << reply.error().message(); 0710 return QString(); 0711 } 0712 return reply.value(); 0713 } 0714 0715 QString RegistryPrivate::localizedRoleName(const AccessibleObject &object) const 0716 { 0717 QDBusMessage message = QDBusMessage::createMethodCall ( 0718 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetLocalizedRoleName")); 0719 0720 QDBusReply<QString> reply = conn.connection().call(message); 0721 if (!reply.isValid()) { 0722 qWarning() << "Could not access localizedRoleName." << reply.error().message();\ 0723 return QString(); 0724 } 0725 return reply.value(); 0726 } 0727 0728 quint64 RegistryPrivate::state(const AccessibleObject &object) const 0729 { 0730 if (m_cache) { 0731 quint64 cachedValue = m_cache->state(object); 0732 if (cachedValue != QAccessibleClient::ObjectCache::StateNotFound) 0733 return cachedValue; 0734 } 0735 0736 QDBusMessage message = QDBusMessage::createMethodCall ( 0737 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetState")); 0738 0739 QDBusReply<QVector<quint32> > reply = conn.connection().call(message); 0740 if (!reply.isValid()) { 0741 qWarning() << "Could not access state." << reply.error().message(); 0742 return 0; 0743 } 0744 if (reply.value().size() < 2) { 0745 qWarning() << "Did not receive expected reply."; 0746 return 0; 0747 } 0748 quint32 low = reply.value().at(0); 0749 quint32 high = reply.value().at(1); 0750 quint64 state = low + (static_cast<quint64>(high) << 32); 0751 0752 if (m_cache) { 0753 m_cache->setState(object, state); 0754 } 0755 0756 return state; 0757 } 0758 0759 int RegistryPrivate::layer(const AccessibleObject &object) const 0760 { 0761 QDBusMessage message = QDBusMessage::createMethodCall ( 0762 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Component"), QLatin1String("GetLayer")); 0763 QDBusReply<uint> reply = conn.connection().call(message); 0764 if (!reply.isValid()) { 0765 qWarning() << "Could not access layer." << reply.error().message(); 0766 return 1; 0767 } 0768 return reply.value(); 0769 } 0770 0771 int RegistryPrivate::mdiZOrder(const AccessibleObject &object) const 0772 { 0773 QDBusMessage message = QDBusMessage::createMethodCall ( 0774 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Component"), QLatin1String("GetMDIZOrder")); 0775 QDBusReply<short> reply = conn.connection().call(message); 0776 if (!reply.isValid()) { 0777 qWarning() << "Could not access mdiZOrder." << reply.error().message(); 0778 return 0; 0779 } 0780 return reply.value(); 0781 } 0782 0783 double RegistryPrivate::alpha(const AccessibleObject &object) const 0784 { 0785 QDBusMessage message = QDBusMessage::createMethodCall ( 0786 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Component"), QLatin1String("GetAlpha")); 0787 QDBusReply<double> reply = conn.connection().call(message); 0788 if (!reply.isValid()) { 0789 qWarning() << "Could not access alpha." << reply.error().message(); 0790 return 1.0; 0791 } 0792 return reply.value(); 0793 } 0794 0795 QRect RegistryPrivate::boundingRect(const AccessibleObject &object) const 0796 { 0797 QDBusMessage message = QDBusMessage::createMethodCall( 0798 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Component"), QLatin1String("GetExtents") ); 0799 QVariantList args; 0800 quint32 coords = ATSPI_COORD_TYPE_SCREEN; 0801 args << coords; 0802 message.setArguments(args); 0803 0804 QDBusReply< QRect > reply = conn.connection().call(message); 0805 if(!reply.isValid()){ 0806 qWarning() << "Could not get extents." << reply.error().message(); 0807 return QRect(); 0808 } 0809 0810 return QRect( reply.value() ); 0811 } 0812 0813 QRect RegistryPrivate::characterRect(const AccessibleObject &object, int offset) const 0814 { 0815 QDBusMessage message = QDBusMessage::createMethodCall( 0816 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), 0817 QLatin1String("GetCharacterExtents")); 0818 0819 QVariantList args; 0820 quint32 coords = ATSPI_COORD_TYPE_SCREEN; 0821 args << offset; 0822 args << coords; 0823 message.setArguments(args); 0824 0825 0826 QDBusReply< QRect > reply = conn.connection().call(message); 0827 if(!reply.isValid()){ 0828 if (reply.error().type() == QDBusError::InvalidSignature) { 0829 QDBusMessage reply2 = conn.connection().call(message); 0830 if (reply2.signature() != QLatin1String("iiii")) { 0831 qWarning() << "Could not get Character Extents. " << reply.error().message(); 0832 return QRect(); 0833 } 0834 QList<QVariant> args = reply2.arguments(); 0835 QRect rect(args.at(0).toInt(), args.at(1).toInt(), args.at(2).toInt(), args.at(3).toInt()); 0836 return rect; 0837 } 0838 } 0839 0840 return reply.value(); 0841 } 0842 0843 AccessibleObject::Interfaces RegistryPrivate::supportedInterfaces(const AccessibleObject &object) const 0844 { 0845 if (m_cache) { 0846 AccessibleObject::Interfaces interfaces = m_cache->interfaces(object); 0847 if (!(interfaces & AccessibleObject::InvalidInterface)) 0848 return interfaces; 0849 } 0850 0851 QDBusMessage message = QDBusMessage::createMethodCall( 0852 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), 0853 QLatin1String("GetInterfaces")); 0854 0855 QDBusReply<QStringList > reply = conn.connection().call(message); 0856 if(!reply.isValid()){ 0857 qWarning() << "Could not get Interfaces. " << reply.error().message(); 0858 return AccessibleObject::NoInterface; 0859 } 0860 0861 AccessibleObject::Interfaces interfaces = AccessibleObject::NoInterface; 0862 const auto values{reply.value()}; 0863 for (const QString &interface : values){ 0864 interfaces |= interfaceHash[interface]; 0865 } 0866 0867 if (m_cache) { 0868 m_cache->setInterfaces(object, interfaces); 0869 } 0870 0871 return interfaces; 0872 } 0873 0874 int RegistryPrivate::caretOffset(const AccessibleObject &object) const 0875 { 0876 QVariant offset= getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("CaretOffset")); 0877 if (offset.isNull()) qWarning() << "Could not get caret offset"; 0878 return offset.toInt(); 0879 } 0880 0881 int RegistryPrivate::characterCount(const AccessibleObject &object) const 0882 { 0883 QVariant count = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("CharacterCount")); 0884 if (count.isNull()) qWarning() << "Could not get character count"; 0885 return count.toInt(); 0886 } 0887 0888 QList< QPair<int,int> > RegistryPrivate::textSelections(const AccessibleObject &object) const 0889 { 0890 QList< QPair<int,int> > result; 0891 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("GetNSelections")); 0892 QDBusReply<int> reply = conn.connection().call(message); 0893 if (!reply.isValid()) { 0894 qWarning() << "Could not access GetNSelections." << reply.error().message(); 0895 return result; 0896 } 0897 int count = reply.value(); 0898 for(int i = 0; i < count; ++i) { 0899 QDBusMessage m = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("GetSelection")); 0900 m.setArguments(QVariantList() << i); 0901 m = conn.connection().call(m); 0902 QList<QVariant> args = m.arguments(); 0903 if (args.count() < 2) { 0904 qWarning() << "Invalid number of arguments. Expected=2 Actual=" << args.count(); 0905 continue; 0906 } 0907 int startOffset = args[0].toInt(); 0908 int endOffset = args[1].toInt(); 0909 if (startOffset > endOffset) 0910 qSwap(startOffset, endOffset); 0911 result.append(qMakePair(startOffset, endOffset)); 0912 } 0913 return result; 0914 } 0915 0916 void RegistryPrivate::setTextSelections(const AccessibleObject &object, const QList< QPair<int,int> > &selections) 0917 { 0918 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("GetNSelections")); 0919 QDBusReply<int> reply = conn.connection().call(message); 0920 if (!reply.isValid()) { 0921 qWarning() << "Could not access GetNSelections." << reply.error().message(); 0922 return; 0923 } 0924 int count = reply.value(); 0925 int setSel = qMin(selections.count(), count); 0926 for(int i = 0; i < setSel; ++i) { 0927 Q_ASSERT(i < selections.count()); 0928 QPair<int,int> p = selections[i]; 0929 QDBusMessage m = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("SetSelection")); 0930 m.setArguments(QVariantList() << i << p.first << p.second); 0931 QDBusReply<bool> r = conn.connection().call(m); 0932 if (!r.isValid()) { 0933 qWarning() << "Failed call text.SetSelection." << r.error().message(); 0934 continue; 0935 } 0936 } 0937 int removeSel = qMax(0, count - selections.count()); 0938 for(int i = 0, k = selections.count(); i < removeSel; ++i, ++k) { 0939 QDBusMessage m = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("RemoveSelection")); 0940 m.setArguments(QVariantList() << k); 0941 QDBusReply<bool> r = conn.connection().call(m); 0942 if (!r.isValid()) { 0943 qWarning() << "Failed call text.RemoveSelection." << r.error().message(); 0944 continue; 0945 } 0946 } 0947 int addSel = qMax(0, selections.count() - count); 0948 for(int i = 0, k = count; i < addSel; ++i, ++k) { 0949 Q_ASSERT(k < selections.count()); 0950 QPair<int,int> p = selections[k]; 0951 QDBusMessage m = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("AddSelection")); 0952 m.setArguments(QVariantList() << p.first << p.second); 0953 QDBusReply<bool> r = conn.connection().call(m); 0954 if (!r.isValid()) { 0955 qWarning() << "Failed call text.AddSelection." << r.error().message(); 0956 continue; 0957 } 0958 } 0959 } 0960 0961 QString RegistryPrivate::text(const AccessibleObject &object, int startOffset, int endOffset) const 0962 { 0963 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("GetText")); 0964 message.setArguments(QVariantList() << startOffset << endOffset); 0965 QDBusReply<QString> reply = conn.connection().call(message); 0966 if (!reply.isValid()) { 0967 qWarning() << "Could not access text." << reply.error().message(); 0968 return QString(); 0969 } 0970 return reply.value(); 0971 } 0972 0973 QString RegistryPrivate::textWithBoundary(const AccessibleObject &object, int offset, AccessibleObject::TextBoundary boundary, int *startOffset, int *endOffset) const 0974 { 0975 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Text"), QLatin1String("GetTextAtOffset")); 0976 message.setArguments(QVariantList() << offset << static_cast<AtspiTextBoundaryType>(boundary)); 0977 QDBusMessage reply = conn.connection().call(message); 0978 if (reply.type() != QDBusMessage::ReplyMessage || reply.signature() != QLatin1String("sii")) { 0979 qWarning() << "Could not access text." << reply.errorMessage(); 0980 if (startOffset) 0981 *startOffset = 0; 0982 if (endOffset) 0983 *endOffset = 0; 0984 return QString(); 0985 } 0986 if (startOffset) 0987 *startOffset = reply.arguments().at(1).toInt(); 0988 if (endOffset) 0989 *endOffset = reply.arguments().at(2).toInt(); 0990 return reply.arguments().first().toString();; 0991 } 0992 0993 bool RegistryPrivate::setText(const AccessibleObject &object, const QString &text) 0994 { 0995 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.EditableText"), QLatin1String("SetTextContents")); 0996 message.setArguments(QVariantList() << text); 0997 QDBusReply<bool> reply = conn.connection().call(message); 0998 if (!reply.isValid()) { 0999 qWarning() << "Could not set text." << reply.error().message(); 1000 return false; 1001 } 1002 return reply.value(); 1003 } 1004 1005 bool RegistryPrivate::insertText(const AccessibleObject &object, const QString &text, int position, int length) 1006 { 1007 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.EditableText"), QLatin1String("InsertText")); 1008 message.setArguments(QVariantList() << position << text << length); 1009 QDBusReply<bool> reply = conn.connection().call(message); 1010 if (!reply.isValid()) { 1011 qWarning() << "Could not insert text." << reply.error().message(); 1012 return false; 1013 } 1014 return reply.value(); 1015 } 1016 1017 bool RegistryPrivate::copyText(const AccessibleObject &object, int startPos, int endPos) 1018 { 1019 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.EditableText"), QLatin1String("CopyText")); 1020 message.setArguments(QVariantList() << startPos << endPos); 1021 conn.connection().call(message); 1022 return true; 1023 } 1024 1025 bool RegistryPrivate::cutText(const AccessibleObject &object, int startPos, int endPos) 1026 { 1027 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.EditableText"), QLatin1String("CutText")); 1028 message.setArguments(QVariantList() << startPos << endPos); 1029 QDBusReply<bool> reply = conn.connection().call(message); 1030 if (!reply.isValid()) { 1031 qWarning() << "Could not cut text." << reply.error().message(); 1032 return false; 1033 } 1034 return reply.value(); 1035 } 1036 1037 bool RegistryPrivate::deleteText(const AccessibleObject &object, int startPos, int endPos) 1038 { 1039 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.EditableText"), QLatin1String("DeleteText")); 1040 message.setArguments(QVariantList() << startPos << endPos); 1041 QDBusReply<bool> reply = conn.connection().call(message); 1042 if (!reply.isValid()) { 1043 qWarning() << "Could not delete text." << reply.error().message(); 1044 return false; 1045 } 1046 return reply.value(); 1047 } 1048 1049 bool RegistryPrivate::pasteText(const AccessibleObject &object, int position) 1050 { 1051 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.EditableText"), QLatin1String("PasteText")); 1052 message.setArguments(QVariantList() << position); 1053 QDBusReply<bool> reply = conn.connection().call(message); 1054 if (!reply.isValid()) { 1055 qWarning() << "Could not paste text." << reply.error().message(); 1056 return false; 1057 } 1058 return reply.value(); 1059 } 1060 1061 AccessibleObject RegistryPrivate::application(const AccessibleObject &object) const 1062 { 1063 QDBusMessage message = QDBusMessage::createMethodCall( 1064 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetApplication")); 1065 QDBusReply<QSpiObjectReference> reply = conn.connection().call(message); 1066 if (!reply.isValid()) { 1067 qWarning() << "Could not access application." << reply.error().message(); 1068 return AccessibleObject(); 1069 } 1070 const QSpiObjectReference child = reply.value(); 1071 return AccessibleObject(const_cast<RegistryPrivate*>(this), child.service, child.path.path()); 1072 } 1073 1074 QString RegistryPrivate::appToolkitName(const AccessibleObject &object) const 1075 { 1076 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Application"), QLatin1String("ToolkitName")); 1077 return v.toString(); 1078 } 1079 1080 QString RegistryPrivate::appVersion(const AccessibleObject &object) const 1081 { 1082 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Application"), QLatin1String("Version")); 1083 return v.toString(); 1084 } 1085 1086 int RegistryPrivate::appId(const AccessibleObject &object) const 1087 { 1088 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Application"), QLatin1String("Id")); 1089 return v.toInt(); 1090 } 1091 1092 QString RegistryPrivate::appLocale(const AccessibleObject &object, uint lctype) const 1093 { 1094 // some apps misbehave and claim to be the service, but on :1.0 we have the atspi service which doesn't reply anything sensible here 1095 if (object.d->service == QLatin1String(":1.0")) 1096 return QString(); 1097 1098 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Application"), QLatin1String("GetLocale")); 1099 1100 QVariantList args; 1101 args.append(lctype); 1102 message.setArguments(args); 1103 1104 QDBusReply<QString> reply = conn.connection().call(message, QDBus::Block, 500); 1105 if (!reply.isValid()) { 1106 qWarning() << "Could not access appLocale." << reply.error().message(); 1107 return QString(); 1108 } 1109 return reply.value(); 1110 } 1111 1112 QString RegistryPrivate::appBusAddress(const AccessibleObject &object) const 1113 { 1114 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Application"), QLatin1String("GetApplicationBusAddress")); 1115 QDBusReply<QString> reply = conn.connection().call(message); 1116 if (!reply.isValid()) { 1117 qWarning() << Q_FUNC_INFO << "Could not access application bus address. Error: " << reply.error().message() << " in response to: " << message; 1118 return QString(); 1119 } 1120 return reply.value(); 1121 } 1122 1123 double RegistryPrivate::minimumValue(const AccessibleObject &object) const 1124 { 1125 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Value"), QLatin1String("MinimumValue")); 1126 return v.toDouble(); 1127 } 1128 1129 double RegistryPrivate::maximumValue(const AccessibleObject &object) const 1130 { 1131 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Value"), QLatin1String("MaximumValue")); 1132 return v.toDouble(); 1133 } 1134 1135 double RegistryPrivate::minimumValueIncrement(const AccessibleObject &object) const 1136 { 1137 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Value"), QLatin1String("MinimumIncrement")); 1138 return v.toDouble(); 1139 } 1140 1141 double RegistryPrivate::currentValue(const AccessibleObject &object) const 1142 { 1143 QVariant v = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Value"), QLatin1String("CurrentValue")); 1144 return v.toDouble(); 1145 } 1146 1147 bool RegistryPrivate::setCurrentValue(const AccessibleObject &object, double value) 1148 { 1149 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Value"), QLatin1String("SetCurrentValue")); 1150 1151 QVariantList arguments; 1152 arguments << QLatin1String("org.a11y.atspi.Value") << QLatin1String("CurrentValue"); 1153 arguments << QVariant::fromValue(QDBusVariant(value)); 1154 message.setArguments(arguments); 1155 1156 QDBusReply<bool> reply = conn.connection().call(message); 1157 if (!reply.isValid()) { 1158 qWarning() << "Could not set text." << reply.error().message(); 1159 return false; 1160 } 1161 return reply.value(); 1162 } 1163 1164 QList<AccessibleObject> RegistryPrivate::selection(const AccessibleObject &object) const 1165 { 1166 QList<AccessibleObject> result; 1167 int count = getProperty(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Selection"), QLatin1String("CurrentValue")).toInt(); 1168 for(int i = 0; i < count; ++i) { 1169 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Selection"), QLatin1String("GetSelectedChild")); 1170 QDBusReply<QSpiObjectReference> reply = conn.connection().call(message); 1171 if (!reply.isValid()) { 1172 qWarning() << "Could not access selection." << reply.error().message(); 1173 return QList<AccessibleObject>(); 1174 } 1175 const QSpiObjectReference ref = reply.value(); 1176 result.append(AccessibleObject(const_cast<RegistryPrivate*>(this), ref.service, ref.path.path())); 1177 } 1178 return result; 1179 } 1180 1181 QString RegistryPrivate::imageDescription(const AccessibleObject &object) const 1182 { 1183 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Image"), QLatin1String("ImageDescription")); 1184 QDBusReply<QString> reply = conn.connection().call(message); 1185 if (!reply.isValid()) { 1186 qWarning() << "Could not access imageDescription." << reply.error().message(); 1187 return QString(); 1188 } 1189 return reply.value(); 1190 } 1191 1192 QString RegistryPrivate::imageLocale(const AccessibleObject &object) const 1193 { 1194 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Image"), QLatin1String("ImageLocale")); 1195 QDBusReply<QString> reply = conn.connection().call(message, QDBus::Block, 500); 1196 if (!reply.isValid()) { 1197 qWarning() << "Could not access imageLocale." << reply.error().message(); 1198 return QString(); 1199 } 1200 return reply.value(); 1201 } 1202 1203 QRect RegistryPrivate::imageRect(const AccessibleObject &object) const 1204 { 1205 QDBusMessage message = QDBusMessage::createMethodCall(object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Image"), QLatin1String("GetImageExtents")); 1206 QVariantList args; 1207 quint32 coords = ATSPI_COORD_TYPE_SCREEN; 1208 args << coords; 1209 message.setArguments(args); 1210 QDBusReply<QRect> reply = conn.connection().call(message); 1211 if (!reply.isValid()) { 1212 qWarning() << "Could not access imageRect." << reply.error().message(); 1213 return QRect(); 1214 } 1215 return QRect( reply.value() ); 1216 } 1217 1218 QVector< QSharedPointer<QAction> > RegistryPrivate::actions(const AccessibleObject &object) 1219 { 1220 QDBusMessage message = QDBusMessage::createMethodCall ( 1221 object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Action"), QLatin1String("GetActions")); 1222 1223 QDBusReply<QSpiActionArray> reply = conn.connection().call(message, QDBus::Block, 500); 1224 if (!reply.isValid()) { 1225 qWarning() << "Could not access actions." << reply.error().message(); 1226 return QVector< QSharedPointer<QAction> >(); 1227 } 1228 1229 QSpiActionArray actionArray = reply.value(); 1230 QVector< QSharedPointer<QAction> > list; 1231 for(int i = 0; i < actionArray.count(); ++i) { 1232 const QSpiAction &a = actionArray[i]; 1233 QAction *action = new QAction(); 1234 QString id = QString(QLatin1String("%1;%2;%3")).arg(object.d->service).arg(object.d->path).arg(i); 1235 action->setObjectName(id); 1236 action->setText(a.name); 1237 action->setWhatsThis(a.description); 1238 QKeySequence shortcut(a.keyBinding); 1239 action->setShortcut(shortcut); 1240 m_actionMapper.setMapping(action, id); 1241 connect(action, SIGNAL(triggered()), &m_actionMapper, SLOT(map())); 1242 list.append(QSharedPointer<QAction>(action)); 1243 } 1244 return list; 1245 } 1246 1247 void RegistryPrivate::actionTriggered(const QString &action) 1248 { 1249 QStringList actionParts = action.split(QLatin1Char(';')); 1250 Q_ASSERT(actionParts.count() == 3); 1251 QString service = actionParts[0]; 1252 QString path = actionParts[1]; 1253 int index = actionParts[2].toInt(); 1254 1255 QDBusMessage message = QDBusMessage::createMethodCall ( 1256 service, path, QLatin1String("org.a11y.atspi.Action"), QLatin1String("DoAction")); 1257 1258 QVariantList args; 1259 args << index; 1260 message.setArguments(args); 1261 1262 QDBusReply<bool> reply = conn.connection().call(message, QDBus::Block, 500); 1263 if (!reply.isValid()) { 1264 qWarning() << "Could not execute action=" << action << reply.error().message(); 1265 return; 1266 } 1267 1268 if (reply.value()) { 1269 qDebug() << "Successful executed action=" << action; 1270 } else { 1271 qWarning() << "Failed to execute action=" << action; 1272 } 1273 } 1274 1275 QVariant RegistryPrivate::getProperty(const QString &service, const QString &path, const QString &interface, const QString &name) const 1276 { 1277 QVariantList args; 1278 args.append(interface); 1279 args.append(name); 1280 1281 QDBusMessage message = QDBusMessage::createMethodCall ( 1282 service, path, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get")); 1283 1284 message.setArguments(args); 1285 QDBusMessage reply = conn.connection().call(message, QDBus::Block, 500); 1286 if (reply.arguments().isEmpty()) 1287 return QVariant(); 1288 1289 QDBusVariant v = reply.arguments().at(0).value<QDBusVariant>(); 1290 return v.variant(); 1291 } 1292 1293 AccessibleObject RegistryPrivate::accessibleFromPath(const QString &service, const QString &path) const 1294 { 1295 return AccessibleObject(const_cast<RegistryPrivate*>(this), service, path); 1296 } 1297 1298 AccessibleObject RegistryPrivate::accessibleFromReference(const QSpiObjectReference &reference) const 1299 { 1300 return accessibleFromPath(reference.service, reference.path.path()); 1301 } 1302 1303 AccessibleObject RegistryPrivate::accessibleFromContext() const 1304 { 1305 return accessibleFromPath(QDBusContext::message().service(), QDBusContext::message().path()); 1306 } 1307 1308 void RegistryPrivate::slotWindowCreate(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &) 1309 { 1310 Q_EMIT q->windowCreated(accessibleFromContext()); 1311 } 1312 1313 void RegistryPrivate::slotWindowDestroy(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1314 { 1315 Q_EMIT q->windowDestroyed(accessibleFromContext()); 1316 } 1317 1318 void RegistryPrivate::slotWindowClose(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1319 { 1320 Q_EMIT q->windowClosed(accessibleFromContext()); 1321 } 1322 1323 void RegistryPrivate::slotWindowReparent(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1324 { 1325 Q_EMIT q->windowReparented(accessibleFromContext()); 1326 } 1327 1328 void RegistryPrivate::slotWindowMinimize(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1329 { 1330 Q_EMIT q->windowMinimized(accessibleFromContext()); 1331 } 1332 1333 void RegistryPrivate::slotWindowMaximize(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1334 { 1335 Q_EMIT q->windowMaximized(accessibleFromContext()); 1336 } 1337 1338 void RegistryPrivate::slotWindowRestore(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1339 { 1340 Q_EMIT q->windowRestored(accessibleFromContext()); 1341 } 1342 1343 void RegistryPrivate::slotWindowActivate(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1344 { 1345 Q_EMIT q->windowActivated(accessibleFromContext()); 1346 } 1347 1348 void RegistryPrivate::slotWindowDeactivate(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1349 { 1350 Q_EMIT q->windowDeactivated(accessibleFromContext()); 1351 } 1352 1353 void RegistryPrivate::slotWindowDesktopCreate(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1354 { 1355 Q_EMIT q->windowDesktopCreated(accessibleFromContext()); 1356 } 1357 1358 void RegistryPrivate::slotWindowDesktopDestroy(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1359 { 1360 Q_EMIT q->windowDesktopDestroyed(accessibleFromContext()); 1361 } 1362 1363 void RegistryPrivate::slotWindowRaise(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1364 { 1365 Q_EMIT q->windowRaised(accessibleFromContext()); 1366 } 1367 1368 void RegistryPrivate::slotWindowLower(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1369 { 1370 Q_EMIT q->windowLowered(accessibleFromContext()); 1371 } 1372 1373 void RegistryPrivate::slotWindowMove(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1374 { 1375 Q_EMIT q->windowMoved(accessibleFromContext()); 1376 } 1377 1378 void RegistryPrivate::slotWindowResize(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1379 { 1380 Q_EMIT q->windowResized(accessibleFromContext()); 1381 } 1382 1383 void RegistryPrivate::slotWindowShade(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1384 { 1385 Q_EMIT q->windowShaded(accessibleFromContext()); 1386 } 1387 1388 void RegistryPrivate::slotWindowUnshade(const QString &state, int detail1, int detail2, const QDBusVariant &/*args*/, const QAccessibleClient::QSpiObjectReference &reference) 1389 { 1390 Q_EMIT q->windowUnshaded(accessibleFromContext()); 1391 } 1392 1393 void RegistryPrivate::slotPropertyChange(const QString &property, int detail1, int detail2, const QDBusVariant &args, const QSpiObjectReference &reference) 1394 { 1395 #ifdef ATSPI_DEBUG 1396 qDebug() << Q_FUNC_INFO << property << detail1 << detail2 << args.variant() << reference.path.path(); 1397 #endif 1398 if (property == QLatin1String("accessible-name")) { 1399 Q_EMIT q->accessibleNameChanged(accessibleFromContext()); 1400 } else if (property == QLatin1String("accessible-description")) { 1401 Q_EMIT q->accessibleDescriptionChanged(accessibleFromContext()); 1402 } 1403 } 1404 1405 void RegistryPrivate::slotStateChanged(const QString &state, int detail1, int detail2, const QDBusVariant &object, const QSpiObjectReference &reference) 1406 { 1407 //qDebug() << Q_FUNC_INFO << state << detail1 << detail2 << reference.service << reference.path.path() << QDBusContext::message(); 1408 1409 if (state == QLatin1String("defunct") && (detail1 == 1)) { 1410 QSpiObjectReference removed; 1411 removed.service = QDBusContext::message().service(); 1412 removed.path = QDBusObjectPath(QDBusContext::message().path()); 1413 removeAccessibleObject(removed); 1414 return; 1415 } 1416 1417 AccessibleObject accessible = accessibleFromContext(); 1418 if (m_cache) { 1419 m_cache->cleanState(accessible); 1420 } 1421 1422 if (state == QLatin1String("focused") && (detail1 == 1) && 1423 (q->subscribedEventListeners().testFlag(Registry::Focus))) { 1424 Q_EMIT q->focusChanged(accessible); 1425 } 1426 1427 if (q->subscribedEventListeners().testFlag(Registry::StateChanged)) { 1428 Q_EMIT q->stateChanged(accessible, state, detail1 == 1); 1429 } 1430 } 1431 1432 // void RegistryPrivate::slotLinkSelected(const QString &/*state*/, int /*detail1*/, int /*detail2*/, const QDBusVariant &args, const QAccessibleClient::QSpiObjectReference &reference) 1433 // { 1434 // Q_EMIT q->linkSelected(accessibleFromContext()); 1435 // } 1436 1437 bool RegistryPrivate::removeAccessibleObject(const QAccessibleClient::AccessibleObject &accessible) 1438 { 1439 Q_ASSERT(accessible.isValid()); 1440 if (m_cache) { 1441 const QString id = accessible.id(); 1442 if (m_cache->remove(id)) { 1443 Q_EMIT q->removed(accessible); 1444 } 1445 } else { 1446 Q_EMIT q->removed(accessible); 1447 } 1448 if (accessible.d) 1449 accessible.d->setDefunct(); 1450 return true; 1451 } 1452 1453 bool RegistryPrivate::removeAccessibleObject(const QAccessibleClient::QSpiObjectReference &reference) 1454 { 1455 QAccessibleClient::AccessibleObject acc = accessibleFromReference(reference); 1456 if (acc.isValid()) { 1457 if (removeAccessibleObject(acc)) 1458 return true; 1459 } 1460 return false; 1461 } 1462 1463 void RegistryPrivate::slotChildrenChanged(const QString &state, int detail1, int detail2, const QDBusVariant &args, const QAccessibleClient::QSpiObjectReference &reference) 1464 { 1465 // qDebug() << Q_FUNC_INFO << state << detail1 << detail2 << args.variant() << reference.path.path(); 1466 QAccessibleClient::AccessibleObject parentAccessible = accessibleFromContext(); 1467 if (!parentAccessible.isValid()) { 1468 qWarning() << Q_FUNC_INFO << "Children change with invalid parent." << reference.path.path(); 1469 return; 1470 } 1471 1472 int index = detail1; 1473 if (state == QLatin1String("add")) { 1474 Q_EMIT q->childAdded(parentAccessible, index); 1475 } else if (state == QLatin1String("remove")) { 1476 Q_EMIT q->childRemoved(parentAccessible, index); 1477 } else { 1478 qWarning() << "Invalid state in ChildrenChanged." << state; 1479 } 1480 } 1481 1482 void RegistryPrivate::slotVisibleDataChanged(const QString &/*state*/, int /*detail1*/, int /*detail2*/, const QDBusVariant &args, const QAccessibleClient::QSpiObjectReference &reference) 1483 { 1484 Q_EMIT q->visibleDataChanged(accessibleFromContext()); 1485 } 1486 1487 void RegistryPrivate::slotSelectionChanged(const QString &/*state*/, int /*detail1*/, int /*detail2*/, const QDBusVariant &args, const QAccessibleClient::QSpiObjectReference &reference) 1488 { 1489 Q_EMIT q->selectionChanged(accessibleFromContext()); 1490 } 1491 1492 void RegistryPrivate::slotModelChanged(const QString &/*state*/, int /*detail1*/, int /*detail2*/, const QDBusVariant &args, const QAccessibleClient::QSpiObjectReference &reference) 1493 { 1494 Q_EMIT q->modelChanged(accessibleFromContext()); 1495 } 1496 1497 void RegistryPrivate::slotTextCaretMoved(const QString &/*state*/, int detail1, int /*detail2*/, const QDBusVariant &/*args*/, const QSpiObjectReference &reference) 1498 { 1499 Q_EMIT q->textCaretMoved(accessibleFromContext(), detail1); 1500 } 1501 1502 void RegistryPrivate::slotTextSelectionChanged(const QString &/*state*/, int /*detail1*/, int /*detail2*/, const QDBusVariant &/*args*/, const QSpiObjectReference &reference) 1503 { 1504 Q_EMIT q->textSelectionChanged(accessibleFromContext()); 1505 } 1506 1507 void RegistryPrivate::slotTextChanged(const QString &change, int start, int end, const QDBusVariant &textVariant, const QSpiObjectReference &reference) 1508 { 1509 AccessibleObject object(accessibleFromContext()); 1510 QString text = textVariant.variant().toString(); 1511 1512 if (change == QLatin1String("insert")) { 1513 Q_EMIT q->textInserted(object, text, start, end); 1514 } else if (change == QLatin1String("remove")) { 1515 Q_EMIT q->textRemoved(object, text, start, end); 1516 } else { 1517 Q_EMIT q->textChanged(object, text, start, end); 1518 } 1519 } 1520 1521 #include "moc_registry_p.cpp"