Hi, Peter :)
I don't think event driven approach vs polling approach should be
the deciding factor for adding accessibleWithCaret().
And the method wasn't my proposal, it was Surkov's. He came up with
it in minutes, with little input from me really.
I humbly feel the focus should be on the IA2 spec, which I feel is
incomplete without such a method. There is no quick way starting
from an IA2 document object or focused object, to get the caret
object directly. You will encounter performance problems with deep
a11y trees, unless you listen to IA2 events. It seems counter
intuitive to have to traverse the a11y tree to find it. Don't you
agree?
By counter intuitive I mean; instead of getting the caret object
directly, you may encounter a lot of objects that can confirm they
don't have it, and find one amongst siblings saying "yep, but you'll
have to ask my children" and so on.
On 11.12.2010 02:36, Peter Korn wrote:
Hi Arnstein,
Reading through your use case, it seems to me you have identified
that the IA2 API provides a way to get what you are seeking: every
time the user types a character or moves the caret, an event is
fired.
I'm unsure what you mean by event here. I assume IA2 event, then no.
I didn't seek a way to react to IA2 events. I want to avoid them.
Our application reacts to events externally from IA2. Currently,
you are forced to listen to IA2 events to get the caret object
without suffering an uncertain performance hit.
You
state that your code would be complicated by having an event loop
in it, and so are therefore seeking additional work by every
mainstream application
Yes, it wouldn't make sense to have an event loop inside the IA2
client code DLL.
Every mainstream application? I thought the IA2 spec wasn't
finalized. Excuse me if I'm wrong, but I thought only a handful
applications/frameworks have implemented it so far, and are still
working on it.
Since Surkov proposed the new method himself, I'm sure he sees the
benefit and low cost of implementing it.
to
provide an additional API call that is otherwise redundant with
information already provided -
The information is redundant yes, but the process is not. It's all
about efficiency, and shifting the responsibility. And it's also
about not to favor neither IA2 event based client nor non-event
based client, which as I mentioned I feel shouldn't be a deciding
factor.
Down the road, I'm sure others will ask about the same functionality.
Most DOM APIs, in my experience, will give you the caret
object/offset/selection object without having to traversing the
document hierarchy. Why should it not be equally easy with IA2?
in
order to save your single AT application some additional code work
(because each such event includes the accessible which generated
it, your proposed accessibleWithCaret() is simply getting
information your event handler could have cached).
Isn't it more efficient if it can hand me that cached caret object
directly, than my client caching it as well?
The IA2 server is already keeping track of which object contains the
caret, and must/can easily already cache it.
It would be nice with input from Surkov about that here.
We may have more products using the same C DLL, it would be overkill
for them all to have an extra thread with an IA2 event loop, and
they would support any number of IA2 server applications. Having
several system wide IA2 event loops would be redundant.
I'm sure I won't be the only one creating an non-event based client.
If it's discouraged, the implementation guide should reflect that.
What
your use case doesn't make clear to me is how your product will be
making use of the information it retrieves from this proposed new
API call. Would your product be polling the app in order to get
this information?
Yes. It would simply not traverse the a11y tree anymore. And step 4
would take constant time, hopefully (depends on the IA2 server how
they keep track of the current caret object internally).
What
is the user scenario (step by step) for which X would be seeking
the accessible with caret (and then presumably doing something
with that caret - e.g. re-rendering the text in the neighborhood
of the caret in some alternate fashion)?
I'm unsure what you ask. I thought I wrote what you ask about in the
previous email.
Regards,
Peter
On 12/10/2010 5:25 PM, Arnstein Skåra wrote:
Here is an use case and additional information:
Joe = any user.
X = our product. A .Net GUI application, providing textual feedback.
Use case:
---------
1. Joe is writing in Firefox, he is also using X. He expects to get
feedback on what he writes through X.
2. X needs to know where and what Joe is writing. X already knows he is
writing in Firefox.
3. X will use IAccessible2 to communicate with Firefox, to get what it
needs.
4. X will conform to the IAccessible2 implementation guide for a client.
It will find the focused object (see below), and traverse the document
hierarchy to find the caret object.
5. The caret object will give X what it needs to report back to Joe.
Motivation:
-----------
X needs non-event based IA2 client code to be isolated in a C dll. IA2
already provides the means to satisfy X.
Problem:
--------
But Joe is not satisfied, he is experiencing inconsistent timing of
feedback from X.
The cause is located in use case step 4. The time it takes to find the
caret object depends on the document currently
being viewed. The deeper the a11y tree the worse the performance. An
example of a deep tree can be viewed at www.inetword.com.
Joe shouldn't have to experience this inconsistency.
Solution:
---------
IA2 spec should relieve any IA2 client of the need to traverse the
document hierarchy to find the caret object.
In a document the caret can only be at one location at any given time. I
assume an IA2 server knows at any given time
where the caret object is, therefore it should be easy to provide it to
a client. Such as through the proposed accessibleWithCaret() method.
The design choice of the DLL:
-----------------------------
IA2 doesn't require a client to be listening to events.
If the DLL would subscribe to events with SetWinEventHook(), it will
need a message queue.
A message queue requires a GUI thread, at the very least you need to
create a message-only window in a new thread.
You will then have to deal with that operations are not mutually
exclusive. For example X calls the DLL, and the DLL's message-only
window is notified by an event at the same time.
It is simply put more complicated than it needs to be. Adding the
accessibleWithCaret() method is beneficial regardless of choice of
client approach.
How to find the focused object in a non-event based client:
-----------------------------------------------------------
1. GetGUIThreadInfo(). See
http://msdn.microsoft.com/en-us/library/ms633506%28VS.85%29.aspx
2. AccessibleObjectFromWindow(hFocusedWindow, OBJID_CLIENT,
__uuidof(IAccessible), (void**)&accObj).
3. Focused MSAA object = accObj->get_accFocus().
- Arnstein
On 08.12.2010 16:49, Alexander Surkov wrote:
Hi, Pete.
The issue is we want to avoid to check whether caret is inside of text
accessible that this method is called for. Perhaps this method should
be defined on top level accessible like application accessible. It
should work until AT want to know whether the caret is contained by
some text accessible, i.e. if AT need to get is a direct text
accessible having a caret and caret offset within it.
Also it makes sense to consider different version of the method that
returns caret offset additionally like:
[propget] HRESULT accessibleWithCaret ([out, retval] IUnknown
**accessible, [out] long* caretOffset);
Thank you.
Alex.
On Wed, Dec 8, 2010 at 11:30 PM, Pete Brunet<[email protected]> wrote:
We could create IAText2 and add this method. Are there any issues with this
proposal? (I'd have to look though my docs to see what else we might have
talked about over the last year or two that could also be added for
IAText2.)
Pete
--
Pete Brunet
a11ysoft - Accessibility Architecture and Development
(512) 238-6967 (work), (512) 689-4155 (cell)
Skype: pete.brunet
IM: ptbrunet (AOL, Google), [email protected] (MSN)
http://www.a11ysoft.com/about/
Ionosphere: WS4G
Arnstein Skåra wrote:
Hi!
A brief description of the current situation:
1.Place caret within a paragraph.
2.Get the focused IAccessible object.
3.Traverse it's children to find the IAccessible2 object containing the
caret.
This approach is how you are supposed to do it, according to the
implementation guide.
It is a very time consuming operation. An example of how bad it can get is
www.inetword.com.
Alexander Surkov proposed a method to deal with it:
[propget] HRESULT accessibleWithCaret ([out, retval] IUnknown **accessible);
Returns the accessible object containing the caret. If the caret is in
an accessible in a tree of accessibles the returned accessible is the
one actually containing the caret, i.e. a leaf node in the
accessibility tree.
Parameters:
[out] accessible The returned accessible contains the caret.
Returned Values:
S_OK
S_FALSE if there is no accessible in the entire accessible hierarchy
containing a caret
- Arnstein
_______________________________________________
Accessibility-ia2 mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/accessibility-ia2
_______________________________________________
Accessibility-ia2 mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/accessibility-ia2
_______________________________________________
Accessibility-ia2 mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/accessibility-ia2
_______________________________________________
Accessibility-ia2 mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/accessibility-ia2
--
Peter Korn | Accessibility Principal
Phone: +1 650 5069522
500 Oracle Parkway | Redwood City, CA 94065
Oracle is committed to developing practices and
products that help protect the environment
ps. sorry if things are unclear, English isn't my native language.
- Arnstein
|