diff options
-rw-r--r-- | vcl/Library_vclplug_gtk4.mk | 1 | ||||
-rw-r--r-- | vcl/unx/gtk4/a11y.cxx | 23 | ||||
-rw-r--r-- | vcl/unx/gtk4/a11y.hxx | 15 | ||||
-rw-r--r-- | vcl/unx/gtk4/gtkaccessibleeventlistener.cxx | 7 | ||||
-rw-r--r-- | vcl/unx/gtk4/gtkaccessibleeventlistener.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk4/gtkaccessibleregistry.cxx | 41 | ||||
-rw-r--r-- | vcl/unx/gtk4/gtkaccessibleregistry.hxx | 32 |
7 files changed, 103 insertions, 18 deletions
diff --git a/vcl/Library_vclplug_gtk4.mk b/vcl/Library_vclplug_gtk4.mk index a288e5151aa6..72ffeb08e267 100644 --- a/vcl/Library_vclplug_gtk4.mk +++ b/vcl/Library_vclplug_gtk4.mk @@ -89,6 +89,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk4,\ vcl/unx/gtk4/convert3to4 \ vcl/unx/gtk4/customcellrenderer \ vcl/unx/gtk4/gtkaccessibleeventlistener \ + vcl/unx/gtk4/gtkaccessibleregistry \ vcl/unx/gtk4/gtkdata \ vcl/unx/gtk4/gtkinst \ vcl/unx/gtk4/gtksys \ diff --git a/vcl/unx/gtk4/a11y.cxx b/vcl/unx/gtk4/a11y.cxx index 4107c7ff0b79..48c22beb21ee 100644 --- a/vcl/unx/gtk4/a11y.cxx +++ b/vcl/unx/gtk4/a11y.cxx @@ -22,6 +22,7 @@ #include "a11y.hxx" #include "gtkaccessibleeventlistener.hxx" +#include "gtkaccessibleregistry.hxx" #define OOO_TYPE_FIXED (ooo_fixed_get_type()) #define OOO_FIXED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OOO_TYPE_FIXED, OOoFixed)) @@ -383,15 +384,6 @@ applyObjectAttributes(GtkAccessible* pGtkAccessible, #define LO_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LO_TYPE_ACCESSIBLE, LoAccessible)) // #define LO_IS_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LO_TYPE_ACCESSIBLE)) -struct LoAccessible -{ - GObject parent_instance; - GdkDisplay* display; - GtkAccessible* parent; - GtkATContext* at_context; - css::uno::Reference<css::accessibility::XAccessible> uno_accessible; -}; - struct LoAccessibleClass { GObjectClass parent_class; @@ -590,7 +582,7 @@ static void lo_accessible_class_init(LoAccessibleClass* klass) g_object_class_override_property(object_class, PROP_ACCESSIBLE_ROLE, "accessible-role"); } -static LoAccessible* +LoAccessible* lo_accessible_new(GdkDisplay* pDisplay, GtkAccessible* pParent, const css::uno::Reference<css::accessibility::XAccessible>& rAccessible) { @@ -684,7 +676,8 @@ static GtkAccessible* lo_accessible_get_first_accessible_child(GtkAccessible* se if (!xFirstChild) return nullptr; - LoAccessible* child_accessible = lo_accessible_new(pAccessible->display, self, xFirstChild); + LoAccessible* child_accessible + = GtkAccessibleRegistry::getLOAccessible(xFirstChild, pAccessible->display, self); return GTK_ACCESSIBLE(g_object_ref(child_accessible)); } @@ -711,8 +704,8 @@ static GtkAccessible* lo_accessible_get_next_accessible_sibling(GtkAccessible* s if (!xNextChild) return nullptr; - LoAccessible* child_accessible - = lo_accessible_new(pAccessible->display, pAccessible->parent, xNextChild); + LoAccessible* child_accessible = GtkAccessibleRegistry::getLOAccessible( + xNextChild, pAccessible->display, pAccessible->parent); return GTK_ACCESSIBLE(g_object_ref(child_accessible)); } @@ -846,8 +839,8 @@ static GtkAccessible* get_first_accessible_child(GtkAccessible* accessible) return nullptr; css::uno::Reference<css::accessibility::XAccessible> xFirstChild( xContext->getAccessibleChild(0)); - LoAccessible* child_accessible - = lo_accessible_new(gtk_widget_get_display(GTK_WIDGET(pFixed)), accessible, xFirstChild); + LoAccessible* child_accessible = GtkAccessibleRegistry::getLOAccessible( + xFirstChild, gtk_widget_get_display(GTK_WIDGET(pFixed)), accessible); return GTK_ACCESSIBLE(g_object_ref(child_accessible)); } diff --git a/vcl/unx/gtk4/a11y.hxx b/vcl/unx/gtk4/a11y.hxx index 3b2e9ce02714..7fc0b2acdab9 100644 --- a/vcl/unx/gtk4/a11y.hxx +++ b/vcl/unx/gtk4/a11y.hxx @@ -10,13 +10,26 @@ #pragma once #include <gtk/gtk.h> +#include <com/sun/star/accessibility/XAccessible.hpp> //TODO: Silence various loplugin:external and loplugin:unreffun in (WIP?) a11y.cxx for now: -struct LoAccessible; struct LoAccessibleClass; struct OOoFixed; struct OOoFixedClass; GType lo_accessible_get_type(); GtkWidget* ooo_fixed_new(); +struct LoAccessible +{ + GObject parent_instance; + GdkDisplay* display; + GtkAccessible* parent; + GtkATContext* at_context; + css::uno::Reference<css::accessibility::XAccessible> uno_accessible; +}; + +LoAccessible* +lo_accessible_new(GdkDisplay* pDisplay, GtkAccessible* pParent, + const css::uno::Reference<css::accessibility::XAccessible>& rAccessible); + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx b/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx index 1bfa69530be3..256073805e7c 100644 --- a/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx +++ b/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx @@ -12,6 +12,7 @@ #include <sal/log.hxx> #include "gtkaccessibleeventlistener.hxx" +#include "gtkaccessibleregistry.hxx" GtkAccessibleEventListener::GtkAccessibleEventListener(LoAccessible* pLoAccessible) : m_pLoAccessible(pLoAccessible) @@ -26,7 +27,11 @@ GtkAccessibleEventListener::~GtkAccessibleEventListener() g_object_unref(m_pLoAccessible); } -void GtkAccessibleEventListener::disposing(const com::sun::star::lang::EventObject&) {} +void GtkAccessibleEventListener::disposing(const com::sun::star::lang::EventObject&) +{ + assert(m_pLoAccessible); + GtkAccessibleRegistry::remove(m_pLoAccessible->uno_accessible); +} void GtkAccessibleEventListener::notifyEvent( const com::sun::star::accessibility::AccessibleEventObject& rEvent) diff --git a/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx b/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx index 584cacff85fa..4422156d6c3b 100644 --- a/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx +++ b/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx @@ -15,7 +15,7 @@ #include <com/sun/star/lang/EventObject.hpp> #include <cppuhelper/implbase.hxx> -struct LoAccessible; +#include "a11y.hxx" class GtkAccessibleEventListener final : public cppu::WeakImplHelper<css::accessibility::XAccessibleEventListener> diff --git a/vcl/unx/gtk4/gtkaccessibleregistry.cxx b/vcl/unx/gtk4/gtkaccessibleregistry.cxx new file mode 100644 index 000000000000..3f5df43ed40e --- /dev/null +++ b/vcl/unx/gtk4/gtkaccessibleregistry.cxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gtkaccessibleregistry.hxx" +#include "a11y.hxx" + +#include <cassert> + +std::map<css::accessibility::XAccessible*, LoAccessible*> GtkAccessibleRegistry::m_aMapping = {}; + +LoAccessible* +GtkAccessibleRegistry::getLOAccessible(css::uno::Reference<css::accessibility::XAccessible> xAcc, + GdkDisplay* pDisplay, GtkAccessible* pParent) +{ + if (!xAcc.is()) + return nullptr; + + // look for existing entry in the map + auto entry = m_aMapping.find(xAcc.get()); + if (entry != m_aMapping.end()) + return entry->second; + + // create a new object and remember it in the map + LoAccessible* pLoAccessible = lo_accessible_new(pDisplay, pParent, xAcc); + m_aMapping.emplace(xAcc.get(), pLoAccessible); + return pLoAccessible; +} + +void GtkAccessibleRegistry::remove(css::uno::Reference<css::accessibility::XAccessible> xAcc) +{ + assert(xAcc.is()); + m_aMapping.erase(xAcc.get()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk4/gtkaccessibleregistry.hxx b/vcl/unx/gtk4/gtkaccessibleregistry.hxx new file mode 100644 index 000000000000..390b60c4345d --- /dev/null +++ b/vcl/unx/gtk4/gtkaccessibleregistry.hxx @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <map> +#include <gtk/gtk.h> +#include <com/sun/star/accessibility/XAccessible.hpp> + +struct LoAccessible; + +class GtkAccessibleRegistry +{ +private: + static std::map<css::accessibility::XAccessible*, LoAccessible*> m_aMapping; + GtkAccessibleRegistry() = delete; + +public: + /** Returns the related LoAccessible* for the XAccessible. Creates a new one if none exists yet. */ + static LoAccessible* getLOAccessible(css::uno::Reference<css::accessibility::XAccessible> xAcc, + GdkDisplay* pDisplay, GtkAccessible* pParent); + /** Removes the entry for the given XAccessible. */ + static void remove(css::uno::Reference<css::accessibility::XAccessible> xAcc); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |