Re: [g-a-devel]Accessibles lifetime & events order''
- From: Bill Haneman <Bill Haneman Sun COM>
- To: gnome-accessibility-devel bernard-hugueney org
- Cc: gnome-accessibility-devel gnome org
- Subject: Re: [g-a-devel]Accessibles lifetime & events order''
- Date: Mon, 22 Sep 2003 11:18:08 +0100
Bonjour Bernard:
It's a little hard to tell from the code you posted - I assume it's
pseudocode ? An actual code sample might be more helpful, since your
code contains "C++-isms".
If you are using the simplified C bindings ('cspi') of at-spi, then the
pointers you receive from various 'getAccessible' calls such as
Accessible_getParent (Accessible *acc) should be compare-able and unique
during their lifetime. These pointers _do_ get reused, but not while
you are holding a reference to them. These are the same sort of pointer
which is contained in the event structure.
This pointer is guaranteed valid ONLY during the event emission unless
you explicitly "ref" it - the same is true for all Accessible objects.
You don't ordinarily need to "ref" the Accessible you get from
"getChild/getParent/etc." since those calls increment the reference
count of the Accessible being returned (as the documentation indicates).
This means of course that you should call "Accessible_unref" on
Accessible pointers when you are done with them. You can also "ref" an
AccessibleEvent, which has the effect of holding a reference to the
Accessible and keeping the AccessibleEvent data valid until you do an
'unref' on it. If you find places in the API documentation for cspi
which doesn't indicate whether a return Accessible value is a reference
or not (i.e. whether the call has incremented the reference count),
please file a bug about that.
If you don't explicitly 'ref' AccessibleEvents, then you cannot safely
reuse their member Accessible* pointers or AccessibleEvents. You can
however make calls on the 'source' of an event inside/during that
event's emission handler. You should not make calls on an Accessible
which you received from a '..getAccessible' or 'getParent' call unless
you hold a reference to it, so don't call these APIs after calling
"Accessible_unref" of course.
As you have discovered, the 'defunct' state can be useful for
determining whether an Accessible's UI component has been destroyed
since you obtained the reference. Calling cspi methods on defunct
objects can result in errors but they should be non-fatal.
Perhaps you are already doing all of the above, and I am
misunderstanding your problem, but I cannot tell from the code you
posted.
Lastly, I would strongly recommend that for performance reasons you do
not traverse the accessibility hierarchy upwards for every event in
anything but a test program. This operation is likely to be quite
'expensive'. If you need to know the context of every event, it is
probably better to compare the sources against cached Accessible pointer
values such as 'most-recently-focussed', etc. and rely on "window:"
events to inform you of changes in topleve-window context.
best regards,
Bill
On Mon, 2003-09-22 at 10:40,
gnome-accessibility-devel bernard-hugueney org wrote:
> Bonjour,
> As I have already explained to this list, I am catching every possible
> event, and then going up the accessible hierarchy from the event
> source.
>
> (code sample :
> for( spi::accessible par(source); par ; par=par.parent())
> {
> // read info in par
> }
> )
>
> I was having trouble with Accessibles from the GUI hierarchy
> disappearing under my feat because of defunct events.
>
> The solution I was using was to save the information about the
> Accessibles that were being destroyed, and use it when I would
> otherwise be using a pointer to a dead Accessible ( with a map from
> pointer to information).
>
> (new code
> bool dying=e.type().find("defunct")!=Glib::ustring::npos;
> ...
> if(dying){
> // store time of death a ptr to info data structure
> }
> ...
> for( spi::accessible par(source); par ; par=par.parent())
> {
> if(is_ok(par.id()) || dying){
> // read info on par
> if(dying) {/*.. store info of dying accessible */}
> }else if(is_dead(par.id())){
> // get info stored in data structure
> }
> )
>
>
> I was not happy with this because pointer (memory locations in fact)
> get reused, so I had to decide when I would trust the pointer to be a
> new Accessible and not dangling from the defunct one :
> When I got a pointer to Accessible for which I had seen a defunct
> event, I could not reliably decide wether it was still related to the
> obsolete Accessible, of if the memory locaton was reused for a new
> one.
>
> Toying with my code, I just realised that the original problem
> (Accessible disappearing when I wanted to use them) was gone !
>
> Am I just lucky ?
> I really would like to clean my code, I would not wat to rely on luck.
> Does anybody have any insight to share ?
>
> Thank you very much in advance !
>
> Bernard,
>
> PS: In fact the problem does not disappear entierly: I would like to
> have unique ID for each Accessible. Pointer value would be an
> obivious choise, but I (once again ) have to handle the reuse.
> Unless someone can suggest anything better ?
>
>
>
>
> _______________________________________________
> Gnome-accessibility-devel mailing list
> Gnome-accessibility-devel gnome org
> http://mail.gnome.org/mailman/listinfo/gnome-accessibility-devel
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]