vcl/qt5/QtAccessibleWidget.cxx |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

New commits:
commit 46a03cb528860c7571c2ff046bef307bb7b04ac2
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Mon Mar 6 08:49:03 2023 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Mon Mar 6 12:17:55 2023 +0000

    qt a11y: Add mapping for relations added in Qt 6.6
    
    Map `AccessibleRelationType::CONTENT_FLOWS_FROM`,
    `AccessibleRelationType::CONTENT_FLOWS_TO` and
    `AccessibleRelationType::DESCRIBED_BY` to the
    Qt equivalents added in Qt 6.6 and vice versa.
    
    As described in more detail in
    
        commit e55713dffbe8d8eba18068f6c2af14c10b787220
        Date:   Fri Feb 17 15:25:37 2023 +0100
    
            qt a11y: Invert relation type to match Qt's semantic
    
    , the "inverse" relation needs to be used when
    mapping to/from the Qt relation.
    
    For example the Orca screen reader on Linux makes
    use of the FlOWS_FROM and FLOWS_TO relations.
    So far, when using the qt6 VCL plugin with Orca
    running, moving focus to a Writer paragraph resulted
    in these warnings being emitted:
    
        warn:vcl.qt:220606:220606:vcl/qt6/../qt5/QtAccessibleWidget.cxx:218: 
Unmatched relation: 1
        warn:vcl.qt:220606:220606:vcl/qt6/../qt5/QtAccessibleWidget.cxx:218: 
Unmatched relation: 2
    
    and thus Orca not being able to make use of those relations.
    
    Sample use in Accerciser's Python console, with a Writer document
    having three paragraphs with texts "First", "second", and "third"
    and the a11y object of the second paragraph's a11y object selected
    in Accerciser's a11y tree view:
    
        In [1]: acc.queryText().getStringAtOffset(0, 
pyatspi.TEXT_GRANULARITY_PARAGRAPH)
        Out[1]: ('second', 0, 6)
        In [2]: acc.get_relation_set()
        Out[2]:
        [<Atspi.Relation object at 0x7fccc36862c0 (AtspiRelation at 0x421e100)>,
         <Atspi.Relation object at 0x7fccc358c280 (AtspiRelation at 0x4493c60)>]
        In [3]: first_relation = acc.get_relation_set()[0]
        In [4]: first_relation.get_n_targets()
        Out[4]: 1
        In [5]: first_relation.get_relation_type()
        Out[5]: <enum ATSPI_RELATION_FLOWS_FROM of type Atspi.RelationType>
        In [6]: first_relation.get_target(0)
        Out[6]: <Atspi.Accessible object at 0x7fccc35aa4c0 (AtspiAccessible at 
0x4479820)>
        In [7]: first_relation.get_target(0).queryText().getStringAtOffset(0, 1)
        Out[7]: ('First', 0, 5)
        In [8]: second_relation = acc.get_relation_set()[1]
        In [9]: second_relation.get_n_targets()
        Out[9]: 1
        In [10]: second_relation.get_relation_type()
        Out[10]: <enum ATSPI_RELATION_FLOWS_TO of type Atspi.RelationType>
        In [11]: 
second_relation.get_target(0).queryText().getStringAtOffset(0,1)
        Out[11]: ('third', 0, 5)
    
    (QTBUG-105864 [1] also has a sample doc and pyatspi script that can be used
    for testing.)
    
    Qt commit adding the relations [2]:
    
        commit f5358e5932bc8701621389c265c4ea86c92c536c
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Fri Feb 17 13:48:38 2023 +0100
    
            a11y: Add new relations DescriptionFor, Described, Flows{From,To}
    
            This is equivalent to the corresponding relation types defined
            in the IAccessible2 spec [1] (IA2_RELATION_DESCRIPTION_FOR,
            IA2_RELATION_DESCRIBED_BY, IA2_RELATION_FLOWS_FROM,
            IA2_RELATION_FLOWS_TO) and for AT-SPI on Linux [2]
            (relation types ATSPI_RELATION_DESCRIPTION_FOR,
            ATSPI_RELATION_DESCRIBED_BY, ATSPI_RELATION_FLOWS_FROM,
            ATSPI_RELATION_FLOWS_TO).
    
            User Interface Automation (UIA) on Windows also has corresponding
            properties for 3 of them [3]: UIA_DescribedByPropertyId,
            UIA_FlowsFromPropertyId, UIA_FlowsToPropertyId.
    
            This commit adds the new flags and implements the mapping for
            the AT-SPI case.
            Note that the relation type is conceptually always "inverted"
            when comparing Qt and AT-SPI (or Qt and UIA)
            as clarified in afbfe30093d49eff0ec4c28c220d33c233b9f807.
    
            "QAccessible::Description" instead of "QAccessible::DescriptionFor"
            would align better with the naming scheme of the other relations, 
but
            that is already used in the Text enum.
    
            [1] 
https://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/group__grp_relations.html
            [2] 
https://lazka.github.io/pgi-docs/Atspi-2.0/enums.html#Atspi.RelationType
            [3] 
https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-automation-element-propids
    
            [ChangeLog][QtGui][QAccessible::RelationFlag] Added new relation
            flags DescriptionFor, Described, FlowsFrom and FlowsTo.
    
            Fixes: QTBUG-105864
            Change-Id: If2d46099eeea75e177358c821d1ae833a553bd0e
            Reviewed-by: Jan Arve Sæther <jan-arve.saet...@qt.io>
    
    [1] https://bugreports.qt.io/browse/QTBUG-105864
    [2] 
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=f5358e5932bc8701621389c265c4ea86c92c536c
    
    Change-Id: I6e5d78fb26f62a6f1745d4f94647e8dc0fe2abfd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138687
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/qt5/QtAccessibleWidget.cxx b/vcl/qt5/QtAccessibleWidget.cxx
index 7a55bae884f5..13823006b6cd 100644
--- a/vcl/qt5/QtAccessibleWidget.cxx
+++ b/vcl/qt5/QtAccessibleWidget.cxx
@@ -223,21 +223,28 @@ QAccessible::Relation lcl_matchUnoRelation(short 
relationType)
     // Qt semantics is the other way around
     switch (relationType)
     {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+        case AccessibleRelationType::CONTENT_FLOWS_FROM:
+            return QAccessible::FlowsTo;
+        case AccessibleRelationType::CONTENT_FLOWS_TO:
+            return QAccessible::FlowsFrom;
+#endif
         case AccessibleRelationType::CONTROLLED_BY:
             return QAccessible::Controller;
         case AccessibleRelationType::CONTROLLER_FOR:
             return QAccessible::Controlled;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+        case AccessibleRelationType::DESCRIBED_BY:
+            return QAccessible::DescriptionFor;
+#endif
         case AccessibleRelationType::LABELED_BY:
             return QAccessible::Label;
         case AccessibleRelationType::LABEL_FOR:
             return QAccessible::Labelled;
         case AccessibleRelationType::INVALID:
-        case AccessibleRelationType::CONTENT_FLOWS_FROM:
-        case AccessibleRelationType::CONTENT_FLOWS_TO:
         case AccessibleRelationType::MEMBER_OF:
         case AccessibleRelationType::SUB_WINDOW_OF:
         case AccessibleRelationType::NODE_CHILD_OF:
-        case AccessibleRelationType::DESCRIBED_BY:
         default:
             SAL_WARN("vcl.qt", "Unmatched relation: " << relationType);
             return {};
@@ -253,10 +260,21 @@ short lcl_matchQtRelation(QAccessible::Relation 
relationType)
             return AccessibleRelationType::CONTROLLER_FOR;
         case QAccessible::Controller:
             return AccessibleRelationType::CONTROLLED_BY;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+        case QAccessible::DescriptionFor:
+            return AccessibleRelationType::DESCRIBED_BY;
+        case QAccessible::FlowsFrom:
+            return AccessibleRelationType::CONTENT_FLOWS_TO;
+        case QAccessible::FlowsTo:
+            return AccessibleRelationType::CONTENT_FLOWS_FROM;
+#endif
         case QAccessible::Labelled:
             return AccessibleRelationType::LABEL_FOR;
         case QAccessible::Label:
             return AccessibleRelationType::LABELED_BY;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+        case QAccessible::Described:
+#endif
         default:
             SAL_WARN("vcl.qt", "Unmatched relation: " << relationType);
     }

Reply via email to