[DEVEL] Accessibility for BonoboControls



Hi Michael (and interested parties):

In view of the looming 'platform alpha' API milestone for Gnome-2 
I have been reviewing what seems to be required for accessibility 
of bonobo controls.

As we concluded at LinuxWorld, it seems that having out-of-process
bonobo controls register like other 'apps' is not a viable option for
accessibility support, where our API requires that embedded object
be exposed as 'children' of their parent (since, for one thing, it
would require the at-spi "registry" to get involved in all at-spi
calls, whereas it is designed only to handle
registeration/deregistration
and serve as an event dispatcher.

So the alternative is that bonobo controls must expose the at-spi
accessibility interfaces directly.  Fortunately the accessibility
interfaces are already bonobo and the 'accessible' types are
BonoboObjects.  Likewise we have means of instantiating
'accessible's via GtkWidgets, so the control simply creates and
returns:

accessible_new (bonobo_control_get_widget (control));

I suggest that a BonoboControlFrame, when queried, should
return the embedded BonoboControl's accessible.  (It could
return its *own* accessible which exposes the BonoboControl's
accessible as its only child, but this would appear to add
very little value).

The query could be done via bonobo_object_query_interface (),
but this would require that all BonoboControls instantiate and
add Accessibility_Accessible implementors ('accessibles')
on creation.  Alternatively, we could add API:

BonoboObject *bonobo_control_get_accessible (control);

which would instantiate (and aggregate) the accessible
interface object only on-demand.

In the first case we would have:

Bonobo_Control control =
    bonobo_control_frame_get_control (control_frame);

Accessibility_Accessible accessible =
    bonobo_object_query_interface(bonobo_object(control_frame),
				  "IDL:Accessibility/Accessible:1.0");

This will work IFF every bonobo_control does:

bonobo_object_add_interface (bonobo_object (object),
	     accessible_new (
		    gtk_widget_get_accessible (
			    bonobo_control_get_widget (control))));


Otherwise, we would use:

Accessible *accessible =
	ACCESSIBLE (bonobo_control_get_accessible (control));

which creates the appropriate interface-implementing BonoboObject
(actually an 'Accessible' as defined in at-spi/libspi/accessible.h)
only on demand.

Please have a glance at my implementation notes below,
I am optimistic so far that we can implement this using
existing API (with the single addition to BonoboControl
mentioned above, but I certainly may have missed something.


	Best regards,
	Bill


----------------------------------------------------------------
Implementation notes:

In short, supporting accessibility for BonoboControls requires that:

(a) a bonobo control has API for getting its toplevel GtkWidget; [met]

(b) the GtkWidget has API for getting its corresponding AtkObject; [met]

(c) a bonobo-accessible object can be instantiated from the AtkObject;
[met, but requires at-spi]

(d) every bonobo control does an add-interface for the accessible
object; [new req't];
	   [alternative is new API, "BonoboObject
*bonobo_control_get_accessible (control);"]

(e) every bonobo control frame can get its embedded control [met];

(f) Accessibility_Accessible_getChild (accessible, i) must use a
different codepath,
    via the above APIs, when called on an Accessibility_Accessible which
is a
    bonobo control frame [implementable with current API]; 

(g) bonobo controls that are in a separate process space must not
register as
    separate apps with the Accessibility_Registry (thus they behave
differently
    from other Gtk toolkit clients). [met if bonobo control factories
ignore GTK_MODULES ?]

(h) bonobo controls must be able to
    use a similar, complementary means of returning their enclosing
frame
    when Accessibility_Accessible_getParent (accessible) is called.
	[bonobo_control_get_control_frame (control) or
	 bonobo_control_get_remote_ui_container()]

(i) GtkPlug and GtkSocket probably need AtkObject proxies so that
    AtkObject methods can be called across the hierarchy, across
processes.

[ Michael: this is "our" problem, meaning the libgail team :-) ]

    Fortunately this usually only happens across one level of hierarchy,
    it is not a frequent occurrence that an AtkObject calls a method on
    its parent or child AtkObject.  However it needs to be possible even
if
    it is not terribly efficient.  It also means that GtkPlug and
GtkSocket
    need a means of getting to the bonobo controls they embed/frame.
	    
    [can do this via:
     bonobo_control_x11_from_window_id (wid) in conjunction with
     bonobo_control_get_control_frame (control),
     gtk_plug_get_id (plug), and
     gtk_socket_get_id (socket);
     
     Michael: We probably want platform-neutral API for the first bonobo
call above,
     to wrap the X-implemented stuff.]

    (The dependencies on bonobo should be restricted to libgail,
    not exposed in Gtk, of course). [implementable with current
codebase, we think.]

- Bill




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