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