Skip to content

Make braille and vision follow caret in browse mode#20465

Merged
seanbudd merged 2 commits into
nvaccess:masterfrom
LeonarddeR:sayAllBrailleFollow
Jul 8, 2026
Merged

Make braille and vision follow caret in browse mode#20465
seanbudd merged 2 commits into
nvaccess:masterfrom
LeonarddeR:sayAllBrailleFollow

Conversation

@LeonarddeR

@LeonarddeR LeonarddeR commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Link to issue number:

Closes #3287

Summary of the issue:

During say all with the caret cursor in browse mode, braille and vision framework did not follow the spoken text. The display stayed on the line where say all started, and only moved if braille happened to be tethered to review.

This happens because _CaretTextReader.updateCaret moved the caret via updater.updateCaret(). In browse mode the caret is virtual, so this does not fire an OS caret event. Braille and the vision handlers are normally notified off that event, so they were never told the caret had moved.

Description of user facing changes:

During say all in browse mode, braille and the magnifier now follow the spoken text line by line, regardless of the braille tether setting.

Description of developer facing changes:

None. No public API changes.

Description of development approach:

_CaretTextReader.updateCaret now detects cursor managers via api.isCursorManager(obj) and, for those, explicitly calls braille.handler.handleCaretMove(obj) and vision.handler.handleCaretMove(obj) after moving the caret. Objects that fire an OS caret event are left on the existing path, since that event already drives the handlers.

Testing strategy:

Say all in browse mode (Firefox, Chrome) with a braille display tethered to focus: braille now follows the spoken line.

Known issues with pull request:

None.

Code Review Checklist:

  • Documentation:
    • Change log entry
    • User Documentation
    • Developer / Technical Documentation
    • Context sensitive help for GUI changes
  • Testing:
    • Unit tests
    • System (end to end) tests
    • Manual testing
  • UX of all users considered:
    • Speech
    • Braille
    • Low Vision
    • Different web browsers
    • Localization in other languages / culture than English
  • API is compatible with existing add-ons.
  • Security precautions taken.

In say all with the caret cursor, _CaretTextReader.updateCaret called
updater.updateCaret(). In browse mode and other cursor managers this sets the
caret without firing an OS caret event, so braille and vision were never
notified and the display stayed on the starting line (unless braille happened
to be tethered to review).

Route the caret update through the object's selection property when supported,
so its _set_selection notifies review/braille/vision handleCaretMove handlers.
The updater is a collapsed position, so setting the selection is equivalent to
moving the caret; objects without a selection setter keep the previous path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LeonarddeR LeonarddeR changed the title Braille and magnifier follow say all in browse mode Make braille and vision follow caret in browse mode Jul 8, 2026
@LeonarddeR LeonarddeR marked this pull request as ready for review July 8, 2026 17:41
@LeonarddeR LeonarddeR requested a review from a team as a code owner July 8, 2026 17:41

Copilot AI 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.

Pull request overview

This PR fixes an NVDA browse mode “say all” regression where the caret was moved virtually (via cursor managers) without generating an OS caret event, so braille and the vision/magnifier stack weren’t notified and didn’t track the spoken line.

Changes:

  • Update _CaretTextReader.updateCaret to explicitly notify braille and vision caret-move handlers when the caret object is a cursor manager (virtual caret).
  • Leave the existing behavior unchanged for non-cursor-manager caret moves (which should still be driven by OS caret events).
  • Add a user-facing change log entry documenting the improved braille/magnifier tracking during browse mode say all.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
user_docs/en/changes.md Documents the user-visible improvement: braille and magnifier track browse mode say all.
source/speech/sayAll.py Notifies braille/vision handlers after virtual caret moves (cursor managers) so output follows spoken text.

Comment thread user_docs/en/changes.md Outdated

@seanbudd seanbudd 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.

Thanks @LeonarddeR

@seanbudd seanbudd merged commit d7042d1 into nvaccess:master Jul 8, 2026
40 of 44 checks passed
@github-actions github-actions Bot added this to the 2026.3 milestone Jul 8, 2026
@CyrilleB79

Copy link
Copy Markdown
Contributor

@LeonarddeR I have locally modified the appearance of the browse mode cursor to be able to see / follow it and test.
I can confirm visually that the browse mode cursor now follows during say all and that it was not the case before this PR. More specifically, it seems to move at the beginning of each browse mode line, e.g. at the beginning of each link since I have screen layout off).

Would you like to update the change log? Or do we expect your work in #20467 to add it?

@LeonarddeR

Copy link
Copy Markdown
Collaborator Author

I can change it in #20467, but of course that relies on how that will be approved.
Sentence nav won't work in browse mode until added. anyway.

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.

Braille doesn't follow continuous reading in virtual buffer.

4 participants