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 _______________________________________________ Gnome-accessibility-devel mailing list [email protected] http://mail.gnome.org/mailman/listinfo/gnome-accessibility-devel
