Repository navigation
Report headings and lists in rich edit controls - #21002
Open
LeonarddeR wants to merge 3 commits into
Open
LeonarddeR wants to merge 3 commits into
LeonarddeR wants to merge 3 commits into
Conversation
Contributor
There was a problem hiding this comment.
🟡 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.
Collaborator
Author
|
This kan now be tested with development builds of Paperback. |
Member
|
Is this ready for review or still being worked on? |
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. |
Collaborator
|
@seanbudd you've added 2027.1 milestone. I guess it's a mistake, isn't it? |
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
Assisted-by: Claude:claude-opus-5-5
LeonarddeR
force-pushed
the
richedit-styles
branch
from
November 10, 2026 09:15
3feea8e to
68e280e
Compare
LeonarddeR
marked this pull request as ready for review
November 10, 2026 09:15
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

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:
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".
ITextDocumentTextInfomaps these styles (tomParaStyleHeading1totomParaStyleHeading9) to theheading-levelformat field.Lists:
tomListNone. As in Word, each list paragraph is a list item.getTextWithFieldswraps the format runs of each list paragraph in a list item control field.line-prefixof the first format field of the list item.tomListBulletis the default bullet. A list type above 32 is the bullet character itself.ITextRange2::GetText2withtomIncludeNumbering, called on the first character of the paragraph. It returns the number, a tab and that character.GetText2leaves out bullets unless the document also contains a numbered list, so it is only used for numbers.ITextRange2. Querying for it from NVDA's process fails withE_NOINTERFACE. NVDA therefore callsGetText2throughIDispatchwith 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: