Skip to content

Report headings and lists in rich edit controls - #21002

Open
LeonarddeR wants to merge 3 commits into
nvaccess:masterfrom
LeonarddeR:richedit-styles
Open

LeonarddeR wants to merge 3 commits into
nvaccess:masterfrom
LeonarddeR:richedit-styles

Conversation

@LeonarddeR

@LeonarddeR LeonarddeR commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Link to issue number:

Closes #20982.
Builds on #20987.

Summary of the issue:

NVDA reads rich edit controls through the Text Object Model exposed using ITextDocumentTextInfo. It reports character formatting and alignment there, but not headings or lists. Users can't tell headings and list items apart from body text.

Description of user facing changes:

In rich edit controls that NVDA reads through the Text Object Model:

  • NVDA reports headings and their level when reporting of headings is on.
  • NVDA reports each list paragraph as a list item with its level when reporting of lists is on.
  • NVDA reports the bullet or number that the control draws before a list item.

Description of developer facing changes:

None.

Description of development approach:

Headings: A rich edit control stores headings as the built-in paragraph styles "heading 1" to "heading 9". ITextDocumentTextInfo maps these styles (tomParaStyleHeading1 to tomParaStyleHeading9) to the heading-level format field.

Lists:

  • A paragraph belongs to a list when its list type is not tomListNone. As in Word, each list paragraph is a list item.
  • getTextWithFields wraps the format runs of each list paragraph in a list item control field.
  • Format runs stop at paragraph ends. So every run that starts before the end of a list paragraph belongs to the same list item.
  • The marker goes into the line-prefix of the first format field of the list item.
  • Bullets come from the list type. tomListBullet is the default bullet. A list type above 32 is the bullet character itself.
  • Numbers come from ITextRange2::GetText2 with tomIncludeNumbering, called on the first character of the paragraph. It returns the number, a tab and that character. GetText2 leaves out bullets unless the document also contains a numbered list, so it is only used for numbers.
  • Windows registers no proxy for ITextRange2. Querying for it from NVDA's process fails with E_NOINTERFACE. NVDA therefore calls GetText2 through IDispatch with comtypes' dynamic dispatch, as it does for Word's object model. This uses the Text Object Model 2 symbols from Include Text Object Model 2 in comInterfaces.tom #20987.

Testing strategy:

Manually tested in Paperback with trypsynth/paperback#1117, which stores headings and lists in its reading view. NVDA reported headings and list items after a plain text load, after a rich text load and after the reading view extended its window.

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.

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.

🟡 Changes recommended

List-item fields suppress normal speech and braille reporting, and list levels are off by one.

2 open findings
What changed in this PR

Adds heading and list information to NVDA’s Text Object Model support for rich edit controls.

Changes:

  • Maps built-in heading styles to heading levels.
  • Wraps list paragraphs in list-item fields with nesting levels.
  • Exposes bullets and numbers through line-prefix formatting.
File Description
source/​NVDAObjects/​window/​edit.py Adds heading detection, list-item fields, and marker extraction.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread source/NVDAObjects/window/edit.py Resolved
Comment thread source/NVDAObjects/window/edit.py Resolved
@seanbudd seanbudd added the conceptApproved Similar 'triaged' for issues, PR accepted in theory, implementation needs review. label Oct 19, 2026
@LeonarddeR

Copy link
Copy Markdown
Collaborator Author

This kan now be tested with development builds of Paperback.

@seanbudd

seanbudd commented Nov 9, 2026

Copy link
Copy Markdown
Member

Is this ready for review or still being worked on?

@LeonarddeR

Copy link
Copy Markdown
Collaborator Author

@seanbudd yes, the only reason this is a draft is to wait for the 2027.2 dev cycle so I can add the changelog entry.

@seanbudd seanbudd added this to the 2027.1 milestone Nov 9, 2026
@CyrilleB79

Copy link
Copy Markdown
Collaborator

@seanbudd you've added 2027.1 milestone. I guess it's a mistake, isn't it?

@seanbudd seanbudd modified the milestones: 2027.1, 2027.2 Nov 9, 2026
@seanbudd seanbudd removed the blocked label Nov 10, 2026
Map the built-in TOM heading paragraph styles (tomParaStyleHeading1 to
tomParaStyleHeading9) to the heading-level format field in
ITextDocumentTextInfo.

Assisted-by: Claude:claude-opus-5-5
Give each list paragraph a list item control field with its level in
ITextDocumentTextInfo when list reporting is on. Expose the bullet or
number that the control draws as line-prefix. Take bullets from the
list type and read numbers through ITextRange2::GetText2 over IDispatch.

Assisted-by: Claude:claude-opus-5-5
@LeonarddeR
LeonarddeR marked this pull request as ready for review November 10, 2026 09:15
@LeonarddeR
LeonarddeR requested a review from a team as a code owner November 10, 2026 09:15
@LeonarddeR
LeonarddeR requested a review from seanbudd November 10, 2026 09:15

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conceptApproved Similar 'triaged' for issues, PR accepted in theory, implementation needs review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Report headings and lists in rich edit controls

4 participants