summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2023-12-18 13:50:39 +0100
committerMichael Weghorn <m.weghorn@posteo.de>2023-12-19 09:29:09 +0100
commitc24ed12d1098bb0a3faf1774fd8bd5f686fb49ab (patch)
tree6f35d06a671b8154e4c8eb36aae73c4376c6ee74
parenttdf#158586 RTF writerfilter: substitute hasProperties for inFrame (diff)
downloadcore-c24ed12d1098bb0a3faf1774fd8bd5f686fb49ab.tar.gz
core-c24ed12d1098bb0a3faf1774fd8bd5f686fb49ab.zip
gtk4 a11y: Add initial event handling
Add a `GtkAccessibleEventListener` that is in charge of handling a11y events for the gtk4 VCL plugin. This is inspired by how the Qt-based VCL plugins do it (see `QtAccessibleEventListener`). Initially, only handle the `css::accessibility::AccessibleEventId::STATE_CHANGED` for the `AccessibleStateType::CHECKED` state by updating the value for the corresponding Gtk state. With this in place, toggling e.g. the "Bold" toggle button in Writer's formatting toolbar now properly updates the "checked" state of the corresponding a11y object in Accerciser's tree view of LO's a11y hierarchy. Gtk takes care of sending a corresponding "state-changed" event on the AT-SPI layer: 10.8 object:state-changed:checked(1, 0, 0) source: [toggle button | Bold] application: [application | soffice] Handling state changes to other states that map to a `GtkAccessibleState` should be possible in a similar way. However, other states - like the FOCUSED state - map to a `GtkAccessiblePlatformState` in Gtk 4, and the function `gtk_accessible_platform_changed` to update these that is used by Gtk's own widgets is private API for now, so cannot be used by LibreOffice, so I currently don't see a way to handle these without changes on Gtk side (see [1]). [1] https://gitlab.gnome.org/GNOME/gtk/-/issues/6272 Change-Id: I2a5ca4448ad14a61dc96aef7b22af36baeeed5c4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160929 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
-rw-r--r--vcl/Library_vclplug_gtk4.mk1
-rw-r--r--vcl/unx/gtk4/a11y.cxx12
-rw-r--r--vcl/unx/gtk4/gtkaccessibleeventlistener.cxx63
-rw-r--r--vcl/unx/gtk4/gtkaccessibleeventlistener.hxx35
4 files changed, 111 insertions, 0 deletions
diff --git a/vcl/Library_vclplug_gtk4.mk b/vcl/Library_vclplug_gtk4.mk
index bb9d82ad570f..a288e5151aa6 100644
--- a/vcl/Library_vclplug_gtk4.mk
+++ b/vcl/Library_vclplug_gtk4.mk
@@ -88,6 +88,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk4,\
vcl/unx/gtk4/a11y \
vcl/unx/gtk4/convert3to4 \
vcl/unx/gtk4/customcellrenderer \
+ vcl/unx/gtk4/gtkaccessibleeventlistener \
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 c8103471b085..37b54bae0475 100644
--- a/vcl/unx/gtk4/a11y.cxx
+++ b/vcl/unx/gtk4/a11y.cxx
@@ -10,6 +10,7 @@
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp>
#include <com/sun/star/accessibility/XAccessibleText.hpp>
#include <com/sun/star/accessibility/XAccessibleValue.hpp>
@@ -20,6 +21,7 @@
#if GTK_CHECK_VERSION(4, 9, 0)
#include "a11y.hxx"
+#include "gtkaccessibleeventlistener.hxx"
#define OOO_TYPE_FIXED (ooo_fixed_get_type())
#define OOO_FIXED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OOO_TYPE_FIXED, OOoFixed))
@@ -617,6 +619,16 @@ lo_accessible_new(GdkDisplay* pDisplay, GtkAccessible* pParent,
GTK_ACCESSIBLE_PROPERTY_VALUE_MAX, fMaxValue, -1);
}
+ // register event listener
+ css::uno::Reference<css::accessibility::XAccessibleEventBroadcaster> xBroadcaster(
+ xContext, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ css::uno::Reference<css::accessibility::XAccessibleEventListener> xListener(
+ new GtkAccessibleEventListener(ret));
+ xBroadcaster->addAccessibleEventListener(xListener);
+ }
+
return ret;
}
diff --git a/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx b/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx
new file mode 100644
index 000000000000..1bfa69530be3
--- /dev/null
+++ b/vcl/unx/gtk4/gtkaccessibleeventlistener.cxx
@@ -0,0 +1,63 @@
+/* -*- 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 <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <sal/log.hxx>
+
+#include "gtkaccessibleeventlistener.hxx"
+
+GtkAccessibleEventListener::GtkAccessibleEventListener(LoAccessible* pLoAccessible)
+ : m_pLoAccessible(pLoAccessible)
+{
+ assert(m_pLoAccessible);
+ g_object_ref(m_pLoAccessible);
+}
+
+GtkAccessibleEventListener::~GtkAccessibleEventListener()
+{
+ assert(m_pLoAccessible);
+ g_object_unref(m_pLoAccessible);
+}
+
+void GtkAccessibleEventListener::disposing(const com::sun::star::lang::EventObject&) {}
+
+void GtkAccessibleEventListener::notifyEvent(
+ const com::sun::star::accessibility::AccessibleEventObject& rEvent)
+{
+ switch (rEvent.EventId)
+ {
+ case css::accessibility::AccessibleEventId::STATE_CHANGED:
+ {
+ sal_Int64 nState;
+ bool bNewValueSet = false;
+ if (rEvent.NewValue >>= nState)
+ {
+ bNewValueSet = true;
+ }
+ else if (!(rEvent.OldValue >>= nState))
+ {
+ assert(false && "neither old nor new value set");
+ }
+
+ if (nState == css::accessibility::AccessibleStateType::CHECKED)
+ {
+ GtkAccessibleTristate eState
+ = bNewValueSet ? GTK_ACCESSIBLE_TRISTATE_TRUE : GTK_ACCESSIBLE_TRISTATE_FALSE;
+ gtk_accessible_update_state(GTK_ACCESSIBLE(m_pLoAccessible),
+ GTK_ACCESSIBLE_STATE_CHECKED, eState, -1);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx b/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx
new file mode 100644
index 000000000000..584cacff85fa
--- /dev/null
+++ b/vcl/unx/gtk4/gtkaccessibleeventlistener.hxx
@@ -0,0 +1,35 @@
+/* -*- 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 <gtk/gtk.h>
+
+#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <cppuhelper/implbase.hxx>
+
+struct LoAccessible;
+
+class GtkAccessibleEventListener final
+ : public cppu::WeakImplHelper<css::accessibility::XAccessibleEventListener>
+{
+public:
+ explicit GtkAccessibleEventListener(LoAccessible* pLoAccessible);
+ ~GtkAccessibleEventListener();
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) override;
+ virtual void SAL_CALL
+ notifyEvent(const css::accessibility::AccessibleEventObject& rEvent) override;
+
+private:
+ LoAccessible* m_pLoAccessible;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */