[g-a-devel] KISSing Collections



Hey guys.

As we continue to look forward to ATK and AT-SPI next, I've got some
questions and thoughts regarding the current Collection interface, which
I feel is unnecessarily complex and convoluted. In short, I feel that
we've forgotten how valuable the KISS principle is. Here's the long
version:

0. Background and Use:

* At the moment, the Collection interface is implemented only in AT-SPI.
  There are plans to implement AtkCollection, however.
* At the moment, only Gecko has implemented support for Collection.
* At the moment (AFAIK), Orca is the only AT using Collection.
* What Orca needs to be able to do is:
  - get the {previous,next,all} instance(s) of an object
  - which meet(s) one or more specified criteria
  - and is found within a given root object
  - for the purpose of efficient navigation, either within the
    document/application or via an Orca-provided 'list of' dialog.
* Personally, I cannot imagine other ATs having vastly different needs
  or use cases with respect to Collection.

1. Do we really need these (not-implemented) methods?

   * atspi_collection_is_ancestor_of()
   * atspi_collection_get_active_descendant()

   In order for an AT to have a collection in the first place, it needs 
   to ask for that collection, ideally specifying the root object (e.g.
   all the paragraphs in this document; all the unvisited links in this
   paragraph; etc.). As a result, that AT already knows the ancestor of
   interest of a given collection. And if that AT wanted to know if a 
   given accessible object were an intermediate ancestor, it's really
   quite simple to ascend the accessible hierarchy. Beyond that, we've
   had Collection for years now and managed to get by just fine without
   atspi_collection_is_ancestor_of(). ;-)

   As for atspi_collection_get_active_descendant(), which we have also
   somehow managed to survive without.... What exactly *is* the active
   descendant of a collection? I can see an argument for defining
   'active descendant' as 'the object with focus and/or the caret'.
   However, this assumes two things: That the object in question is even
   capable of having focus and/or the caret, AND that having the focus
   and/or the caret is of relevance to the AT with respect to the 
   collection in question. I think it is more likely that the AT itself
   will keep track of what it considers to be the 'active descendant.'
   And I think that ability to ask for the object which has focus and/or
   the caret is not something unique to Collection, and thus should be
   implemented elsewhere.

   My proposal: We nuke these methods which have gone unimplemented for
   years. In addition, the ability to specify the root object gets added
   to the get_matches methods.

2. Do we really need these methods (as currently named and defined):

   * atspi_collection_get_matches_to()
   * atspi_collection_get_matches_from()

   These methods seem to suggest that an AT would want more than one of
   the previous/next objects. What on earth for?? In the case of
   facilitating navigation within the document/app, only the previous/ 
   next *single* object is needed; in the case of implementing an
   AT-specific tool (e.g. a 'list of' dialog), the AT would presumably
   want all of the objects.

   My proposal: We replace the above methods with:

   * atspi_collection_get_previous_match()
   * atspi_collection_get_next_match()

   That, combined with atspi_collection_get_matches() should more than
   suffice IMHO.

3. Do we really need the ability to specify a count?

   This follows point 2. I want one (previous/next) or all. Why would I
   want some arbitrary number in between?

   My proposal: Count gets removed from the present and/or revised
   get_matches methods' arguments.

4. Do we really need the ability to specify the sort order?

   typedef enum {
       ATSPI_Collection_SORT_ORDER_INVALID,
       ATSPI_Collection_SORT_ORDER_CANONICAL,
       ATSPI_Collection_SORT_ORDER_FLOW,
       ATSPI_Collection_SORT_ORDER_TAB,
       ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL,
       ATSPI_Collection_SORT_ORDER_REVERSE_FLOW,
       ATSPI_Collection_SORT_ORDER_REVERSE_TAB,
       ATSPI_Collection_SORT_ORDER_LAST_DEFINED,
   } AtspiCollectionSortOrder;

   A. Shouldn't the tab order and the flow order be the same thing?
   B. The main use case (IMHO) for Collection is to facilitate
      navigation amongst and/or examination of objects. As such, isn't
      the logical sort order that which corresponds to the flow/tab
      order?
   C. Do we really need to be able to reverse the order? And, if so,
      can't we ATs just take the resulting object list and reverse it
      ourselves?

   My proposal: Sort order gets removed from the present and/or
   revised get_matches methods' arguments.

5. Do we really need the ability to specify the tree traversal type?

   typedef enum {
       ATSPI_Collection_TREE_RESTRICT_CHILDREN,
       ATSPI_Collection_TREE_RESTRICT_SIBLING,
       ATSPI_Collection_TREE_INORDER,
       ATSPI_Collection_TREE_LAST_DEFINED,
   } AtspiCollectionTreeTraversalType;

   As you might have guessed, my proposal: nuke it.

6. Recurse and Traverse? What are these even for? Aline asked us on
   several occasions as part of her most awesome documentation work. And
   the consensus of those of us who have been around is that we don't
   know and will have to dig through the AT-SPI code in order to sort it
   out. If no one even knows what these things are for or why they might
   be of benefit to an AT are they a) worth keeping around and b) worth
   asking apps and toolkits to implement -- and then expecting them to
   do so in a consistent fashion??

   My proposal: If there is indeed a compelling reason to keep these 
   things around, it should be made much more obvious to us -- and then 
   clearly documented for implementors. Otherwise, I think these need
   removing.

Thoughts?
--joanie



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