Skip to content

chatdlg: replace QTextBrowser with QListView for screen reader accessibility#3748

Open
mcfnord wants to merge 2 commits into
jamulussoftware:mainfrom
mcfnord:chatdlg-listview-accessibility
Open

chatdlg: replace QTextBrowser with QListView for screen reader accessibility#3748
mcfnord wants to merge 2 commits into
jamulussoftware:mainfrom
mcfnord:chatdlg-listview-accessibility

Conversation

@mcfnord

@mcfnord mcfnord commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Replaces `QTextBrowser` with `QListView` + `QStyledItemDelegate` in the chat dialog so that each message is a discrete item in the OS accessibility tree.

With `QTextBrowser`, VoiceOver (and other screen readers that consume `QAccessible`) sees the entire chat history as a single text block. With `QListView`, each appended message becomes a `QAccessible::ListItem`, letting the user arrow-key through individual messages.

`ChatDelegate` renders each item as HTML via `QTextDocument`, preserving the existing rich-text formatting. Link clicks are detected in `eventFilter` by installing a filter on the viewport (mouse events in `QListView` go to the viewport child widget, not the view itself) and using `QTextDocument::documentLayout()->anchorAt()` to hit-test the click position. Hovering over a link shows a pointing-hand cursor. Clicking routes through the existing `OnAnchorClicked` confirmation dialog. Right-click or Ctrl+C copies the selected message's plain text to the clipboard.

Link clicks have been confirmed working on Windows, perhaps on Linux. Does VoiceOver read individual messages as expected on macOS?

Fixes an issue?

Addresses #3613.

Does this change need documentation? What needs to be documented and how?

No documentation changes needed.

Status of this Pull Request

Builds and runs. Not tested on macOS. does VoiceOver navigate individual messages?

I don't see pointer cursor on hover; probably worth investigating.

Checklist

  • I've verified that this Pull Request follows the general code principles
  • I tested my code and it does what I want... but does it do things I don't want?
  • My code follows the style guide
  • I waited some time after this Pull Request was opened and all GitHub checks completed without errors.

@pljones

pljones commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

Thanks - we've been looking to get more of the assistive side of Jamulus fixed.

Could you also provide screenshots (ideally with some rich HTML text - and welcome messages) and a comparative walk through of use with the existing interface - not just for screen-reader use but generally.

-- Peter

@mcfnord

mcfnord commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

I found a problem with this approach (links not clickable) but Claude says it's fixable. I agree that we'd need to assure any visual changes are unimportant. My hope is that the only useability difference is arguably an improvement: you can copy the whole line rather than pieces of it, but no copy of multiple lines anymore. This is a more common pattern in tools like Slack.

Comment thread src/chatdlg.cpp
// set a placeholder text to make sure where to type the message in (#384)
edtLocalInputText->setPlaceholderText ( tr ( "Type a message here" ) );

// Set up the list model and delegate for accessible per-message rows ------

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
// Set up the list model and delegate for accessible per-message rows ------
// Set up the list model and delegate for accessible per-message rows

Check for AI artifacts like this.

@ann0see ann0see left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tested locally on linux and there is a slight difference. I'd be interested what happens if you send broken html form the server side (e.g. a broken welcome message).

jrd and others added 2 commits June 20, 2026 19:51
Each chat message is now a discrete QListView row rendered by a
QStyledItemDelegate, exposing it to the OS accessibility tree as a
QAccessible::ListItem. VoiceOver can arrow-key through individual
messages instead of treating the whole history as one text block.

Right-click or Ctrl+C copies the selected message's plain text to the
clipboard. Link clicks are detected via the event filter and routed to
the existing confirmation dialog.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mouse events in QListView go to the viewport child widget, not the
view itself. The event filter was installed only on the view, so
MouseButtonPress was never caught. Install on viewport() too and
check obj == viewport() for mouse events.

Also adds MouseMove handling to show PointingHandCursor over links.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mcfnord mcfnord force-pushed the chatdlg-listview-accessibility branch from 2766b96 to dde15e4 Compare June 20, 2026 19:52
@mcfnord

mcfnord commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Tested locally on linux and there is a slight difference. I'd be interested what happens if you send broken html form the server side (e.g. a broken welcome message).

I want a Mac user to test with VoiceOver!

@dingodoppelt

Copy link
Copy Markdown
Member

Do @chigkim or @OnjLouis have anything to add to this maybe?

@ann0see

ann0see commented Jun 21, 2026

Copy link
Copy Markdown
Member

I tried it on macOS but could not succeed to tab inside the chat message. It also did not speak once i clicked onto the message. so it didn't fix it unfortunately.

I think that we probably need to resructure the UI anyway. It should probably be restructured such that it works like modern messengers.

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.

4 participants