[g-a-devel] Interfacing a non-GTK application with AT-SPI



Hi,

I'm attempting to add accessibility to a non-GTK application written in
Python.  I guess this is more of a "here's how I'm getting on" feedback
mail, but I'd appreciate any comments or clarifications on things I'm
doing.

After going from not knowing much about AT-SPI or accessibility in
general a few days ago, I must say I'm impressed with the architecture
which has been built, even if my understanding is not complete.


My first attempt at this was interfacing with ATK. I figured that if I
just tell ATK about all my widgets and their status, then we get
accessibility 'for free'.

After some experimentation I managed to write a small C sample app which
defines the following classes:
 1. A psuedo-widget GObject class
 2. A AtkGObjectAccessible class to interact with the pseudo-widget
 3. An AtkObjectFactory class to generate my AtkGObjectAccessible    
    instances
 4. An AtkUtil class to do the kind of things that GAIL does

I built this with the long term goal that I'd be able to produce a
GObject for every one of my custom widgets, with the accessibility
objects built on top of that. Or alternatively skip the custom GObject
and just build AtkGObjectAccessible instances on top of the custom
widgets, if that is possible.

Anyway - I built this prototype C app, and eventually managed to get
dogtail to interface with my pseudo-widgets. Woohoo!


Next, I decided to port my prototype C app to Python+pygtk, as the app
I'm wanting to add accessibility to is a python app. I thought this part
would be easy, however I ran into a few showstoppers early on due to
pygtk's interface to ATK being incomplete:

 1. The code generater does not know about GSignalEmissionHook so it
    does not generate the add_global_event_listener() virtual function
    for the atk.AtkUtil class, meaning that I can't write a gail   
    replacement. This is potentially hard to solve because pygobject
    mangles GSignalEmissionHooks internally, so passing one down from
    AT-SPI's atk-bridge to glib's g_signal_add_emission_hook() poses
    a challenge.

 2. The definitions file does not include definitions for the virtual
    function "get_parent" (and a few others) in atk.AtkUtil. These
    virtuals are slightly odd in that they do not take the AtkUtil 
    instance as the first parameter. pygtk currently offers no way
    of generating code for these virtuals.

I stopped at this point, although it would not surprise me if there were
other showstoppers preventing me from implementing this stuff in python
right now.



I decided to change direction and thought about skipping the ATK and
atk-bridge translation and simply adding an interface onto my app to
talk to AT-SPI directly. pyspi looks like it will allow me to do this,
so I research further. I can't find any website or documentation for
pyspi, but I read up a little about pyrex and realise that the pyspi
functionality is evident by reading the source (i.e. code is not
automatically generated).

Alas, understanding pyspi now requires me to understand the AT-SPI C
API. There are docs for this one, but their purpose is unclear to me:
are these docs detailing how an app can register with AT-SPI and say
"i've got 3 buttons, 2 labels, and a frame", or do they detail how an
accesibility app (e.g. screenreader) can say "give me the text from
widget X on app Y", or both?

Further confusion ensues when I look at the atk-bridge code and see it
calling functions like spi_application_new() which are not mentioned in
the API docs. That aside, spi_application_new() can't be used here since
it deals in terms of AtkObjects and I've dropped the ATK idea. I'm left
wondering how I might be able to create an application object so that I
can register it, etc.


The other option which I have not yet explored is to create a C library
to make my app interact with ATK, and then a Python module bridge so
that my app can talk to the C library. I'm no so keen on this though, I
feel that this architecture has enough bridging already...

Daniel





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]