[Kde-accessibility] documentation of QAccessible and friends

Volker Hilsheimer vohi@trolltech.com
Sun, 9 Mar 2003 13:39:26 +0100


> I have some comments, please see below:
>
> On Fri, 2003-03-07 at 22:58, Volker Hilsheimer wrote:
> ...
> > QAccessibleInterface is a generic API that abstracts every
accessible
> > "object" using four central concepts:
> >
> > - an object is part of an object hierarchy. It can have children,
and
> > can have a parent
> > This implies that the parent can identify any child with an index,
so
> > that you can navigate throught the complete hierarchy once you got
hold
> > of any object in the tree.
>
> ATK of course has this same concept.
>
> > - an object has properties
> > Most properties can be expressed by strings - those properties can
> > change. Some properties can only have a predefined value, e.g.
values
> > that an accessible client and hence a user relying on such a client
can
> > make use of, and are usually static, or at least not writable from
> > outside. "role" and "state" are such properties.
>
> ATK has this concept, except properties are read-write at the ATK
level
> but are generally presented to clients as read-only.
>
> > - an object has methods
> > You can push a button. IAccessible - and hence the current
> > QAccessibleInterface API - only provide one default method, apart
from
> > "secondary" methods like setFocus. A new text property, e.g. "verbs"
or
> > "actions", that returns a comma separated list of strings, and a new
> > method "doVerb" or "doAction" that takes that string is definitely
> > something we can add to QAccessibleInterface, or to a new interface
that
> > would be supported using multiple inheritance until we can break
binary
> > compatibility in 4.0.
>
> ATK doesn't use multiple inheritance, but it does allow multiple
> interfaces to be implemented by the same object instance.  As noted
ATK
> supports multiple actions now.  I believe the Mozilla team dealt with
> this by introducing extensions to nsiAccessible (which is a similar
> class to QAccessible)

For interface based development, which is sort of inevitable in
component development IMHO, multiple inheritance is an extremely useful
feature. For accessibility, any accessible object becomes a component,
and the accessibility APIs the component implements (ie. the interfaces
it inherits from) tell the accessibility client what it can do with the
component. If a component implements a selection interface, then the
object in the application will most likely have a concept of selection.

> >
> > - an object can change, and send a notification about this change
> > That's what updateAccessibility is all about.
>
> So far, this is virtually identical conceptually to ATK (and for that
> matter, to the Java Accessibility APIs which predate MSAA and ATK).
>
> > Microsoft figured out that those four central concepts might be
> > sufficient to abstract any user interface object, but that it's
> > impractical to both implement and use only those central concepts to
do
> > something complex like selection handling. So
> > IAccessible/QAccessibleInterface has some special APIs for selection
> > handling.
>
> ATK has AtkSelection (for container/child selection handling) and
> AtkText has some text-selection API.
>
> > The AtkText API is pretty involved, and for QAccessible we would
create
> > a new interface that would be implemented only for a few widget
classes.
> > But then why not just pass the (rich)text string to the client, and
let
> > the client deal with it? It's definitely more efficient to pass the
> > string to the client, and the clients figures out which character is
at
> > position X than making a remote procedure call to ask the server for
> > that rather obvious piece of information. Same for attributes at
> > position X.
>
> Volker, I don't understand your suggestion (or at least, I don't see
how
> it could work).  If by "client" we mean assistive technology (AT
> client), then the client cannot determine glyph bounds, etc. from rich
> text.  Only the application/widget set (which in this case functions
as
> the "server") knows this information.  You just cannot get the
necessary
> information by passing some sort of marked-up string to the client;
and
> it's especially inefficient if the text objects are large,
> content-wise.  The API approach is designed to get away from the
concept
> of AT clients with enormous caches that duplicate what's already in
the
> applications.

Considering that there will always be significantely more accessibility
servers than accessibility clients it's important that implementing the
server's side of accessibility is as easy as possible, and that the
clients can handle different levels of "sophistication".
If the client can use a specialized interface that gives more exact
information about things like glyph bounds (which is probably irrelevant
information for 90% of all AT clients) he can use it. But the client has
to handle the situation where it is dealing with an accessibility server
that has non implementation for such an interface. e.g. should be able
to understand i.e. richtext markups, and use them to generate ie. a DOM
tree that can be made "visible" to the user by whatever means necessary.

> > Most of the AtkEditableText class could be put into a single
function
> > "doAction(const QString&)" - start_pos and end_pos would be handled
with
> > the selection API. doAction would by default use QObject
introspection
> > and check if there is a slot with that name, e.g. QTextEdit::paste()
> > would be called if you call doAction("paste") on an interface that
wraps
> > a QTextEdit.
>
> I think that a single string-based function API is really not
sufficient
> for EditableText; there are methods that take different types and
> numbers of parameters, etc.  In general, in=process string-based APIs
> are more trouble than they are worth.  No need for me to elaborate on
> their drawbacks here, I am sure.  Our experience has been that text
> editing and selection aren't nearly as tightly coupled as you are
> suggesting.

Hm, for the Qt widgets the cursor position and the selection is entirely
sufficient. It's in fact even entirely sufficient for the user, who
cannot modify anything but cursor position and selection when he wants
to insert, copy, paste or whatever. So if you have a property
"cursorPosition", and a selection API, then you can do anything
programatically what the user can do interactively.

Not everything might be doable with a single string parameter of course,
but named actions work very nicely in e.g. Qt's signals and slots, OLE
automation, SOAP... you name it. I don't see why it should not work
here, assuming that there is a way to pass parameters through e.g. a
QValueList<QVariant> (since the parameters need to be marshalled a
variant would be a rather obvious solution).

> > There would be a few special interfaces that 90% of controls or
objects
> > don't have to take care about, e.g. for tables or - even worse -
> > canvases.
>
> Right, fortunately only a few components need complex APIs like
> AtkTable.  But for those that do, it is really essential for good
> accessibility information client-side.
>

And here interfaces and multiple inheritance scale very well.

All in all I don't see any fundamental conflict here, so I will start
looking into extending QAccessible with more interfaces for special
requirements, and will have a look at ATK to see what sort of
functionality seems to be required.

--
Volker