GNOME Accessibility Logo

GNOME Accessibility Team

GNOME 2 - Mechanics

/!\ The following content is being kept here for historical preservation only. The information contained herein may or may not be accurate. It is definitely not being maintained.

This page provides information on how the GNOME Accessibility infrastructure is launched in GNOME 2 and how things tie together.

Login Screen (gdm)

gdm is launched via the /usr/sbin/gdm script. gdm looks at /etc/X11/gdm/custom.conf and /usr/share/gdm/defaults.conf for the configuration settings. The gdm *.conf file contains a line like the following:

SessionDesktopDir=/etc/X11/sessions/:/etc/X11/dm/Sessions/:/usr/share/gdm/BuiltInSessions/:/usr/share/xsessions/

The SessionDesktopDir value represents a PATH-like structure, where each directory in the path can contain *.desktop files. Each *.desktop file contains an Exec line. These are glommed together to give you the sessions you can choose from (e.g., GNOME, failsafe terminal, etc.).

All said and done, the typical scenario is that once the user has authenticated with gdm, gdm launches uses /usr/share/xsessions/gnome.desktop as the session, and this ultimately results in gnome-session being launched as the user.

Accessible Login

See http://library.gnome.org/users/gnome-access-guide/stable/sysadmin-27.html.en.

WDW: add notes on what is really happening underneath, especially with respect to the gdm D-Bus session and Bonobo. What's needed here is a description of how the at-spi-registryd is launched and how the gdm GUI interacts with it. Also need a section on what can go wrong. A typical problem is that the assistive technology launches, but is not able to connect with the gdm GUI. This can be a disconnect between the D-Bus stuff or that the gdm GUI was launched without accessibility enabled. If I recall, something like an AT poking a gconf setting could make D-Bus launch.

gnome-session

See http://git.gnome.org/cgit/gnome-session/tree/gnome-session/main.c

The very first thing gnome-session does is ensure that there is a D-Bus session. If a D-Bus session doesn't exist (as determined by the absence of a DBUS_SESSION_BUS_ADDRESS environment variable), gnome-session execvp's dbus-launch --exit-with-session.

Note that it is important that D-Bus be launched for the session. This avoids a problem with Bonobo activation where we can end up with multiple Bonobo activation servers and/or multiple at-spi-registryd processes. In a nutshell: for a client to talk to bonobo-activation-server it needs to know the IOR of the bonobo-activation-server. The IOR is written to a file in /tmp and the name of that file is based on DBUS_SESSION_BUS_ADDRESS. Clients use DBUS_SESSION_BUS_ADDRESS to construct the name of the file, open the file, read the IOR and then communicate with the bonobo-activation-server over ORBit. If one launches a bonobo-activation-server before D-Bus is launched, we get one bonobo-activation-server and if we launch another after D-Bus, we get another. This is why we can end up with multiple at-spi-registryd processes. So, the bonobo-activation-server should only be launched after D-Bus is launched.

WDW: who else might launch the D-Bus daemon for the session? Note that this is not meant in the pedantic sense, but more in the "what existing real world conditions are out there that launch the D-Bus daemon for the session prior to gnome-session" sense. If I recall, something like an AT poking a gconf setting could make D-Bus launch.

Once the user has authenticated with gdm, gdm launches gnome-session as the user. gnome-session looks to the gconf /desktop/gnome/session/default_session key to find the name of the binary to launch. It is typically gnome-settings-daemon.

Also, the /desktop/gnome/session/required_components_list key is a list of things that must be started. These typically are [windowmanager,panel,filemanager]. Under the /desktop/gnome/session/required_components section, you'll find keys for each one of these, with each value being the name of the binary to run for the component.

Finally, gnome-session looks at the desktop files in /usr/share/gnome/autostart/*.desktop to find other things it should launch when the session starts. These *.desktop files have conditions in them to say whether they should autostart or not. This is where the at-spi-registryd is launched (see below). Note that the *.desktop files can have a field named X-GNOME-Autostart-Phase. The at-spi-registryd's value is Initialization, which lets it start very early.

Once it has figured everything out, gnome-session launches the XSMP server, the relevant autostart apps from /usr/share/gnome/autostart/*.desktop, /etc/xdg/autostart/*.desktop, etc., (i.e., the ones whose conditions match the autostart conditions), the required components from /desktop/gnome/session/required_components_list, and gnome-settings-daemon.

WDW: Which GUI components, if any, does gnome-session launch on its own (e.g., the logout dialog)?

at-spi-registryd

The at-spi-registryd is the daemon that ties everything together and lets assistive technologies communicate with applications.

gnome-session has an at-spi-registryd-wrapper.desktop that gets installed to /usr/share/gnome/autostart/at-spi-registryd-wrapper.desktop. Via the following line, this file looks to the gconf /desktop/gnome/interface/accessibility boolean property to determine if it should start or not:

AutostartCondition=GNOME /desktop/gnome/interface/accessibility

This boolean property is the same boolean property that is set by the "System/Preferences/Assistive Technologies" dialog. It is setup and owned by libgnome: http://git.gnome.org/cgit/libgnome/tree/schemas/desktop_gnome_interface.schemas.in.in. If the boolean value is True, gnome-session launches the wrapper (/usr/lib/gnome-session/helpers/at-spi-registryd-wrapper). The wrapper does two things: 1) Makes sure the GTK_MODULES environment variable has gail:atk-bridge in it, allowing GTK+ applications to participate in the AT-SPI infrastructure, and 2) executes the at-spi-registryd, which serves as the connection point between assistive technologies and GUi applications. Note that the wrapper will no longer be needed in the future as part of https://bugzilla.gnome.org/show_bug.cgi?id=578334. Note also that through D-Bus activation, the *.desktop file will not be needed at all.

at-spi-registryd adds the AT_SPI_IOR property to the root window, telling other clients how to reach it (see http://git.gnome.org/cgit/at-spi/tree/registryd/registry-main.c).

Note that at-spi-registryd can also to be launched by Bonobo activation. It still ships a /usr/lib/bonobo/servers/Accessibility_Registry.server. This has the potential to cause multiple at-spi-registryd processes to get launched. WDW - wonders if this is what causes the accessibility of gdm to be flakey at times.

gnome-settings-daemon

The gnome-settings-daemon has gconf properties it uses for accessibility. The main gconf key is /apps/gnome_settings_daemon/gtk-modules. This holds several other keys, where the key name is a set of GTK+ modules to load and the value is the condition under which they should be loaded. For accessibility, the key is gail:atk-bridge and the value is /desktop/gnome/interface/accessibility, which is the same boolean property used everywhere that specifies whether accessibility should be enabled or not. The end result is that gnome-settings-daemon sets the XSETTINGS "Gtk/Modules" property on the screen (http://git.gnome.org/cgit/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c). GTK+ then looks to this property to load the accessibility modules (see below).

WDW: need to describe what might go wrong here (e.g., schemas might not be installed) and commands to type to check things out.

GTK+ and Accessibility

See http://library.gnome.org/devel/accessibility-devel-guide/stable/gad-how-it-works.html.en for an overview of ATK and GAIL. In order for a GTK+ application to participate in the assistive technology infrastructure, it needs to load the GAIL module (/usr/lib/gtk-2.0/modules/libgail.so) to provide accessible ATK peers for GTK+ controls and the ATK Bridge module (//usr/lib/gtk-2.0/modules/libatk-bridge.so) to communicate with assistive technologies. GTK+ knows to load the assistive technology support via the following means:

  • The "old" way (which still works): The GTK_MODULES environment variable defines any modules GTK+ should load (see http://git.gnome.org/cgit/gtk+/tree/gtk/gtkmain.c). Including gail:atk-bridge in GTK_MODULES will load the accessibility infrastructure.

  • The "new" way: XSETTINGS "Gtk/Modules" property. GTK+ observes the XSETTINGS "Gtk/Modules" property on the screen and uses it to determine which modules it should load (see http://git.gnome.org/cgit/gtk+/tree/gtk/gtkmodules.c). This XSETTINGS property is set by the gnome-settings-daemon (see above). With this mechanism, the GTK_MODULES environment variable is unnecessary. This work requires gnome-settings-daemon from at least GNOME 2.24.

Note that the initialization of GAIL can be delayed by setting the NO_GAIL environment variable. If this is done, the gail_accessibility_module_init method of the GAIL module will not be called when the GTK+ gail module is loaded (see https://bugzilla.gnome.org/show_bug.cgi?id=565110 and http://git.gnome.org/cgit/gtk+/tree/modules/other/gail/gail.c). This can be necessary with an application that needs to load atk-bridge to export its ATK objects but not gail. The example is Mono, which uses Gtk+ only for theming.

Note that the initialization of the ATK Bridge can be delayed by setting the NO_AT_BRIDGE environment variable. If this is done, the atk_bridge_init method of the ATK Bridge will not be called when the GTK+ atk-bridge module is loaded (see https://bugzilla.gnome.org/show_bug.cgi?id=563943 and http://git.gnome.org/cgit/at-spi/tree/atk-bridge/bridge.c). This can be necessary with an application that mixes accessible toolkits (e.g., GTK+ and Gecko) and needs to make sure the accessible hierarchy is set up appropriately.

Gecko Accessibility

OOo Accessibility

Java Accessibility

Applications Running as root

Describe how this works. That is, how a GUI application running as root can connect to the at-spi-registryd that is running as the user. Also describe the issues involved. In particular, the gksu keyboard grab as well as GNOME keyring issues (https://bugzilla.gnome.org/show_bug.cgi?id=447435#c9).

Automatically Launching Assistive Technologies

See the notes on how this is done via gnome-session. In a nutshell, there are /desktop/gnome/applications/at/mobility and /desktop/gnome/applications/at/visual gconf properties. These both have an exec property that is the name of the binary and a startup property that is a boolean that specifies whether or not it should start on login. The sequence of events is this:

For future reference, the gconf /desktop/gnome/applications/at property holds three boolean values: screen_keyboard_enabled (for GOK, Dasher, etc.), screen_magnifier_enabled (for Orca), and screen_reader_enabled (for Orca). These are currently unused. The idea, however, is that we'd put a line like the following in an assistive technology's *.desktop file and it would just launch:

AutostartCondition=GNOME /desktop/gnome/applications/at/screen_reader_enabled

A11y-related GConf Keys

WDW: who registers listeners for changes in all these key values and what the listeners do when they detect a change?

Key name

Owner

Purpose

/desktop/gnome/interface/accessibility

libgnome

Enables the AT-SPI infrastructure. Currently, this is not dynamic for the desktop and needs to be set prior to launching a GUI. This key can be set many ways. The main UI for doing so is the gnome-at-properties applet owned by gnome-control-center

/apps/gnome_settings_daemon/gtk-modules/gail:atk-bridge

at-spi

Used by gnome-settings-daemon to tell GTK+ which GTK modules to load. WDW - at-spi2-atk needs to define this, too!

These tend to be changed by the gnome-appearance-properties applet owned by gnome-control-center.

Key name

Owner

Purpose

/desktop/gnome/interface/icon_theme

libgnome

Icon theme to use for the panel, nautilus etc. WDW - I think the actual themes live in gnome-themes and you refer to them by their directory name (e.g., HighContrast).

/desktop/gnome/interface/gtk_theme

libgnome

Basename of the default theme used by gtk+.

/desktop/gnome/interface/font_name

libgnome

Name of the default font used by gtk+. (e.g., Sans 10)

/desktop/gnome/interface/document_font_name

libgnome

Name of the default font used for reading documents. (e.g., Sans 10)

/desktop/gnome/interface/use_custom_font

libgnome

Whether to use a custom font in gtk+ applications.

/desktop/gnome/interface/toolbar_icons_size

libgnome

Size of icons in toolbars, either "small-toolbar" or "large-toolbar".

Assistive Technology Keys for Screen Magnifier, Screen Reader, and On Screen Keyboard

Here's stuff provided by the gnome-settings-daemon, which I think is new as of the new gdm:

/desktop/gnome/applications/at/screen_magnifier_enabled

gnome-settings-daemon

Whether the screen magnifier is turned on. WDW: which *.desktop file (if any) listens to this?

/desktop/gnome/keybindings/magnifier/binding

gnome-settings-daemon

Binding to toggle the magnifier.

/desktop/gnome/keybindings/magnifier/action

gnome-settings-daemon

Command used to turn the magnifier on and off (gconftool-2 --toggle /desktop/gnome/applications/at/screen_magnifier_enabled)

/desktop/gnome/applications/at/screen_reader_enabled

gnome-settings-daemon

Whether the screen reader is turned on. WDW: which *.desktop file (if any) listens to this?

/desktop/gnome/keybindings/screenreader/binding

gnome-settings-daemon

Binding to toggle the screen reader.

/desktop/gnome/keybindings/screenreader/action

gnome-settings-daemon

Command used to turn the screen reader on and off (gconftool-2 --toggle /desktop/gnome/applications/at/screen_reader_enabled)

/desktop/gnome/applications/at/screen_keyboard_enabled

gnome-settings-daemon

Whether the on-screen keyboard is turned on. WDW: which *.desktop file (if any) listens to this?

/desktop/gnome/keybindings/onscreenkeyboard/binding

gnome-settings-daemon

Binding to toggle the on screen keyboard.

/desktop/gnome/keybindings/onscreenkeyboard/action

gnome-settings-daemon

Command used to turn the on screen keyboard on and off (gconftool-2 --toggle /desktop/gnome/applications/at/screen_keyboard_enabled)

Here's stuff from gdm -- seems to duplicate the above:

/apps/gdm/simple-greeter/accessibility/screen_keyboard_enabled

/apps/gdm/simple-greeter/accessibility/screen_magnifier_enabled

/apps/gdm/simple-greeter/accessibility/screen_reader_enabled

/apps/gdm/simple-greeter/settings-manager-plugins/a11y-keyboard/active

Here's older stuff. See the "Automatically Launching Assistive Technologies" section above for how they are used:

/desktop/gnome/accessibility/startup/exec_ats

libgnome

List of assistive technology applications to start when logging into the GNOME desktop.

/desktop/gnome/applications/at/mobility/exec

libgnome

Preferred Mobility assistive technology application to be used for login, menu, or command line. WDW - the default is dasher. It probably should be gok.

/desktop/gnome/applications/at/mobility/startup

libgnome

Start preferred Mobility assistive technology application (True or False)

/desktop/gnome/applications/at/visual/exec

libgnome

Preferred Visual assistive technology application be used for login, menu, or command line.

/desktop/gnome/applications/at/visual/startup

libgnome

Start preferred Visual assistive technology application (True or False)

AccessX Keys

These are the StickyKeys, SlowKeys, etc., features. They are set by the gnome-keyboard-properties applet owned by gnome-control-center and monitored by the accessx-status applet of gnome-applets.

/apps/gnome_settings_daemon/plugins/a11y-keyboard/active

gnome-settings-daemon

Enable accessibility keyboard plugin (i.e., the accessx-status applet). This is set by the "Accessibility features can be toggled with keyboard shortcuts" checkbox of the gnome-keyboard-properties applet.

/desktop/gnome/accessibility/keyboard/feature_state_change_beep

libgnome

?

/desktop/gnome/accessibility/keyboard/timeout_enable

libgnome

If True, turn features off after a timeout period. Useful for shared machines.

/desktop/gnome/accessibility/keyboard/timeout

libgnome

Timeout time.

/desktop/gnome/accessibility/keyboard/bouncekeys_enable

gnome-settings-daemon and libgnome

Whether the bounce keys keyboard accessibility feature is turned on.

/desktop/gnome/accessibility/keyboard/bouncekeys_delay

libgnome

Ignore multiple presses of the _same_ key within @delay milliseconds. WDW - the default value is 0, which is likely the wrong default (i.e., it basically renders BounceKeys disabled).

/desktop/gnome/accessibility/keyboard/bouncekeys_beep_reject

libgnome

Whether to beep when a key is rejected.

/desktop/gnome/accessibility/keyboard/mousekeys_enable

gnome-settings-daemon and libgnome

Whether the mouse keys keyboard accessibility feature is turned on.

/desktop/gnome/accessibility/keyboard/mousekeys_max_speed

libgnome

How many pixels per second to move at the maximum speed.

/desktop/gnome/accessibility/keyboard/mousekeys_accel_time

libgnome

How many milliseconds it takes to go from 0 to maximum speed.

/desktop/gnome/accessibility/keyboard/mousekeys_init_delay

libgnome

How many milliseconds to wait before mouse movement keys start to operate.

/desktop/gnome/accessibility/keyboard/slowkeys_enable

gnome-settings-daemon and libgnome

Whether the slow keys keyboard accessibility feature is turned on.

/desktop/gnome/accessibility/keyboard/slowkeys_delay

libgnome

Do not accept a key as being pressed unless held for @delay milliseconds. WDW - the default value is 0, which is likely wrong (i.e., it basically renders SlowKeys disabled).

/desktop/gnome/accessibility/keyboard/slowkeys_beep_press

libgnome

Whether to beep when a key is first pressed.

/desktop/gnome/accessibility/keyboard/slowkeys_beep_accept

libgnome

Whether to beep when a key is accepted.

/desktop/gnome/accessibility/keyboard/slowkeys_beep_reject

libgnome

Whether to beep when a key is rejected.

/desktop/gnome/accessibility/keyboard/stickykeys_enable

gnome-settings-daemon and libgnome

Whether the sticky keys keyboard accessibility feature is turned on.

/desktop/gnome/accessibility/keyboard/stickykeys_two_key_off

libgnome

Disable if two keys are pressed at the same time.

/desktop/gnome/accessibility/keyboard/stickykeys_modifier_beep

libgnome

Beep when a modifier is pressed.

/desktop/gnome/accessibility/keyboard/togglekeys_enable

libgnome

Beep when a locking modifier changes state.


Notes on the OLD Way

This is old stuff for reference only.

Starting the Registry (gnome-session)

The AT-SPI registry is the core of the AT-SPI infrastructure. It is the means by which applications and assistive technologies can find and talk to each other.

gnome-session starts the at-spi-registryd, which lives in libexecdir (/usr/lib on Solaris) and also sets the GTK_MODULES environment variable to include gail and atk-bridge. Here's a quick layout of the relevant code in the gnome-session module:

  • gnome-session/main.c:main

    1. main looks for the GNOME_ACCESSIBILITY environment variable (see ACCESSIBILITY_ENV in gnome-session/headers.h). If set, this environment variable overrides any gconf setting, and is an integer value that indicates whether or not to enable accessibility. "1" means to enable it, "0" means do not.

    2. main looks for the gconf ACCESSIBILITY_KEY, which is defined as "/desktop/gnome/interface/accessibility" in gnome-session/headers.h. This is the key that is set when one enables accessibility via the assistive technologies preferences dialog (the gnome-at-properties application).

    3. If it determines accessibility should be used via the above decisions, main calls gnome-session/gsm-at-startup.c:gsm_assistive_registry_start and then gsm_at_set_gtk_modules.

  • gnome-session/gsm-at-startup.c:gsm_assistive_registry_start

    1. First adds a listener for property change events on the root window property AT_SPI_IOR, which is set by the at-spi-registryd (see below).

    2. Asynchronously execs the at-spi-registryd via gsm_exec_command_line_async (command, NULL); and sets up a 5 second timer that waits for the AT_SPI_IOR property to be set. The at-spi-registryd is the thing that sets the AT_SPI_IOR property. If the timer times out, we get a "Assistive technology support has been requested for this session, but the accessibility registry was not found. Please ensure that the AT-SPI package is installed. Your session has been started without assistive technology support." dialog and then gnome-session quits. [WDW: I hit the 5 second timeout somewhat frequently on my slow machine, so I think this might need to be extended or perhaps even customizable].

  • gnome-session/gsm-at-startup.c:gsm_at_set_gtk_modules

    1. Makes sure GTK_MODULES is set (via g_setenv ("GTK_MODULES", g_strjoinv (":", modules), TRUE);) and that gail and atk-bridge are part of it.

The AT_SPI_IOR property is the way any client that has access to the X Windows display can find the AT-SPI registry. The AT-SPI registry is the way all assistive technologies can discover and interact with applications running on the desktop. The application that runs the AT-SPI registry is at-spi_registryd. Its source code lives in the registryd of the at-spi module. The relevant code that sets the AT_SPI_IOR property on the root window lives in registryd/registry-main.c:registry_set_ior.

See bug 163132 for complete details on the current implementation.

Autostarting Assistive Technologies

See the notes on how this is done via gnome-session. The nice thing is that gnome-session has been modified to stop using a special exec_ats property. Instead, it starts up assistive technologies via the same autostart mechanism used for all of GNOME (i.e., a *.desktop file under ~/.config/autostart), and the assistive technology setup (gnome-at-properties and gnome-default-applications-properties) ends up putting the correct *.desktop files in place. gnome-session-properties also provides some startup applications configuration. [WDW: I'm not quite sure how all these work together.]

How Applications Connect to the Registry

The GTK_MODULES environment variable specifies modules that GTK+ applications should load on startup. This is the hook for getting accessibility support into GTK+ applications -- when a GTK+ application runs, it will load the modules listed in GTK_MODULES. The most common setting for GTK_MODULES in an accessibility environment is:

GTK_MODULES=gail:atk-bridge

The gail module sets up the mapping of GTK+ widgets to atk widgets, and the atk-bridge module communicates with the at-spi-registryd that was started by gnome-session. The code that attempts to connect to the at-spi-registryd lives in the at-spi module under atk-bridge/bridge.c. It looks for the AT_SPI_IOR property on the root window to find the at-spi-registryd process and then attempts to connect to it.

At one time prior to the AT_SPI_IOR work, the at-spi-registryd would automagically (e.g., Bonobo activation) start if one attempted to tickle it and it wasn't running. Now, it needs to be explicitly started by gnome-session in order for the AT-SPI infrastructure to work.

Accessibility/Documentation/GNOME2/Mechanics (last edited 2011-07-21 18:54:18 by JoanmarieDiggs)