summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp126
1 files changed, 124 insertions, 2 deletions
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index 345fb5e2fa..c040dab5e1 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -1924,6 +1924,124 @@ QAccessible::TextBoundaryType AtSpiAdaptor::qAccessibleBoundaryType(int atspiTex
return QAccessible::CharBoundary;
}
+namespace
+{
+ struct AtSpiAttribute {
+ QString name;
+ QString value;
+ AtSpiAttribute(const QString &aName, const QString &aValue) : name(aName), value(aValue) {}
+ bool isNull() const { return name.isNull() || value.isNull(); }
+ };
+
+ QString atspiColor(const QString &ia2Color)
+ {
+ // "rgb(%u,%u,%u)" -> "%u,%u,%u"
+ return ia2Color.mid(4, ia2Color.length() - (4+1));
+ }
+
+ QString atspiSize(const QString &ia2Size)
+ {
+ // "%fpt" -> "%f"
+ return ia2Size.left(ia2Size.length() - 2);
+ }
+
+ AtSpiAttribute atspiTextAttribute(const QString &ia2Name, const QString &ia2Value)
+ {
+ QString name = ia2Name;
+ QString value = ia2Value;
+
+ // IAccessible2: http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes
+ // ATK attribute names: https://git.gnome.org/browse/orca/tree/src/orca/text_attribute_names.py
+ // ATK attribute values: https://developer.gnome.org/atk/unstable/AtkText.html#AtkTextAttribute
+
+ // https://bugzilla.gnome.org/show_bug.cgi?id=744553 "ATK docs provide no guidance for allowed values of some text attributes"
+ // specifically for "weight", "invalid", "language" and value range for colors
+
+ if (ia2Name == QStringLiteral("background-color")) {
+ name = QStringLiteral("bg-color");
+ value = atspiColor(value);
+ } else if (ia2Name == QStringLiteral("font-family")) {
+ name = QStringLiteral("family-name");
+ } else if (ia2Name == QStringLiteral("color")) {
+ name = QStringLiteral("fg-color");
+ value = atspiColor(value);
+ } else if (ia2Name == QStringLiteral("text-align")) {
+ name = QStringLiteral("justification");
+ if (value == QStringLiteral("justify")) {
+ value = QStringLiteral("fill");
+ } else {
+ if (value != QStringLiteral("left") &&
+ value != QStringLiteral("right") &&
+ value != QStringLiteral("center")
+ ) {
+ value = QString();
+ qAtspiDebug() << "Unknown text-align attribute value \"" << value << "\" cannot be translated to AT-SPI.";
+ }
+ }
+ } else if (ia2Name == QStringLiteral("font-size")) {
+ name = QStringLiteral("size");
+ value = atspiSize(value);
+ } else if (ia2Name == QStringLiteral("font-style")) {
+ name = QStringLiteral("style");
+ if (value != QStringLiteral("normal") &&
+ value != QStringLiteral("italic") &&
+ value != QStringLiteral("oblique")
+ ) {
+ value = QString();
+ qAtspiDebug() << "Unknown font-style attribute value \"" << value << "\" cannot be translated to AT-SPI.";
+ }
+ } else if (ia2Name == QStringLiteral("text-underline-type")) {
+ name = QStringLiteral("underline");
+ if (value != QStringLiteral("none") &&
+ value != QStringLiteral("single") &&
+ value != QStringLiteral("double")
+ ) {
+ value = QString();
+ qAtspiDebug() << "Unknown text-underline-type attribute value \"" << value << "\" cannot be translated to AT-SPI.";
+ }
+ } else if (ia2Name == QStringLiteral("font-weight")) {
+ name = QStringLiteral("weight");
+ if (value == QStringLiteral("normal"))
+ // Orca seems to accept all IAccessible2 values except for "normal"
+ // (on which it produces traceback and fails to read any following text attributes),
+ // but that is the default value, so omit it anyway
+ value = QString();
+ } else if (ia2Name == QStringLiteral("text-position")) {
+ name = QStringLiteral("vertical-align");
+ if (value != QStringLiteral("baseline") &&
+ value != QStringLiteral("super") &&
+ value != QStringLiteral("sub")
+ ) {
+ value = QString();
+ qAtspiDebug() << "Unknown text-position attribute value \"" << value << "\" cannot be translated to AT-SPI.";
+ }
+ } else if (ia2Name == QStringLiteral("writing-mode")) {
+ name = QStringLiteral("direction");
+ if (value == QStringLiteral("lr"))
+ value = QStringLiteral("ltr");
+ else if (value == QStringLiteral("rl"))
+ value = QStringLiteral("rtl");
+ else if (value == QStringLiteral("tb")) {
+ // IAccessible2 docs refer to XSL, which specifies "tb" is shorthand for "tb-rl"; so at least give a hint about the horizontal direction (ATK does not support vertical direction in this attribute (yet))
+ value = QStringLiteral("rtl");
+ qAtspiDebug() << "writing-mode attribute value \"tb\" translated only w.r.t. horizontal direction; vertical direction ignored";
+ } else {
+ value = QString();
+ qAtspiDebug() << "Unknown writing-mode attribute value \"" << value << "\" cannot be translated to AT-SPI.";
+ }
+ } else if (ia2Name == QStringLiteral("language")) {
+ // OK - ATK has no docs on the format of the value, IAccessible2 has reasonable format - leave it at that now
+ } else if (ia2Name == QStringLiteral("invalid")) {
+ // OK - ATK docs are vague but suggest they support the same range of values as IAccessible2
+ } else {
+ // attribute we know nothing about
+ name = QString();
+ value = QString();
+ }
+ return AtSpiAttribute(name, value);
+ }
+}
+
// FIXME all attribute methods below should share code
QVariantList AtSpiAdaptor::getAttributes(QAccessibleInterface *interface, int offset, bool includeDefaults) const
{
@@ -1938,7 +2056,9 @@ QVariantList AtSpiAdaptor::getAttributes(QAccessibleInterface *interface, int of
foreach (const QString &attr, attributes) {
QStringList items;
items = attr.split(QLatin1Char(':'), QString::SkipEmptyParts, Qt::CaseSensitive);
- set[items[0]] = items[1];
+ AtSpiAttribute attribute = atspiTextAttribute(items[0], items[1]);
+ if (!attribute.isNull())
+ set[attribute.name] = attribute.value;
}
QVariantList list;
@@ -1962,7 +2082,9 @@ QVariantList AtSpiAdaptor::getAttributeValue(QAccessibleInterface *interface, in
foreach (const QString& attr, attributes) {
QStringList items;
items = attr.split(QLatin1Char(':'), QString::SkipEmptyParts, Qt::CaseSensitive);
- map[items[0]] = items[1];
+ AtSpiAttribute attribute = atspiTextAttribute(items[0], items[1]);
+ if (!attribute.isNull())
+ map[attribute.name] = attribute.value;
}
mapped = map[attributeName];
defined = mapped.isEmpty();