vcl/qt5/QtAccessibleEventListener.cxx |   36 +++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

New commits:
commit dce8fda483f38eb8624c89c20c07a1af68e3952e
Author:     Michael Weghorn <[email protected]>
AuthorDate: Fri Aug 26 17:00:01 2022 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Aug 26 19:38:27 2022 +0200

    qt a11y: Set the (un)selected child in selection add/remove event
    
    Qt itself sets the child index when sending
    `QAccessible::SelectionAdd` or `QAccessible::SelectionRemove`
    events for its own widgets and the handling in its AT-SPI adapter
    assumes that this is the case, so do so here as well.
    
    Work around QTBUG-105988 [1] by using the
    `QAccessibleEvent` ctor that takes a `QObject*` instead
    of the one that takes the `QAccesibleInterface*`, since
    calling `QAccessibleEvent::setChild` in the event object
    would otherwise break things.
    
    When used in combination with the suggested Qt changes to
    send AT-SPI `SelectionChanged` events for these event
    types and `QAccessible::SelectionWithin` [2] [3],
    the suggested Qt changes to add support
    for the AT-SPI selection interface [4] [5] and a
    corresponding LibreOffice demo change [6] that implements
    the suggested `QAccessibleSelectionInterface`, this
    makes Orca announce selected Calc cells for the qt6 VCL
    plugin.
    
    [1] https://bugreports.qt.io/browse/QTBUG-105988
    [2] https://codereview.qt-project.org/c/qt/qtbase/+/429146
    [3] https://codereview.qt-project.org/c/qt/qtbase/+/429147
    [4] https://codereview.qt-project.org/c/qt/qtbase/+/428566
    [5] https://codereview.qt-project.org/c/qt/qtbase/+/428567
    [6] https://gerrit.libreoffice.org/c/core/+/138750
    
    Change-Id: Id1cd28aa8cab208d7713ddd46ede5a7acd73334a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138882
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/qt5/QtAccessibleEventListener.cxx 
b/vcl/qt5/QtAccessibleEventListener.cxx
index 9dbc3f3e5504..3716472b2d96 100644
--- a/vcl/qt5/QtAccessibleEventListener.cxx
+++ b/vcl/qt5/QtAccessibleEventListener.cxx
@@ -321,13 +321,39 @@ void QtAccessibleEventListener::notifyEvent(const 
css::accessibility::Accessible
                 new QAccessibleEvent(pQAccessibleInterface, 
QAccessible::TableSummaryChanged));
             return;
         case AccessibleEventId::SELECTION_CHANGED_ADD:
-            QAccessible::updateAccessibility(
-                new QAccessibleEvent(pQAccessibleInterface, 
QAccessible::SelectionAdd));
-            return;
         case AccessibleEventId::SELECTION_CHANGED_REMOVE:
-            QAccessible::updateAccessibility(
-                new QAccessibleEvent(pQAccessibleInterface, 
QAccessible::SelectionRemove));
+        {
+            QAccessible::Event eEventType;
+            if (aEvent.EventId == AccessibleEventId::SELECTION_CHANGED_ADD)
+                eEventType = QAccessible::SelectionAdd;
+            else
+                eEventType = QAccessible::SelectionRemove;
+
+            uno::Reference<accessibility::XAccessible> xChildAcc;
+            aEvent.NewValue >>= xChildAcc;
+            if (!xChildAcc.is())
+            {
+                SAL_WARN("vcl.qt",
+                         "Selection add/remove event without the (un)selected 
accessible set");
+                return;
+            }
+            Reference<XAccessibleContext> xContext = 
xChildAcc->getAccessibleContext();
+            if (!xContext.is())
+            {
+                SAL_WARN("vcl.qt", "No valid XAccessibleContext for 
(un)selected accessible.");
+                return;
+            }
+
+            // use the QAccessibleEvent ctor taking a QObject* instead of the 
one that takes QAccessibleInterface*
+            // to work around QTBUG-105988
+            QAccessibleEvent* pSelectionAddEvent
+                = new QAccessibleEvent(pQAccessibleInterface->object(), 
eEventType);
+            // Qt expects the index of the (un)selected child to be set in the 
event
+            sal_Int32 nChildIndex = xContext->getAccessibleIndexInParent();
+            pSelectionAddEvent->setChild(nChildIndex);
+            QAccessible::updateAccessibility(pSelectionAddEvent);
             return;
+        }
         case AccessibleEventId::SELECTION_CHANGED_WITHIN:
             QAccessible::updateAccessibility(
                 new QAccessibleEvent(pQAccessibleInterface, 
QAccessible::SelectionWithin));

Reply via email to