Use line as a unit for which say all is moved in rich edit controls - #13971
Merged
Conversation
Contributor
|
I don't recall this specific case, but usually, when we used sentence, it
was either because the underlying implementation didn't support line at the
time or because line caused a performance problem. If it works now, it
seems reasonable to change it for consistency if nothing else.
|
seanbudd
approved these changes
Aug 1, 2022
5 tasks
seanbudd
pushed a commit
that referenced
this pull request
Aug 3, 2026
…to read by paragraph or line (#20467) Related to #13420, #9179 and #13971 Fixes #13829 by making paragraph available as an additional unit, so say all can send whole paragraphs to the synthesizer. Summary of the issue: For rich text controls where UNIT_READINGCHUNK was previously mapped to line (ITextDocumentTextInfo, e.g. WordPad, NVDA's log viewer, and third-party apps such as Paperback), say all's caret/review position hardly updates when word wrap is off and a paragraph spans many visual lines — the position only advances once the whole (very long) paragraph line is read. This was introduced by #13971, which changed the reading unit from sentence to line for these controls to fix caret tracking in other apps (#13420, #9179). This PR effectively reverts the default introduced by #13971: say all now reads by sentence again by default wherever sentence boundaries are supported, restoring smoother caret tracking in rich edit controls with long paragraphs. To avoid regressing the caret-tracking fix #13971 provided for apps/languages without usable sentence boundaries, the choice is no longer hardcoded: a new speech setting lets users switch back to line-based reading, re-enabling the behavior @lukaszgo1 introduced in #13971 where they need it. A paragraph unit is also available, which sends larger chunks of text to the synthesizer so it can determine sentence boundaries (and e.g. abbreviations like "Mr.") itself (#13829). Description of user facing changes: New "Say all reads by" combo box in the Speech settings panel, with three options: Sentence where possible (default) — say all reads sentence by sentence where the control supports sentence boundaries, falling back to line where it doesn't. Paragraph — say all reads paragraph by paragraph. Line — say all always reads line by line, matching the behavior introduced by Use line as a unit for which say all is moved in rich edit controls #13971. Say all now reads by sentence by default in Rich Edit controls such as WordPad and NVDA's log viewer. Description of developer facing changes: Added SayAllReadingUnitFlag feature flag (config.featureFlagEnums) with a [speech] sayAllReadingUnit configSpec entry, behaviorOfDefault="sentence". Added TextInfo.unit_readingChunk, resolving textInfos.UNIT_READINGCHUNK to UNIT_SENTENCE/UNIT_PARAGRAPH/UNIT_LINE based on the flag's calculated value; cached per core pump (_cache_unit_readingChunk) to avoid repeated config lookups in the say all loop. Added TextInfo._resolveReadingChunkUnit, used by winword.py/edit.py expand/move to substitute the resolved unit for UNIT_READINGCHUNK before their static unit-map lookup; the now-unreachable UNIT_READINGCHUNK entries were removed from those maps. OffsetsTextInfo._getReadingChunkOffsets dispatches self.unit_readingChunk through the existing _getUnitOffsets, falling back to line offsets if the resolved unit raises NotImplementedError. UIA-based TextInfos are unaffected: UIAHandler.NVDAUnitsToUIAUnits hardcodes UNIT_READINGCHUNK to TextUnit_Line, since UIA's TextPattern has no sentence text unit. This means modern UIA Word (NVDAObjects/UIA/wordDocument.py) already reads by line for say all regardless of this flag (the paragraph option is likewise ignored there for now); only legacy Word Object Model Word (winword.py, wdSentence) is driven by the flag. Description of development approach: Introduced the reading unit as a feature flag rather than hardcoding a default, so the sentence/line choice from #13971 remains available per user preference instead of being an all-or-nothing global default. SayAllReadingUnitFlag avoids a module-level import textInfos in featureFlagEnums.py, since that module is imported during config package init, before languageHandler installs the _ gettext builtin, and textInfos transitively calls _() at import time. Testing strategy: Added unit tests for _getReadingChunkOffsets covering the sentence, paragraph, line, and unsupported-unit-falls-back-to-line cases. Manually verified say all in WordPad and NVDA's log viewer with both settings.
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:
Fixes #13420
Fixes #9179
Summary of the issue:
When in say all NVDA moves caret by the unit specified as a
RREADINGCHUNKfor a given text info implementation. In most text info implementations it defaults to line, however inITextDocumentTextInfoit was set to sentence. While it probably results in smoother reading for literary text written in language where TOM can split into sentences properly, in text's such as log or for languages without clear concept of sentence such as Chinese it results in caret not following spoken text since it is moved to the current position only when the sentence ending is reached.Description of user facing changes
Say all both for review and system cursor moves by line in Rich Edit controls such as WordPad or NVDA's log viewer.
Description of development approach
for
ITextDocumentTextInfotextInfos.UNIT_READINGCHUNKhas been set to line.Testing strategy:
Made sure that say all both with system caret and review cursor follows spoken text in QRead and log viewer.
Known issues with pull request:
textInfos.UNIT_READINGCHUNKwas set to the sentence in the first place, perhaps @michaelDCurran or @jcsteh would be able to recall the reasonChange log entries:
Bug fixes
Code Review Checklist: