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);
+            }
         }
     }
 

Reply via email to