Bug 161548 - Could each component (Writer, Calc, Impress, Draw, etc.) have its own accessible application name?
Summary: Could each component (Writer, Calc, Impress, Draw, etc.) have its own accessi...
Status: NEEDINFO
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: LibreOffice (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: All Linux (All)
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: a11y-Linux
  Show dependency treegraph
 
Reported: 2024-06-13 09:50 UTC by Joanmarie Diggs
Modified: 2025-04-09 19:47 UTC (History)
1 user (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joanmarie Diggs 2024-06-13 09:50:56 UTC
Currently all components of LibreOffice, i.e., Writer, Calc, Impress, Draw, etc. have an accessible application name of "soffice". As a result, Orca has an "soffice" script which contains heuristics to determine if a given event, object to present, etc., is coming from Writer, Calc, Impress, ...

What I would really like to do is have a dedicated Writer script, and a dedicated Calc script, and a dedicated Impress script. That would eliminate the need for the "soffice" script heuristics which would be good for performance.

In addition, it would mean Orca could easily use AtspiCollection on everything that isn't Calc, see https://bugs.documentfoundation.org/show_bug.cgi?id=156657#c3, in particular:

> The changes I'm making to Orca will be to use AtspiCollection **any time the
> task is to find one or more descendants**. And Orca does that often enough -- 
> including for its Flat Review feature which is notoriously non-performant. 
> AtspiCollection will fix that.

and https://gitlab.gnome.org/GNOME/orca/-/commit/faf1d81b

Michael, is this an easy thing or a hard thing?
Comment 1 Michael Weghorn 2024-06-13 10:41:21 UTC
I'm sorry, but I don't see any way to make that work with LibreOffice's current architecture.

All of those components are still the same application, and run in the same process.

You can see that for example if you start Writer, then select "File" -> "New Spreadsheet": There's a Writer and a Calc window, but they both belong to the same single soffice process, and in Accerciser, you'll also see both windows as children of the same soffice (or soffice.bin) application.

So I think distinction would have to be done at least one level lower than the application, i.e. on the window/frame level or further down.

-> Closing for now, but please feel free to reopen if you have any further thoughts.
Comment 2 Joanmarie Diggs 2025-04-08 14:02:11 UTC
Reopening. Could you expose it as an object attribute somewhere?

Due to bug 156657, Orca treats all LibreOffice components as not supporting the collection interface. I really want to restrict that to just Calc.

If the user is in the document, I can easily ascend the accessibility tree and see what type of document it is. But if the user is outside the document (which is often the case in the scenario described in the other bug), I'd have to do a non-performant tree dive to look for a spreadsheet or some other indication that Calc is being used.

Thoughts?
Comment 3 Michael Weghorn 2025-04-09 19:47:07 UTC
(In reply to Joanmarie Diggs from comment #2)
> Reopening. Could you expose it as an object attribute somewhere?

I thought about it for a while and at least cannot think of a really simple/straightforward solution right now.
The top-level window/frame might be the easiest for Orca to evaluate, but (besides the question how to determine inside LO when/where to set the attribute and get that through the abstraction layers to the specific UI toolkit window) setting object attributes seems less straightforward than setting accessible name/description/ID for example. (It's relatively simple for document content where we implement the ATK or Qt a11y interfaces/objects ourselves anyway, but seems less straightforward for native GTK or Qt widgets that have existing a11y objects from a quick glance. At least for Qt, I'm quite sure it would require somehow implementing a custom QAccessibleInterface instead of being able to use the default one provided by the toolkit.

> Due to bug 156657, Orca treats all LibreOffice components as not supporting
> the collection interface. I really want to restrict that to just Calc.
> 
> If the user is in the document, I can easily ascend the accessibility tree
> and see what type of document it is. But if the user is outside the document
> (which is often the case in the scenario described in the other bug), I'd
> have to do a non-performant tree dive to look for a spreadsheet or some
> other indication that Calc is being used.
> 
> Thoughts?

Could using the AtSpiCollection interface be an option to see whether there's a DOCUMENT_SPREADSHEET object, using a max result count of 1, so that the search will stop once the spreadsheet object is found (to avoid the problem of iterating over all children)?

It's my first time really experimenting with the AtspiCollection interface, so I might be missing something, but at least in a quick test in Accerciser, this looks somewhat promising to me:

This (a single result within a short time) is what I get with with the top-level Calc window/frame selected, when using the gtk3 VCL plugin:

    In [127]:collection = acc.queryCollection()
    In [128]: rule = collection.createMatchRule(Atspi.StateSet(), Atspi.CollectionMatchType.ALL, [], Atspi.CollectionMatchType.ALL, [Atspi.Role.DOCUMENT_SPREADSHEET], Atspi.CollectionMatchType.ANY, [], Atspi.CollectionMatchType.ALL, False)
    In [129]: collection.getMatches(rule, Atspi.CollectionSortOrder.CANONICAL, 1, True)
    Out[129]: [<Atspi.Accessible object at 0x7f21746b54c0 (AtspiAccessible at 0x1e387200)>]
    In [130]: collection.getMatches(rule, Atspi.CollectionSortOrder.CANONICAL, 1, True)[0].get_role()
    Out[130]: <enum ATSPI_ROLE_DOCUMENT_SPREADSHEET of type Atspi.Role>
    In [131]: collection.getMatches(rule, Atspi.CollectionSortOrder.CANONICAL, 1, True)[0].get_name()
    Out[131]: 'Untitled 2 - LibreOfficeDev Spreadsheets'

Using a max count larger than 1 in the above example would trigger a LibreOffice freeze and timeout on the client side:

    In [1]: collection = acc.queryCollection()
    In [2]: rule = collection.createMatchRule(Atspi.StateSet(), Atspi.CollectionMatchType.ALL, [], Atspi.CollectionMatchType.ALL, [Atspi.Role.DOCUMENT_SPREADSHEET], Atspi.CollectionMatchType.ANY, [], Atspi.CollectionMatchType.ALL, False)
    In [3]: collection.getMatches(rule, Atspi.CollectionSortOrder.CANONICAL, 2, True)
    ---------------------------------------------------------------------------
    Error                                     Traceback (most recent call last)
    Cell In[3], line 1
    ----> 1 collection.getMatches(rule, Atspi.CollectionSortOrder.CANONICAL, 2, True)

    File /usr/lib/python3/dist-packages/pyatspi/collection.py:96, in Collection.getMatches(self, rule, sortby, count, traverse)
        95 def getMatches(self, rule, sortby, count, traverse):
    ---> 96         return Atspi.Collection.get_matches(self.obj, rule, sortby, count, traverse)

    Error: atspi_error: timeout from dbind (1)

For other applications/modules, the result set would be empty, e.g. for Writer:

    In [132]: collection = acc.queryCollection()
    In [133]: rule = collection.createMatchRule(Atspi.StateSet(), Atspi.CollectionMatchType.ALL, [], Atspi.CollectionMatchType.ALL, [Atspi.Role.DOCUMENT_SPREADSHEET], Atspi.CollectionMatchType.ANY, [], Atspi.CollectionMatchType.ALL, False)
    In [134]: collection.getMatches(rule, Atspi.CollectionSortOrder.CANONICAL, 1, True)
    Out[134]: []

Could something along these lines be a workable approach for Orca?


PS: As far as I know, only GTK 3/ATK currently implements AtspiCollection, so if the mid/long term idea is to rely on that interface, then Qt 6 and GTK 4 might need some more consideration/work - but that's just something to keep in mind for later...