summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2023-11-09 15:31:57 +0100
committerMichael Weghorn <m.weghorn@posteo.de>2023-11-09 21:00:05 +0100
commit3aca2d9776a871f15009a1aa70628ba3a03ee147 (patch)
tree411aa03ed3baf2053d3df45c8855a1f1e95c6bcf /vcl
parent9cb506a37a3228cf820eaeec681e49c08607cf59 (diff)
gtk4 a11y: Handle the "level" object attribute
Add initial handling/mapping for object attributes. In LibreOffice and Gtk 3/ATK/AT-SPI, object attributes are currently key-value pairs, so arbitrary attribute names and values can be set. For Gtk 4, there's currently a discussion on how AT-SPI object attributes should be handled, s. [1]. One potential option is for them to be handled as `GtkAccessibleProperty`s. In any case, there's already a `GTK_ACCESSIBLE_PROPERTY_LEVEL` property that matches the "level" object attribute that Writer sets for headings to specify what heading level this is (s. `SwAccessibleParagraph::getExtendedAttributes`) and that the gtk3 VCL plugin reports as an ATK/AT-SPI object attribute with the same name and semantics for AT-SPI, which is in line with the specification in the Core Accessibility API Mappings 1.2 [2]. Map that LO object attribute to the above-mentioned `GTK_ACCESSIBLE_PROPERTY_LEVEL`. The property is currently not yet mapped to an AT-SPI attribute in Gtk 4, but together with a corresponding merge request [3], the object attribute can be seen in Accerciser as expected. While object properties in LO are currently generally only generated/updated when they're queried (via `XAccessibleExtendedAttributes::getExtendedAttributes`), the `GtkAccessibleProperty` handling in Gtk 4 would require to explicitly call `gtk_accessible_update_property` with the new value. This may require further adjustments on LO side to keep the properties up-to-date (e.g. adding something like a new `AccessibleEventId::OBJECT_PROPERTY_CHANGED` event and then implementing corresponding handling in all places that provide object properties). But that's something to look into later, also depending on the outcome of the discussion in [1]. (As of now, the gtk4 VCL plugin doesn't handle any a11y events, not even the existing ones.) [1] https://gitlab.gnome.org/GNOME/gtk/-/issues/6196 [2] https://www.w3.org/TR/core-aam-1.2/#ariaLevelHeading [3] https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6549 Change-Id: I024afd7b527a20922e69156e1562dda783be2b49 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159216 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/unx/gtk4/a11y.cxx47
1 files changed, 47 insertions, 0 deletions
diff --git a/vcl/unx/gtk4/a11y.cxx b/vcl/unx/gtk4/a11y.cxx
index 8bd1b97f0aa9..42a0fd59e4b9 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/XAccessibleExtendedAttributes.hpp>
#include <com/sun/star/accessibility/XAccessibleText.hpp>
#include <com/sun/star/accessibility/XAccessibleValue.hpp>
#include <unx/gtk/gtkframe.hxx>
@@ -307,6 +308,50 @@ static void applyStates(GtkAccessible* pGtkAccessible,
}
}
+static void applyObjectAttribute(GtkAccessible* pGtkAccessible, const OUString& rName,
+ const OUString& rValue)
+{
+ assert(pGtkAccessible);
+
+ if (rName == u"level")
+ {
+ const int nLevel = static_cast<int>(rValue.toInt32());
+ gtk_accessible_update_property(pGtkAccessible, GTK_ACCESSIBLE_PROPERTY_LEVEL, nLevel, -1);
+ }
+}
+
+/**
+ * Based on the object attributes set for xContext, set the corresponding Gtk equivalents
+ * in pGtkAccessible, where applicable.
+ */
+static void
+applyObjectAttributes(GtkAccessible* pGtkAccessible,
+ css::uno::Reference<css::accessibility::XAccessibleContext> xContext)
+{
+ assert(pGtkAccessible);
+
+ css::uno::Reference<css::accessibility::XAccessibleExtendedAttributes> xAttributes(
+ xContext, css::uno::UNO_QUERY);
+ if (!xAttributes.is())
+ return;
+
+ OUString sAttrs;
+ xAttributes->getExtendedAttributes() >>= sAttrs;
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ const OUString sAttribute = sAttrs.getToken(0, ';', nIndex);
+ sal_Int32 nColonPos = 0;
+ const OUString sName = sAttribute.getToken(0, ':', nColonPos);
+ const OUString sValue = sAttribute.getToken(0, ':', nColonPos);
+ assert(nColonPos == -1
+ && "Too many colons in attribute that should have \"name:value\" syntax");
+
+ applyObjectAttribute(pGtkAccessible, sName, sValue);
+ } while (nIndex >= 0);
+}
+
#define LO_TYPE_ACCESSIBLE (lo_accessible_get_type())
#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))
@@ -545,6 +590,8 @@ lo_accessible_new(GdkDisplay* pDisplay, GtkAccessible* pParent,
applyStates(pGtkAccessible, xContext);
+ applyObjectAttributes(GTK_ACCESSIBLE(ret), xContext);
+
// set values from XAccessibleValue interface if that's implemented
css::uno::Reference<css::accessibility::XAccessibleValue> xAccessibleValue(xContext,
css::uno::UNO_QUERY);