summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vcl/Library_vclplug_gtk4.mk1
-rw-r--r--vcl/unx/gtk4/a11y.cxx23
-rw-r--r--vcl/unx/gtk4/a11y.hxx15
-rw-r--r--vcl/unx/gtk4/gtkaccessibleeventlistener.cxx7
-rw-r--r--vcl/unx/gtk4/gtkaccessibleeventlistener.hxx2
-rw-r--r--vcl/unx/gtk4/gtkaccessibleregistry.cxx41
-rw-r--r--vcl/unx/gtk4/gtkaccessibleregistry.hxx32
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: */