vcl/unx/gtk3/gtkinst.cxx | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
New commits: commit ee168614ddea2f349e80372599296e835080f264 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu May 23 15:39:34 2024 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri May 24 06:25:54 2024 +0200 tdf#160971 gtk3 a11y: Manually unset focus for combobox popup The gtk3 VCL plugin uses a custom implementation that has a listbox in a popup (s. vcl/uiconfig/ui/combobox.ui). The popup window gets shown when expanding the combobox, e.g. using Alt+Up/Alt+Down while the edit has focus. Once the popup is closed again, focus is given to the edit again. That one correctly reports focus when checked via `gtk_widget_has_focus`, but for some unknown reason, the listbox in the popup assumes/claims it still has global keyboard focus as well, despite it no longer being visible and the `gtk_widget_has_focus` doc [1] explicitly mentioning: > Determines if the widget has the global input focus. > See gtk_widget_is_focus() for the difference between having the global input focus, and only having the focus > within a toplevel. The tree view listbox still assuming focus leads to it emitting invalid active-descendant-changed a11y events when the selected entry changes, which e.g. breaks focus tracking by the Orca screen reader. As a consequence, current Orca git main (as of commit d70919051ef01384c473e08321a88cec52549cd2) doesn't doesn't announce the new value of e.g. the "Font Name" combobox in the Writer toolbar when changing it via the Up/Down arrow keys any more once the popup has been shown. (It works fine before showing the popup for the first time.) To avoid that problem, manually unset the focus using `gtk_widget_send_focus_change`. Its doc [2] mentions > This function is not meant to be used by applications. , but since the focus is apparently not unset automatically, still use it as a workaround for now. [1] https://docs.gtk.org/gtk3/method.Widget.has_focus.html [2] https://docs.gtk.org/gtk3/method.Widget.send_focus_change.html Change-Id: Ifd32c2a66b4a7b9e827f5c8dc2927c7e359a42aa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167994 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index f9b087e25f4e..6e4f95dc7e3d 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -21368,6 +21368,29 @@ private: //is what the vcl case does, to ease the transition a little gtk_widget_grab_focus(m_pEntry); enable_notify_events(); + + // tdf#160971: For some reason, the tree view in the no longer visible + // popup still incorrectly assumes it has focus in addition to the now + // actually focused entry. + // That would cause it to send invalid active-descendant-changed a11y events when + // the selected entry changes, e.g. breaking focus tracking by the Orca screen reader. + // Manually unset focus to avoid that + assert(!gtk_widget_is_visible(GTK_WIDGET(m_pTreeView))); + const bool bTreeViewFocus = gtk_widget_has_focus(GTK_WIDGET(m_pTreeView)); + if (bTreeViewFocus) + { + SAL_WARN("vcl.gtk", "No more visible tree view in combobox still incorrectly " + "claims having focus - unsetting manually."); + GdkWindow* pWindow = gtk_widget_get_window(GTK_WIDGET(m_pTreeView)); + GdkEvent* pEvent = gdk_event_new(GDK_FOCUS_CHANGE); + pEvent->focus_change.type = GDK_FOCUS_CHANGE; + pEvent->focus_change.window = pWindow; + if (pWindow) + g_object_ref(pWindow); + pEvent->focus_change.in = 0; + gtk_widget_send_focus_change(GTK_WIDGET(m_pTreeView), pEvent); + gdk_event_free(pEvent); + } } }