vcl/unx/gtk3/a11y/atkfactory.cxx |   83 +++++----------------------------------
 1 file changed, 12 insertions(+), 71 deletions(-)

New commits:
commit be543e321552d4331e7dddca954a2b57f4c7f379
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Apr 30 16:17:25 2024 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Tue Apr 30 20:53:20 2024 +0200

    tdf#159369 tdf#160806 gtk3 a11y: Drop fallback dummy a11y obj
    
    No longer return a dummy AtkObject in
    `wrapper_factory_create_accessible`, but drop the
    implementation of that dummy object completely.
    
    As far as I understand, the code path previously
    creating those dummy objects should never be triggered,
    so add asserts to detect any cases where it does.
    However, gracefully return nullptr for release builds
    for now at least.
    
    This dummy implementation was originally added
    as part of:
    
        commit 62f451cb03d5202e2f15bf440c53a61b2efd99f8
        Date:   Fri May 5 09:54:24 2006 +0000
    
            INTEGRATION: CWS atkbridge (1.1.2); FILE ADDED
            2006/03/31 12:19:39 obr 1.1.2.12: #i63583# eliminated warnings
            2006/03/28 10:49:45 obr 1.1.2.11: #i47890# redid the last patch to 
make it more clear
            2006/03/23 14:45:26 obr 1.1.2.10: fixed endless loop problem with 
tooltips
            2006/02/15 10:59:22 obr 1.1.2.9: #i47890# replaced tabs with spaces
            2006/01/05 14:06:31 obr 1.1.2.8: #i47890# override toolkit name and 
version and reworked bridge initialization
            2005/11/16 12:29:16 obr 1.1.2.7: no longer return NULL in 
factory_create_accessible
            2005/11/16 09:09:20 obr 1.1.2.6: gail rev. 1.8.6 fixes the things 
we needed gsignalhook for
            2005/10/20 07:09:09 obr 1.1.2.5: #i47890# made cxx files 
standalone, avoid queryInterface on each API call and demacrofied try/catch to 
include appropriate warnings
            2005/09/28 07:24:12 obr 1.1.2.4: #i47890# changed ref-counting/life 
cycle once again, adjust tree and role of dialogs and filter sub-menu windows
            2005/09/26 11:01:00 obr 1.1.2.3: #i47890# reworked lifecycle of atk 
wrapper objects
            2005/06/14 13:57:23 obr 1.1.2.2: #i47890# global focus event 
listening stuff
            2005/04/21 14:59:24 mmeeks 1.1.2.1: Issue number: i#47890#
            Submitted by: mmeeks
    
            Hacked up prototype of atk bridge
    
    Change-Id: Ibdc525412ba6cc4b449c775a74dcd919c4045b6c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166934
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/unx/gtk3/a11y/atkfactory.cxx b/vcl/unx/gtk3/a11y/atkfactory.cxx
index c9702c9f85d8..3c8e6222e896 100644
--- a/vcl/unx/gtk3/a11y/atkfactory.cxx
+++ b/vcl/unx/gtk3/a11y/atkfactory.cxx
@@ -27,68 +27,6 @@ using namespace ::com::sun::star;
 
 extern "C" {
 
-/*
- *  Instances of this dummy object class are returned whenever we have to
- *  create an AtkObject, but can't touch the OOo object anymore since it
- *  is already disposed.
- */
-
-static AtkStateSet *
-noop_wrapper_ref_state_set( AtkObject * )
-{
-    AtkStateSet *state_set = atk_state_set_new();
-    atk_state_set_add_state( state_set, ATK_STATE_DEFUNCT );
-    return state_set;
-}
-
-static void
-atk_noop_object_wrapper_class_init(gpointer klass_, gpointer)
-{
-    auto const klass = static_cast<AtkNoOpObjectClass *>(klass_);
-    AtkObjectClass *atk_class = ATK_OBJECT_CLASS( klass );
-    atk_class->ref_state_set = noop_wrapper_ref_state_set;
-}
-
-static GType
-atk_noop_object_wrapper_get_type()
-{
-    static GType type = 0;
-
-    if (!type)
-    {
-        static const GTypeInfo typeInfo =
-        {
-            sizeof (AtkNoOpObjectClass),
-            nullptr,
-            nullptr,
-            atk_noop_object_wrapper_class_init,
-            nullptr,
-            nullptr,
-            sizeof (AtkObjectWrapper),
-            0,
-            nullptr,
-            nullptr
-        } ;
-
-        type = g_type_register_static (ATK_TYPE_OBJECT, "OOoAtkNoOpObj", 
&typeInfo, GTypeFlags(0)) ;
-    }
-    return type;
-}
-
-static AtkObject*
-atk_noop_object_wrapper_new()
-{
-  AtkObject *accessible;
-
-  accessible = static_cast<AtkObject *>(g_object_new 
(atk_noop_object_wrapper_get_type(), nullptr));
-  g_return_val_if_fail (accessible != nullptr, nullptr);
-
-  accessible->role = ATK_ROLE_INVALID;
-  accessible->layer = ATK_LAYER_INVALID;
-
-  return accessible;
-}
-
 /*
  * The wrapper factory
  */
@@ -103,24 +41,27 @@ static AtkObject*
 wrapper_factory_create_accessible( GObject *obj )
 {
     GtkWidget* pEventBox = gtk_widget_get_parent(GTK_WIDGET(obj));
-
-    // gail_container_real_remove_gtk tries to re-instantiate an accessible
-    // for a widget that is about to vanish ..
+    assert(pEventBox);
     if (!pEventBox)
-        return atk_noop_object_wrapper_new();
+        return nullptr;
 
     GtkWidget* pTopLevelGrid = gtk_widget_get_parent(pEventBox);
+    assert(pTopLevelGrid);
     if (!pTopLevelGrid)
-        return atk_noop_object_wrapper_new();
+        return nullptr;
 
     GtkWidget* pTopLevel = gtk_widget_get_parent(pTopLevelGrid);
+    assert(pTopLevel);
     if (!pTopLevel)
-        return atk_noop_object_wrapper_new();
+        return nullptr;
 
     GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(pTopLevel);
-    g_return_val_if_fail(pFrame != nullptr, atk_noop_object_wrapper_new());
+    assert(pFrame);
+    if (!pFrame)
+        return nullptr;
 
     vcl::Window* pFrameWindow = pFrame->GetWindow();
+    assert(pFrameWindow);
     if( pFrameWindow )
     {
         vcl::Window* pWindow = pFrameWindow;
@@ -146,7 +87,7 @@ wrapper_factory_create_accessible( GObject *obj )
         }
     }
 
-    return atk_noop_object_wrapper_new();
+    return nullptr;
 }
 
 AtkObject* ooo_fixed_get_accessible(GtkWidget *obj)
commit 252b1591d5e4e3adbf7063b56c2b578fe046ad3d
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Apr 30 15:30:52 2024 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Tue Apr 30 20:53:14 2024 +0200

    tdf#159369 tdf#160806 tdf#160837 gtk3 a11y: Don't skip parents one way
    
    The gtk3 VCL plugin partly uses native GTK widgets (see
    `GtkSalFrame::InitCommon`), like an OOoFixed, a GtkEventBox
    and a GtkGrid.
    
    Therefore, when descending the a11y hierarchy from top to bottom,
    GTK's a11y implementation for GtkWidget etc. come into play
    for those.
    
    For the OOoFixed, LO provides its own factory to create an
    accessible. That one was skipping some of the widgets to
    determine a parent and create an AtkObject (wrapper) for
    the OOoFixed.
    
    This made the a11y hierarchy inconsistent, as walking the
    tree up from an object should result in the same path
    as descending down from the root node to that child.
    
    Demo in Accerciser, with the root pane selected for
    Writer:
    
    Printing the a11y info for the object with role root pane
    and the object it reports as its parent:
    
        In [24]: acc.name
        Out[24]: 'Untitled 1 — LibreOfficeDev Calc 24.8 
[621cfc0e4120ab2b381b54268fe39bd19257df9b]'
        In [25]: acc.role
        Out[25]: <enum ATSPI_ROLE_ROOT_PANE of type Atspi.Role>
        In [26]: acc.parent
        Out[26]: <Atspi.Accessible object at 0x7f4c4e908fc0 (AtspiAccessible at 
0x359a3e0)>
        In [27]: acc.parent.name
        Out[27]: 'Untitled 1 — LibreOfficeDev Calc 24.8 
[621cfc0e4120ab2b381b54268fe39bd19257df9b]'
        In [28]: acc.parent.role
        Out[28]: <enum ATSPI_ROLE_FRAME of type Atspi.Role>
    
    Then, after selecting the object that is shown as the
    parent in Accerciser's treeview of LO's a11y hierarchy
    shows that this is a different object:
    
        In [29]: acc.name
        Out[29]: ''
        In [30]: acc.role
        Out[30]: <enum ATSPI_ROLE_PANEL of type Atspi.Role>
    
    And it can also be seen directly that that panel's first
    child doesn't report the panel itself as its parent:
    
        In [31]: acc.get_child_at_index(0).parent == acc
        Out[31]: False
    
    No longer skip the widgets but set the widget's direct
    parent as accessible parent as well.
    
    With this in place, the above check worked reliably
    for me when starting Accerciser before starting LO
    and clicking through the LO hierarchy on Wayland no
    longer showed the issue described in tdf#159369 comment 4.
    (When starting LO first and Accerciser afterwards, there
    are still more issues presumably related to events,
    which needs further investigation).
    
    In that scenario, highlighting for the toolbar
    icons in Accerciser (tdf#160838) was also correct.
    
    Calc was behaving similarly in a quick test.
    
    Change-Id: I4c782dc8dcb543e6a0db01c9f887a2716711ea64
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166933
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/unx/gtk3/a11y/atkfactory.cxx b/vcl/unx/gtk3/a11y/atkfactory.cxx
index bb19eb8cea8d..c9702c9f85d8 100644
--- a/vcl/unx/gtk3/a11y/atkfactory.cxx
+++ b/vcl/unx/gtk3/a11y/atkfactory.cxx
@@ -139,7 +139,7 @@ wrapper_factory_create_accessible( GObject *obj )
                 if( accessible )
                     g_object_ref( G_OBJECT(accessible) );
                 else
-                    accessible = atk_object_wrapper_new( xAccessible, 
gtk_widget_get_accessible(pTopLevel) );
+                    accessible = atk_object_wrapper_new(xAccessible, 
gtk_widget_get_accessible(pEventBox));
 
                 return accessible;
             }

Reply via email to