summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2025-01-14 11:32:25 +0100
committerMichael Weghorn <m.weghorn@posteo.de>2025-01-14 15:24:32 +0100
commit3eaa35e8bacc19a85f5c9d907450846bfa8bffae (patch)
tree7fc39e6d5cc04d8d76af786c3fe8b2dbe17a4657
parent91a97c7d11d77935ff459679ddcacd59014771d2 (diff)
tdf#163335 qt a11y: Work around broken sw selection handling
When using the qt6 vcl plugin with the Orca screen reader running, selecting text in Writer resulted in a crash due to an IndexOutOfBoundsException being thrown. Backtrace: Thread 1 received signal SIGABRT, Aborted. __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 warning: 44 ./nptl/pthread_kill.c: No such file or directory (rr) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007f889b09ddef in __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:78 #2 0x00007f889b049d02 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007f889b0324f0 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007f889aca1a3d in ??? () at /lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007f889acb300a in ??? () at /lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x00007f889aca15e9 in std::terminate() () at /lib/x86_64-linux-gnu/libstdc++.so.6 #7 0x00007f889acb3288 in __cxa_throw () at /lib/x86_64-linux-gnu/libstdc++.so.6 #8 0x00007f8862346900 in SwAccessibleSelectionHelper::throwIndexOutOfBoundsException (this=0x561f2f8d1910) at .../libreoffice/sw/source/core/access/accselectionhelper.cxx:72 #9 0x00007f8862347df8 in SwAccessibleSelectionHelper::getSelectedAccessibleChild (this=0x561f2f8d1910, nSelectedChildIndex=0) at .../libreoffice/sw/source/core/access/accselectionhelper.cxx:283 #10 0x00007f8862298e6f in SwAccessibleDocument::getSelectedAccessibleChild (this=0x561f2f8d1800, nSelectedChildIndex=0) at .../libreoffice/sw/source/core/access/accdoc.cxx:467 #11 0x00007f8862298eaf in non-virtual thunk to SwAccessibleDocument::getSelectedAccessibleChild(long) () at .../libreoffice/sw/source/core/access/accdoc.cxx:467 #12 0x00007f88878c6200 in QtAccessibleWidget::selectedItem (this=0x7f887c014ac0, nSelectionIndex=0) at vcl/qt6/../qt5/QtAccessibleWidget.cxx:1861 #13 0x00007f8885f08ba0 in AtSpiAdaptor::selectionInterface (this=0x561f2b8a7070, interface=0x7f887c014ac0, function=..., message=..., connection=...) at .../qt5/qtbase/src/gui/accessible/linux/atspiadaptor.cpp:2596 #14 0x00007f8885f03ce1 in AtSpiAdaptor::handleMessage (this=0x561f2b8a7070, message=..., connection=...) at .../qt5/qtbase/src/gui/accessible/linux/atspiadaptor.cpp:1479 #15 0x00007f888366d217 in QDBusConnectionPrivate::activateObject (this=0x7f887c00a390, node=..., msg=..., pathStartPos=27) at .../qt5/qtbase/src/dbus/qdbusintegrator.cpp:1448 #16 0x00007f888366e1d0 in QDBusActivateObjectEvent::placeMetaCall (this=0x7f887c03aca0) at .../qt5/qtbase/src/dbus/qdbusintegrator.cpp:1604 #17 0x00007f8886b09bb1 in QObject::event (this=0x561f2b8a7070, e=0x7f887c03aca0) at .../qt5/qtbase/src/corelib/kernel/qobject.cpp:1431 #18 0x00007f88849e2dd0 in QApplicationPrivate::notify_helper (this=0x561f2a554ae0, receiver=0x561f2b8a7070, e=0x7f887c03aca0) at .../qt5/qtbase/src/widgets/kernel/qapplication.cpp:3305 #19 0x00007f88849e6ced in QApplication::notify (this=0x561f2a541420, receiver=0x561f2b8a7070, e=0x7f887c03aca0) at .../qt5/qtbase/src/widgets/kernel/qapplication.cpp:3255 #20 0x00007f8886a481b9 in QCoreApplication::notifyInternal2 (receiver=0x561f2b8a7070, event=0x7f887c03aca0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1118 #21 0x00007f8886a48e29 in QCoreApplication::sendEvent (receiver=0x561f2b8a7070, event=0x7f887c03aca0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1558 #22 0x00007f8886a49d68 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x561f2a56fee0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1898 #23 0x00007f8886a48c6c in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at .../qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1752 #24 0x00007f88870377b1 in postEventSourceDispatch (s=0x561f2a5cce80) at .../qt5/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:246 #25 0x00007f888d50b81f in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #26 0x00007f888d50da57 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #27 0x00007f888d50e1c0 in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #28 0x00007f88870369eb in QEventDispatcherGlib::processEvents (this=0x561f2a545d00, flags=...) at .../qt5/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:399 #29 0x00007f8886164858 in QPAEventDispatcherGlib::processEvents (this=0x561f2a545d00, flags=...) at .../qt5/qtbase/src/gui/platform/unix/qeventdispatcher_glib.cpp:89 #30 0x00007f888796a492 in QtInstance::ImplYield (this=0x561f2a5d16c0, bWait=true, bHandleAllCurrentEvents=false) at vcl/qt6/../qt5/QtInstance.cxx:464 #31 0x00007f888796d511 in QtInstance::DoYield (this=0x561f2a5d16c0, bWait=true, bHandleAllCurrentEvents=false) at vcl/qt6/../qt5/QtInstance.cxx:475 #32 0x00007f88924bd626 in ImplYield (i_bWait=true, i_bAllEvents=false) at .../libreoffice/vcl/source/app/svapp.cxx:385 #33 0x00007f88924bcf3f in Application::Yield () at .../libreoffice/vcl/source/app/svapp.cxx:488 #34 0x00007f88924bcd20 in Application::Execute () at .../libreoffice/vcl/source/app/svapp.cxx:360 #35 0x00007f889b327b89 in desktop::Desktop::Main (this=0x7ffcd9ea1c00) at .../libreoffice/desktop/source/app/app.cxx:1679 #36 0x00007f88924deaa6 in ImplSVMain () at .../libreoffice/vcl/source/app/svmain.cxx:230 #37 0x00007f88924e0699 in SVMain () at .../libreoffice/vcl/source/app/svmain.cxx:248 #38 0x00007f889b3a146a in soffice_main () at .../libreoffice/desktop/source/app/sofficemain.cxx:121 #39 0x0000561ef2802a6d in sal_main () at .../libreoffice/desktop/source/app/main.c:51 #40 0x0000561ef2802a47 in main (argc=2, argv=0x7ffcd9ea1e08) at .../libreoffice/desktop/source/app/main.c:49 While QtAccessibleWidget::selectedItem already returns early if the passed selection index is too large according to what XAccessibleSelection::getSelectedAccessibleChildCount() returns, this is not enough because Writer's SwAccessibleSelectionHelper has an inconsistent/broken implementation: SwAccessibleSelectionHelper::getSelectedAccessibleChildCount returns the count of paragraphs that are (partially) selected by the text cursor if no other objects are selected. However, SwAccessibleSelectionHelper::getSelectedAccessibleChild doesn't take these into account and therefore throws the IndexOutOfBoundsException when called with any index. Temporarily (in particular for backporting to release branches), handle the exception in QtAccessibleWidget::selectedItem like other a11y bridges do (see e.g. `selection_ref_selection` for the gtk3 VCL plugin) to avoid the crash. The underlying Writer issue described above will be fixed in a separate commit (and for master only). Change-Id: I874ad4a7a9faf79492967c943517d83df5f47e75 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180228 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
-rw-r--r--vcl/qt5/QtAccessibleWidget.cxx20
1 files changed, 16 insertions, 4 deletions
diff --git a/vcl/qt5/QtAccessibleWidget.cxx b/vcl/qt5/QtAccessibleWidget.cxx
index 7438c5e368d1..f7f55f74f82d 100644
--- a/vcl/qt5/QtAccessibleWidget.cxx
+++ b/vcl/qt5/QtAccessibleWidget.cxx
@@ -51,6 +51,7 @@
#include <com/sun/star/accessibility/XAccessibleValue.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <comphelper/AccessibleImplementationHelper.hxx>
@@ -1858,11 +1859,22 @@ QAccessibleInterface* QtAccessibleWidget::selectedItem(int nSelectionIndex) cons
return nullptr;
}
- Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(nSelectionIndex);
- if (!xChild)
- return nullptr;
+ try
+ {
+ Reference<XAccessible> xChild = xSelection->getSelectedAccessibleChild(nSelectionIndex);
+ if (xChild)
+ return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
+ }
+ catch (const css::lang::IndexOutOfBoundsException&)
+ {
+ // tdf#163335: temporarily work around inconsistency in
+ // SwAccessibleSelectionHelper::getSelectedAccessibleChildCount
+ // returning a larger number of selected items than
+ // SwAccessibleSelectionHelper::getSelectedAccessibleChild supports
+ SAL_WARN("vcl.qt", "QtAccessibleWidget::selectedItem triggered an exception");
+ }
- return QAccessible::queryAccessibleInterface(QtAccessibleRegistry::getQObject(xChild));
+ return nullptr;
}
bool QtAccessibleWidget::isSelected(QAccessibleInterface* pItem) const