Bug 163802 - Back-to-back name-changed events are causing Orca to interrupt speech in spellcheck dialog
Summary: Back-to-back name-changed events are causing Orca to interrupt speech in spel...
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Writer (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: All All
: medium normal
Assignee: Michael Weghorn
URL:
Whiteboard: target:25.2.0 target:26.2.0
Keywords: accessibility
Depends on:
Blocks: a11y-Linux
  Show dependency treegraph
 
Reported: 2024-11-07 15:01 UTC by Joanmarie Diggs
Modified: 2025-08-05 21:49 UTC (History)
1 user (show)

See Also:
Crash report or crash signature:


Attachments
pyatspi script to print events (432 bytes, text/x-python)
2024-11-08 09:01 UTC, Michael Weghorn
Details
Sample doc with spelling errors (9.67 KB, application/vnd.oasis.opendocument.text)
2024-11-08 09:02 UTC, Michael Weghorn
Details
Alternative listener (527 bytes, text/x-python)
2024-11-08 10:46 UTC, Joanmarie Diggs
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Joanmarie Diggs 2024-11-07 15:01:39 UTC
Michael: I noticed that Orca was sometimes interrupting speech of the spelling error and context in order to present a name change.

Orca has logic to try to prevent incorrect interruptions, and I could add more. But in this particular case one of the events seems wrong, and the other will be redundant if the first event is addressed.

From my debug.out (trimmed for clarity):

------
object:property-change:accessible-name
for [dialog: 'Spelling: English (USA)'] in soffice (gtk 3.24.43)
(detail1: 0, detail2: 0, any_data: 'Spelling: $LANGUAGE ($LOCATION)')
------

This means that the dialog with the name of 'Spelling: English (USA)' is changing its name to 'Spelling: $LANGUAGE ($LOCATION)'

Presumably it doesn't want to do that. Then another event comes in to put things back to what they should be:

------
object:property-change:accessible-name
for [dialog: 'Spelling: English (USA)'] in soffice (gtk 3.24.43)
(detail1: 0, detail2: 0, any_data: 'Spelling: English (USA)')
------

(Note that there may be Orca debugging side effects that's causing the name after "dialog:" to be corrected/updated. But the any_data is what Orca gets from LO. And it's the any_data that demonstrates the problem.)

Orca's skips processing the first of those two events because, at processing time, Orca knows about the second one having been queued. But Orca does present the second one, interrupting speech for the error presentation.

At the time the dialog was shown, it already had the right name. So I'm hoping if you stop the first event (as being wrong) and have code that checks if the name really changed (to stop the second event), Orca will stop interrupting itself.
Comment 1 Michael Weghorn 2024-11-08 07:52:30 UTC
I can reproduce. Corresponding events seeing in Accerciser's event monitor:

99.6 object:property-change:accessible-name(0, 0, Spelling: $LANGUAGE ($LOCATION))
	source: [dialog | Spelling: $LANGUAGE ($LOCATION)]
	application: [application | soffice]
99.6 object:property-change:accessible-name(0, 0, Spelling: )
	source: [dialog | Spelling: ]
	application: [application | soffice]

Version: 25.2.0.0.alpha0+ (X86_64) / LibreOffice Community
Build ID: aae76f4df1d4a554fa16c05a28d2e1d10ea558af
CPU threads: 32; OS: Linux 6.11; UI render: default; VCL: gtk3
Locale: en-GB (en_GB.UTF-8); UI: en-US
Calc: CL threaded
Comment 2 Michael Weghorn 2024-11-08 09:01:25 UTC
Created attachment 197490 [details]
pyatspi script to print events
Comment 3 Michael Weghorn 2024-11-08 09:02:03 UTC
Created attachment 197491 [details]
Sample doc with spelling errors
Comment 4 Michael Weghorn 2024-11-08 09:17:06 UTC
On further analysis, it seems to me like most of the events I see are triggered by setting the title on the dialog before it gets shown, and I don't see "Spelling: $LANGUAGE ($LOCATION)" being set any more once the correct title has been set, so I'm not not sure whether I actually see the exact same behavior as you do.

Steps:

1) run the attached pyatspi script attachment 197490 [details]
2) open the attached document attachment 197491 [details] (with LO using the gtk3 VCL plugin, version from comment 1)
3 while the cursor is still at the beginning of the document: Press F7 to open the spellcheck dialog
4) check the script output generated in step 3

I see these events:

event source: Spelling: $LANGUAGE ($LOCATION), showing: False
object:property-change:accessible-name(0, 0, Spelling: $LANGUAGE ($LOCATION))
        source: [dialog | Spelling: $LANGUAGE ($LOCATION)]
        host_application: [application | soffice]
        sender: [application | soffice]
event source: Spelling: , showing: False
object:property-change:accessible-name(0, 0, Spelling: )
        source: [dialog | Spelling: ]
        host_application: [application | soffice]
        sender: [application | soffice]
event source: Spelling: English (USA), showing: False
object:property-change:accessible-name(0, 0, Spelling: English (USA))
        source: [dialog | Spelling: English (USA)]
        host_application: [application | soffice]
        sender: [application | soffice]

, all of which are triggered while the dialog is not yet reporting itself as showing on the a11y level (notice the "showing: False" output from the script above).

With a breakpoint on `gtk_window_set_title`, it seems the first one is triggered when GtkBuilder (from the GTK library) processes the .ui file, the second one is in SpellDialog::SpellDialog, the third one is in SpellDialog::UpdateBoxes_Impl. In particular the first one is likely not easy to avoid.

If I manually switch the text language in the dialog, I see an additional event, this time with the showing state set as expected:

event source: Spelling: English (UK), showing: True
object:property-change:accessible-name(0, 0, Spelling: English (UK))
        source: [dialog | Spelling: English (UK)]
        host_application: [application | soffice]
        sender: [application | soffice]

Does this match what you're seeing? If so, could/should Orca maybe ignore these events for objects that don't have the AT-SPI showing state set?

Or do you see different events being emitted, maybe when taking different steps?

I've submitted https://gerrit.libreoffice.org/c/core/+/176256 to avoid one unnecessary case where a title might be set, but that doesn't seem to play a role for my scenario described above at least.
Comment 5 Joanmarie Diggs 2024-11-08 10:46:34 UTC
Created attachment 197494 [details]
Alternative listener

I modified your listener because getting the states as a property of the source seems to be failing.

Here's the output I get from my version of your listener. The showing state is present.

event type: object:property-change:accessible-name, event source: Spelling: $LANGUAGE ($LOCATION), states: ['ENABLED', 'SENSITIVE', 'SHOWING', 'VISIBLE']
object:property-change:accessible-name(0, 0, Spelling: $LANGUAGE ($LOCATION))
	source: [dialog | Spelling: $LANGUAGE ($LOCATION)]
	host_application: [application | soffice]
	sender: [application | soffice]

event type: object:property-change:accessible-name, event source: Spelling: , states: ['ENABLED', 'SENSITIVE', 'SHOWING', 'VISIBLE']
object:property-change:accessible-name(0, 0, Spelling: )
	source: [dialog | Spelling: ]
	host_application: [application | soffice]
	sender: [application | soffice]

event type: object:state-changed:showing, event source: Spelling: , states: ['ENABLED', 'SENSITIVE', 'SHOWING', 'VISIBLE']
object:state-changed:showing(1, 0, 0)
	source: [dialog | Spelling: ]
	host_application: [application | soffice]
	sender: [application | soffice]

event type: object:property-change:accessible-name, event source: Spelling: English (USA), states: ['ENABLED', 'SENSITIVE', 'SHOWING', 'VISIBLE']
object:property-change:accessible-name(0, 0, Spelling: English (USA))
	source: [dialog | Spelling: English (USA)]
	host_application: [application | soffice]
	sender: [application | soffice]
Comment 6 Joanmarie Diggs 2024-11-08 11:08:06 UTC
Michael: In answer to your suggestion to ignore name changes on non-showing objects, that makes sense in general so I just landed that change: https://gitlab.gnome.org/GNOME/orca/-/commit/db1a26161

I'm still seeing the problem because, again, the showing state is actually present.
Comment 7 Michael Weghorn 2024-11-08 14:07:15 UTC
(In reply to Joanmarie Diggs from comment #5)
> Created attachment 197494 [details]
> Alternative listener
> 
> I modified your listener because getting the states as a property of the
> source seems to be failing.

Thanks!

> Here's the output I get from my version of your listener. The showing state
> is present.

The SHOWING state being present already before the object:state-changed:showing event is emitted seems odd to me.
Since this is a GTK dialog/widget, I'd generally expect that GTK would take care of accessible states here, but that needs further investigation.
Comment 8 Michael Weghorn 2024-11-08 14:15:31 UTC
(In reply to Michael Weghorn from comment #7)
> (In reply to Joanmarie Diggs from comment #5)
> > Created attachment 197494 [details]
> > Alternative listener
> > 
> > I modified your listener because getting the states as a property of the
> > source seems to be failing.
> 
> Thanks!
> 
> > Here's the output I get from my version of your listener. The showing state
> > is present.
> 
> The SHOWING state being present already before the
> object:state-changed:showing event is emitted seems odd to me.
> Since this is a GTK dialog/widget, I'd generally expect that GTK would take
> care of accessible states here, but that needs further investigation.

Assuming that got fixed, that would only help get rid of the first two object:property-change:accessible-name events. The one for the final title would remain.

Would getting rid of the first two be of any help or wouldn't that make much of a difference anyway as long as the final one is still there?
Comment 9 Commit Notification 2024-11-08 20:41:06 UTC
Michael Weghorn committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/e44f566a2c901d9c761759a20bbd767f18795d5b

tdf#163802 cui: Don't set temporary title for spelling dialog

It will be available in 25.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 10 Michael Weghorn 2024-11-08 20:45:21 UTC
(In reply to Michael Weghorn from comment #8)
> Would getting rid of the first two be of any help or wouldn't that make much
> of a difference anyway as long as the final one is still there?

Avoiding the last title/name change or making it also happen before the dialog shows seems non-trivial from what I've seen this far, as the logic to retrieve the language/dictionary (that's part of the dialog title) is currently only available later. (Might need a more fundamental rework, but I'm not too familiar with the involved code to give a more definitive answer at the moment.)
Comment 11 Michael Weghorn 2025-08-04 13:46:30 UTC
(In reply to Michael Weghorn from comment #7)
> The SHOWING state being present already before the
> object:state-changed:showing event is emitted seems odd to me.
> Since this is a GTK dialog/widget, I'd generally expect that GTK would take
> care of accessible states here, but that needs further investigation.

On further analysis, the underlying GTK problem is maybe not that the SHOWING state is present, but that an object:property-change:accessible-name event incorrectly gets emitted when the accessible name hasn't actually changed (the already set window title is set again).

New GTK 3 upstream bug report and suggested fix for that:

https://gitlab.gnome.org/GNOME/gtk/-/issues/7690
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8814

There's still another aspect here that needs to be addressed on LO side to prevent another event, though.
Comment 12 Michael Weghorn 2025-08-05 09:30:06 UTC
(In reply to Michael Weghorn from comment #11)
> On further analysis, the underlying GTK problem is maybe not that the
> SHOWING state is present, but that an object:property-change:accessible-name
> event incorrectly gets emitted when the accessible name hasn't actually
> changed (the already set window title is set again).
> 
> New GTK 3 upstream bug report and suggested fix for that:
> 
> https://gitlab.gnome.org/GNOME/gtk/-/issues/7690
> https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8814

That's merged now.

> There's still another aspect here that needs to be addressed on LO side to
> prevent another event, though.

Pending LO change series to avoid changing the dialog title when the dialog is already showing:

https://gerrit.libreoffice.org/c/core/+/188937

With that in place, there is no more object:property-change:accessible-name event after the object:state-changed:showing event, but the name is changed prior to showing the dialog:

    event type: object:property-change:accessible-name, event source: Spelling: English (UK), states: ['ENABLED', 'SENSITIVE', 'SHOWING', 'VISIBLE']
    object:property-change:accessible-name(0, 0, Spelling: English (UK))
            source: [dialog | Spelling: English (UK)]
            host_application: [application | soffice]
            sender: [application | soffice]

    event type: object:state-changed:showing, event source: Spelling: English (UK), states: ['ENABLED', 'SENSITIVE', 'SHOWING', 'VISIBLE']
    object:state-changed:showing(1, 0, 0)
            source: [dialog | Spelling: English (UK)]
            host_application: [application | soffice]
            sender: [application | soffice]

The accessible event listener script still prints the SHOWING state for the object in the object:property-change:accessible-name event.

However, that state doesn't seem to be present at the point in time GTK sets the title - checked by adding some debug output to GTK 3:

$ git diff
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 552972f28b..1763cde76e 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -2418,6 +2418,13 @@ gtk_window_set_title (GtkWindow   *window,
 {
   g_return_if_fail (GTK_IS_WINDOW (window));
 
+  AtkObject* pObject = gtk_widget_get_accessible(GTK_WIDGET(window));
+  const char* name = atk_object_get_name(pObject);
+  AtkStateSet* stateSet = atk_object_ref_state_set(pObject);
+  gboolean isShowing = atk_state_set_contains_state (stateSet, ATK_STATE_SHOWING);
+  printf("set title: %s, showing: %d\n", name, isShowing);
+
+
   gtk_window_set_title_internal (window, title, TRUE);
 }

I would guess that the script shows the "wrong" state because AT-SPI event processing happens out-of-process, and by the point in time that the script queries the states, the dialog is already shown.

Hopefully, this is not a problem with the correct event order any more:
I would expect/guess that Orca only starts announcing the dialog when it receives the object:state-changed:showing event (or something similar, like activate,...) and as long as no object:property-change:accessible-name event is emitted *after* that, it should be OK.

@joanie: Can you confirm that?

(At least I can't reproduce any interruption of speech with Orca + the above LO change + the previously mentioned GTK fix in place any more.)
Comment 13 Commit Notification 2025-08-05 21:47:24 UTC
Michael Weghorn committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/82422565eb8f0e2cab33c82fd8feba60249a0d32

tdf#163802 Merge SpellDialog::Init_Impl into ctor

It will be available in 26.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 14 Commit Notification 2025-08-05 21:48:27 UTC
Michael Weghorn committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/94442bd94e504b067efd0b992525b53fc660f114

tdf#163802 a11y: Fully initialize SpellDialog before showing

It will be available in 26.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 15 Michael Weghorn 2025-08-05 21:49:57 UTC
As far as I understand, this should be fine now with current LibreOffice git master and GTK's current gtk-3-24 git branch.

-> Closing as fixed, but please let me know if I'm missing anything.