(?source)
Requests from the screen reader
The Orca screen reader can explicitly request for information for a given widget of a given application, for instance getText:
- Orca calls pyatspi's
getText
method on a pyatspi object corresponding to the widget - pyatspi's
getText
method (implemented inpyatspi/pyatspi/text.py
) callsAtspi.Text.get_text
, which is a python binding for the Catspi_text_get_text
function fromlibatspi.so
provided by at-spi2-core atspi_text_get_text
(implemented inat-spi2-core/atspi/atspi-text.c
) creates an RPC message for the dbus sender of the application and the path for the widget, using theorg.a11y.atspi.Text
dbus interface, and theGetText
method.
dbus transmits the message to the application.
In the case of a GTK2/3 application:
impl_GetText
(implemented inat-spi2-atk/atk-adaptor/adaptors/text-adaptor.c
) gets called by dbus, it parses the parameters (offsets of beginning and end), and callsatk_text_get_text
atk_text_get_text
(implemented inatk1.0/./atk/atktext.c
) calls theget_text
method of the accessible object corresponding to the widget, for instance a textcell.gail_text_cell_get_text
(implemented in the gail module of gtk,gtk+2.0/modules/other/gail/gailtextcell.c
orgtk_text_cell_accessible_get_text
ingtk+3.0/gtk/a11y/gtktextcellaccessible.c
) fetches the text from the widget corresponding to the accessible object and returns itatk_text_get_text
returns itimpl_GetText
stuffes the string into a dbus response
TODO: In the case of a GTK4 application
In the case of a Java application:
impl_GetText
andatk_text_get_text
get called like for a GTK application, theget_text
method isjaw_text_get_text
jaw_text_get_text
(implemented injava-atk-wrapper/jni/src/jawtext.c
) calls theget_text
method of theAtkText
java classget_text
(implemented injava-atk-wrapper/wrapper/org/GNOME/Accessibility/AtkText.java
) uses thegetAtIndex
method of theAccessibleExtendedText
interface of the widget and returns the text.atk_text_get_text
returns itimpl_GetText
stuffes the string into a dbus response
In the case of mozilla:
impl_GetText
andatk_text_get_text
get called like for a GTK application, theget_text
method isgetTextCB
getTextCB
(implemented inmozilla/accessible/atk/nsMaiInterfaceText.cpp
) uses theTextSubstring
of theHyperTextAccessible
class.
In the case of a Qt4 application:
AtSpiAdaptor::textInterface
(implemented inqt-at-spi/src/atspiadaptor.cpp
) gets called by qt dbus, it parses the parameters, and calls thetext
method of thetextInterface
of theQAccessibleInterface
class.QAccessibleTextWidget::text
(implemented inqt4-x11/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
) fetches the text and returns it.AtSpiAdaptor::textInterface
stuffes the string into a dbus response.
In the case of a Qt5 application:
AtSpiAdaptor::textInterface
(implemented in qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp`) gets called by qt dbus, the rest is happening as with Qt4.
dbus transmits the response to the application.
atspi_text_get_text
gets the string from the response and returns it
Notifications from the application
The application can notify about e.g. an insertion of text in a widget. The Orca screen reader must first register for getting the event, before the toolkit will only send events if there are listeners for them:
- The default
getListeners
method (implemented inorca/src/orca/scripts/default.py
) returns to callonTextInserted
onobject:text-changed:insert
signal registerScriptListeners
(implemented inorca/src/orca/event_manager.py
) calls_registerListener
to record a callback to_enqueue
on that signal_registerListener
callsregistry.registerEventListener
for this.registerEventListener
(implemented inpython-atspi/pyatspi/registry.py
) callsAtspi.EventListener.register
, which is a Python binding for the Catspi_event_listener_register
function.atspi_event_listener_register
(implemented inat-spi2-core/atspi/atspi-event-listener.c
) usesdbus_bus_add_match
on"org.a11y.atspi.Event"
to make dbus make the_enqueue
callback when the event is received. It also makes an RPC to the at-spi-registryd (conventional dbus name"org.a11y.atspi.Registry"
), on the"/org/a11y/atspi/registry"
path, the"org.a11y.atspi.Registry"
interface,RegisterEvent
method, to tell the registry to start notifying Orca about these events.
dbus transmits the RPC to at-spi2-registryd.
impl_register_event
(implemented inat-spi2-core/registryd/registry.c
) parses the request, records the registration in theregistry->events
list, and sends aEventListenerRegistered
signal on the bus
In the case of a GTK2/3 application (quite unsure about the details):
- When receiving the
EventListenerRegistered
signal insignal_filter
(implemented inat-spi2-atk/atk-adaptor/bridge.c
),handle_event_listener_registered
is called handle_event_listener_registered
adds the event listening registration to theevents
list.The Atk adaptor has added in
spi_atk_register_event_listeners
(implemented inat-spi2-atk/atk-adaptor/event.c
)text_changed_event_listener
as listener for signals"Gtk:AtkText:text-insert"
and"Gtk:AtkText:text-changed"
- Atk has added in
atk_text_base_init
(implemented inatk1.0/atk/atktext.c
) the"text-insert"
signal. Gail has added
gail_text_cell_update_cache
as update_cache callbackTODO textcell to
text_insert
signalgail_text_cell_update_cache
(implemented ingtk+2.0/modules/other/gail/gailtextcell.c
orgtk_text_cell_accessible_update_cache
ingtk+3.0/gtk/a11y/gtktextcellaccessible.c
) emits the"text_changed::insert"
glib signal.text_changed_event_listener
(implemented inat-spi2-atk/atk-adaptor/event.c
) callsemit_event
emit_event
checkssignal_is_needed
before emitting thetext-changed:insert
event on the bus.signal_is_needed
checks whether the signal is in theevents
list.
TODO: In the case of a GTK4 application
TODO: In the case of a Qt application
TODO: In the case of a Java application
jaw_impl_class_init sets jaw_impl_initialize as initializer for atk class
when receiving events about a yet-unseen object, jaw_impl_get_instance calls atk_object_initialize
- atk_object_initialize calls the atk class initializer, jaw_impl_initialize
- jaw_impl_initialize calls org.GNOME.Accessibility.AtkWrapper::registerPropertyChangeListener
registerPropertyChangeListener calls AccessibleContext::addPropertyChangeListener to register propertyChangeListener to beans
AtkWrapper.java's propertyChangeListener's propertyChange get called, calls org.GNOME.Accessibility.AtkWrapper::dispatchFocusEvent.
- dispatchFocusEvent calls focusNotify (implemented in C function Java_org_GNOME_Accessibility_AtkWrapper_focusNotify)
- Java_org_GNOME_Accessibility_AtkWrapper_focusNotify uses jni_main_idle_add or gdk_threads_add_idle to record having to call focus_notify_handler later.
- The glib loop calls focus_notify_handler.
- focus_notify_handler calls atk_object_notify_state_change
- atk_object_notify_state_change emits the signal
- The rest is like gtk
TODO: In the case of mozilla
dbus transmits the event on the bus.
- In Orca, the dbus filter calls
_enqueue
_enqueue
(implemented inorca/src/orca/event_manager.py
) calls_addToQueue
_addToQueue
queues an event- glib idle loop calls
_dequeue
. _dequeue
dequeues an event and calls_processObjectEvent
_processObjectEvent
callsprocessObjectEvent
processObjectEvent
(implemented inorca/src/orca/script.py
) calls the listener forobject:text-changed:insert
.onTextInserted
(implemented inorca/src/orca/scripts/default.py
for instance) updates the user output.
Startup
In the case of a GTK application:
TODO
In the case of a java application:
The javax.accessibility.assistive_technologies system property, or assistive_technologies file property contains the name of the class to load. It is loaded by loadAssistiveTechnologies, called from getDefaultToolkit in src/jdk/src/share/classes/java/awt/Toolkit.java
In the case of a mozilla application:
TODO
In the case of a QT4 application:
TODO
In the case of a QT5 application:
TODO