Skip to content

Fix crashes with AT-SPI2 screen readers (Orca) on Linux#3191

Draft
danijel1124 wants to merge 2 commits into
BearWare:masterfrom
danijel1124:fix/orca-accessibility-crash
Draft

Fix crashes with AT-SPI2 screen readers (Orca) on Linux#3191
danijel1124 wants to merge 2 commits into
BearWare:masterfrom
danijel1124:fix/orca-accessibility-crash

Conversation

@danijel1124

Copy link
Copy Markdown

Summary

  • QTableView with an active screen reader (Orca/AT-SPI2) crashed in several ways due to bugs in Qt 6.4.x's QAccessibleTable implementation
  • Replaces the default accessibility backend for MyTableView with a custom MyTableViewAccessible that fixes all identified crash paths
  • Tested with Orca on Ubuntu 24.04 / Qt 6.4.2: server list opens, navigation works, reconnect works, dialog close works without crash

What was fixed

  • focusChild() with no selection — guards against invalid current index, preventing cellAt(-1,-1) calls that crash the AT-SPI2 bridge
  • child() / cellAt() returning nullptr — returns a dummy cell instead, working around a missing null-check in atspiadaptor.cpp
  • Dangling pointer on dialog close — uses QAccessible::Id (Qt-managed IDs) for the cell cache instead of raw pointers
  • Wrong child index mapping — fixed to account for header rows/columns, matching Qt's own accessibleTable2Index() formula
  • Missing pure virtual implementations — all methods of QAccessibleTableInterface implemented
  • ensureSelection() — table always has a current index when shown, reducing AT-SPI2 focus errors

Test plan

  • Open server list with Orca active — no crash
  • Navigate table rows with arrow keys
  • Connect to a server and reconnect
  • Close the server list dialog — no crash
  • Test on Qt 6.4.x / Ubuntu with AT-SPI2 bridge

QTableView with a screen reader active crashed in several ways due to
bugs in Qt 6.4.x's QAccessibleTable implementation. This replaces the
default accessibility backend for MyTableView with a custom one that:

- Guards focusChild() against invalid (unselected) current index,
  preventing cellAt(-1,-1) calls that crash the AT-SPI2 bridge
- Returns a dummy cell instead of nullptr from cellAt() and child(),
  working around a missing null-check in atspiadaptor.cpp
- Uses QAccessible::Id (Qt-managed IDs) for the cell cache instead of
  raw pointers, preventing dangling-pointer crashes when the dialog
  is closed while a screen reader is active
- Fixes child index mapping to account for header rows/columns,
  matching Qt's own accessibleTable2Index() formula
- Implements all pure virtual methods of QAccessibleTableInterface

Also adds ensureSelection() so the table always has a current index
when shown, further reducing the chance of focus-related AT-SPI2 errors.

Tested with Orca on Ubuntu 24.04 / Qt 6.4.2: server list opens,
navigation works, reconnect works, dialog close works without crash.

Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@bear101 bear101 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CoBC are you able to test this?

void MyTableView::showEvent(QShowEvent* e)
{
QTableView::showEvent(e);
ensureSelection();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also #ifdef here


MyTableView::MyTableView(QWidget* parent/* = nullptr*/) : QTableView(parent)
{
QAccessible::installFactory(myTableViewFactory);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably have a:
#if defined(Q_OS_LINUX) && QT_VERSION == QT_VERSION_CHECK(6,4,0)
I'm not aware that other platforms have this issue or other Qt versions.

@bear101

bear101 commented May 20, 2026

Copy link
Copy Markdown
Contributor

I'm changing this to Draft because the changes have unknown side effects on macOS and Windows as well as other versions of Qt.

@bear101 bear101 marked this pull request as draft May 20, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants