[g-a-devel] Re: ATK implementation issues for user defined object types.



Marcus Von Appen sent me some direct email regarding implementing ATK
for his applications' widgets.  I now understand that his application
does not derive widgets from gtk+, so his problem is a little more
complex than that met by most application developers, who will be using
a toolkit for which ATK implementation work may already exist.

Marcus' case requires that an ATK implementation, and the necessary
bootstrapping code, be written for a new widget set.  I thought that my
answer to him might be of wider interest, so I am attaching it below.

Best regards,

Bill


On Wed, 2006-03-29 at 11:26, Bill Haneman wrote:
> On Wed, 2006-03-29 at 10:52, Marcus von Appen wrote:
> > On, Wed Mar 29, 2006, Bill Haneman wrote:
> > 
> > [...] 
> > > > Would that in turn mean for my example class and code, that I have to
> > > > create a similar implementation like gail (or a bridge towards gail) to
> > > > allow Gnopernicus or at-poke as well as e.g. braille systems further
> > > > access to my class Foo? Or is there something I miss?
> > > 
> > > If your application's widgets inherit from gtk+, you inherit the ATK
> > > implementations already provided by gail.  You only need to add
> > > implementations for custom widgets in situations where their needs
> > > differ from those of the base widgets from which they inherit.  The
> > > "farther along" the gtk+ inheritance tree your custom widgets are
> > > derived, the better; if you inherit from GtkWidget directly, you'll have
> > > to provide explicit implementations for almost all of ATK for your
> > > custom widgets, whereas a slightly-customized GtkRadioButton would need
> > > only a minor tweak.
> > 
> > None of the widgets will ever inherit from Gtk+ nor GObject. This is
> > where my problems with wondering about gail and an AT-SPI interaction
> > starts. I'm okay with inheriting or binding an AtkObject to my own code,
> > but not with making all code dependant on Gtk+, thus gail is not usable for
> > my case(s).
> > 
> > Therefore I would like to know, what has to be done to make at-poke and
> > other assistive technologies to recognize those objects as accessible.
> > As gail is no option, I am really confused about what has to be used
> > for such cases as the docs do not tell anything about it.
> 
> This is an area where there is a hole in the existing docs.  Since most
> application developers use an existing widget set such as gtk+ (or Qt or
> OOo's VCL, etc.), the question you are asking is not one that most
> application developers encounter.  Basically each totally new widget set
> needs to provide a little glue, and you happen to be the pioneer for
> PyGame I guess.  Your question is thus quite specialized, and not
> something that most developers will encounter.
> 
> So, your widget set needs to provide ATK implementations (i.e. in the
> manner of gail) where appropriate.  It also needs to provide a couple of
> 'hooks' into AtkUtil.  The way this is normally done is to overwrite the
> AtkObjectClass->get_root, get_toolkit_name, and get_toolkit_version
> function pointers.  (I know this seems strange to some GObject folks,
> but AtkUtil is essentially a static/singleton class and this is how we
> ensure that it remains so within a given process space).  See gailutil.c
> for information - gail_util_class_init() is the method that does this. 
> Similarly in gail.c, gtk_module_init() sets up the appropriate factory
> classes for the various GObject types of the widgets.  In your
> equivalent case, of course, you won't be using gtk+ code or #include'ing
> gtk+ headers, but will be calling the appropriate toolkit API for your
> widgets, in order to satisfy the interfaces.
> 
> For the factories, you have several choices.  Since the factories
> operate on the basis that an AtkObject factory is associated with a
> GType, if your widgets are derived at all from GObject, you pass in
> their type; otherwise you will need to either invent a
> GType-to-your-widget-type hashsystem, or replace the AtkObjectFactory
> with one of your own devising.  Lastly, if the GType and factory system
> doesn't suit your toolkit at all, you can create your own private
> factory API and just call that whenever constructing AtkObject peers for
> your toolkit's widgets.
> 
> You'll then include the atk-bridge code at runtime; if you are not using
> gtk+ or gnome, you'll need to find another way to preload and initialize
> the atk-bridge.  The entry and exit points are
> gnome_accessibility_module_init and gnome_accessibility_module_shutdown,
> both of which are exported by the atk-bridge.  Alternatively, and
> equivalently, you can load the atk-bridge via the g_module_open(), which
> is a glib API, passing in the "atk-bridge" gmodule name. 
> 
> At runtime, the g_module_init() code will get executed when the modules
> are loaded; then atk-bridge will call atk_get_root() to obtain the root
> AtkObject for your app, register the app with the at-spi-registryd
> daemon, and call any atk_add_global_event_listener() for the necessary
> ATK event types.  Note that you must provide an implementation for
> AtkObjectClass->add_global_event_listener, and that the event names you
> are passed may in some cases be prefixed with "Gtk:AtkObject".  Feel
> free to ignore the anomalous "Gtk" in that namespace, it's of no
> consequence.  Your ATK implementation is responsible for emitting the
> appropriate ATK signals via the GSignal API.
> 
> As I said before, this is not something that most developers will need
> to do; this sort of code needs to be written only once per toolkit, and
> has historically been an area where the accessibility folks (me,
> nowadays) have worked with the toolkit developers to get things started.
> 
> Lastly Marcus, I personally will be away for approximately two months
> starting next week, so I may not be of much more help right away. 
> Hopefully the gailutil.c and gail.c sources will provide much of what
> you need to know for bootstrapping, they total about 1500 lines of code.
> 
> Best regards,
> 
> Bill
> 
> > > In order to inherit the maximum GAIL implementation already provided for
> > > your custom widget, you will need to use a special "anonymous
> > > inheritance" trick which is described in the following paper:
> > > 
> > > http://developer.gnome.org/projects/gap/presentations/GUAD3C/making-apps-accessible/start.html
> > 
> > As most other documentation about Atk this assumes that a developer uses
> > Gtk+ as basic toolkit. This is not the case for me and other toolkits,
> > which might want to provide accessibility over time. Bringing a Gtk+
> > dependency to the pygame UI I am currently writing is not an option as
> > it neither has any necessity for it nor would ever make use of the Gtk+
> > model (it is completely written from scratch using pygame as only
> > dependency).
> > 
> > [...]
> > > > From my understanding I need some bridge from my newly Atk aware code
> > > > towards AT-SPI to make it work using e.g. at-poke (which in fact
> > > > directly uses the AT-SPI interfaces). Would not that mean, that I
> > > > could use AT-SPI directly in favour of Atk to reduce the amount of work
> > > > to do?
> > > 
> > > Implementing directly to AT-SPI would be a much, much bigger chunk of
> > > work, and you'd have to reimplement almost all of AT-SPI even if you had
> > > only one custom widget.  Writing to ATK is much, much easier, because
> > > it's a straightforward in-process API written using glib/gobject
> > > conventions.  This is what all other accessible graphical apps on the
> > 
> > Yes, this is what we clarified on the a11y-atspi mailing list
> > already. I think I gave a bad explanation of my exact problems here.
> > 
> > Regards
> > Marcus




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