diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2023-11-09 15:31:57 +0100 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2023-11-09 21:00:05 +0100 |
commit | 3aca2d9776a871f15009a1aa70628ba3a03ee147 (patch) | |
tree | 411aa03ed3baf2053d3df45c8855a1f1e95c6bcf /vcl | |
parent | 9cb506a37a3228cf820eaeec681e49c08607cf59 (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.cxx | 47 |
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); |