Dispatch browse mode alt+arrow gestures between collapse or expand and sentence navigation - #20604
Dispatch browse mode alt+arrow gestures between collapse or expand and sentence navigation#20604LeonarddeR wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR resolves the alt+upArrow / alt+downArrow gesture conflict in browse mode by dispatching per keypress between collapse/expand behavior for relevant controls and sentence navigation for document content, backed by ICU-based sentence segmentation for OffsetsTextInfo. It also updates end-user documentation and adds targeted unit tests for the new segmentation and dispatch logic.
Changes:
- Add ICU sentence boundary support (
UBRK.SENTENCE,calculateSentenceOffsets, andOffsetsTextInfo._getSentenceOffsets) and reuse a shared encoding-conversion helper. - Update browse mode to route
alt+upArrow/alt+downArrowto sentence navigation unless the caret is on an “expandable / popup / focus-mode” control. - Add/adjust unit tests and documentation (User Guide + changelog) to reflect the new sentence navigation behavior.
Reviewed changes
Copilot reviewed 11 out of 15 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| user_docs/en/userGuide.md | Updates the sentence navigation key command description to include browse mode support. |
| user_docs/en/changes.md | Adds a changelog entry announcing sentence navigation support beyond Word/Outlook. |
| tests/unit/test_textUtils/test_wordSegIcu.py | Adds unit tests for ICU word segmentation strategy behavior. |
| tests/unit/test_textUtils/test_wordSeg.py | Adds broader unit tests for word segmentation initialization/selection and converters. |
| tests/unit/test_textUtils/test_sentenceSegIcu.py | Adds unit tests for ICU sentence segmentation and tiling invariants. |
| tests/unit/test_textUtils/test_offsetConverters.py | Adds unit tests for offset converters and related utilities. |
| tests/unit/test_textUtils/test_hyphenation.py | Adds unit tests for hyphenation behavior on known/unknown languages. |
| tests/unit/test_textUtils/test_backendComparison.py | Switches ICU skipping to use the shared skipIfNoICU helper. |
| tests/unit/test_textUtils/init.py | Introduces skipIfNoICU for reuse across test_textUtils modules. |
| tests/unit/test_browseModeSentenceDispatch.py | Adds unit tests for browse mode dispatch discriminator _isExpandableControlAtCaret. |
| source/winBindings/icu.py | Adds UBRK.SENTENCE to the ICU break iterator enum. |
| source/textUtils/icu.py | Adds ICU sentence segmentation and a shared calculateOffsetsForEncoding helper. |
| source/textUtils/_wordSeg/wordSegStrategy.py | Refactors ICU word strategy to use calculateOffsetsForEncoding. |
| source/textInfos/offsets.py | Implements sentence offsets for OffsetsTextInfo using ICU sentence boundaries. |
| source/browseMode.py | Implements per-press dispatch between collapse/expand and sentence navigation; removes gesture shadowing. |
| skipIfNoICU = unittest.skipUnless(ICU_AVAILABLE, "ICU library not available on this system") | ||
| """Decorator skipping tests that need the Windows built-in ICU library.""" |
textUtils.icu gains _containingSegment and calculateOffsetsForEncoding. IcuWordSegmentationStrategy.getSegmentForOffset now delegates its encoding conversion to calculateOffsetsForEncoding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
textUtils.icu gains calculateSentenceOffsets using the SENTENCE break iterator. OffsetsTextInfo._getSentenceOffsets segments the containing paragraph with it instead of raising NotImplementedError. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8b7d545 to
fd83472
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (3)
user_docs/en/changes.md:12
- The changelog entry implies sentence navigation now works in browse mode and other documents unconditionally, but the implementation still depends on sentence support (eg OffsetsTextInfo + availability of the Windows ICU library) and won’t apply to all document types (eg UIA-based browse mode). Tightening the wording here would avoid misleading users.
* Sentence navigation (`alt+upArrow` and `alt+downArrow`) now works in browse mode and other documents, using the Windows built-in ICU library for Unicode-aware sentence boundary detection. Previously it was only supported in Microsoft Word and Outlook. (#18901, @LeonarddeR)
source/browseMode.py:2057
- The docstring/return description for
_isExpandableControlAtCaretis inaccurate: returningTruedoesn’t always mean the control will be collapsed/expanded; for roles inALWAYS_SWITCH_TO_PASS_THROUGH_ROLESit primarily means the alt+up/down gesture should be passed through to the control (eg. slider/list navigation). Updating the docstring helps avoid confusion for future maintainers.
The object tested is the one :meth:`script_collapseOrExpandControl` acts on. For
plain document content the focusable node is the root object, so this returns
``False``.
:return: ``True`` to collapse/expand the control, ``False`` to navigate by sentence.
user_docs/en/userGuide.md:791
- This table entry now states sentence navigation is supported in “browse mode”, but per the PR description it’s still unavailable in some browse mode documents (eg UIA-based browse mode / documents without sentence-aware TextInfos). Consider wording this more narrowly so it doesn’t over-promise support in all browse mode contexts.
|Next sentence |alt+downArrow |alt+downArrow |Moves the caret to the next sentence and announces it. (supported in browse mode and in Microsoft Word and Outlook)|
|Previous sentence |alt+upArrow |alt+upArrow |Moves the caret to the previous sentence and announces it. (supported in browse mode and in Microsoft Word and Outlook)|
…fsets OffsetsTextInfo._getSentenceOffsets now applies the same encoding guard as _getWordOffsets and _getCharacterOffsets, accepting only UTF-16 and the encodings whose offsets are str indices. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…d sentence navigation alt+upArrow and alt+downArrow now run script_moveBySentence_back/forward, which collapse or expand the focusable control at the caret when it takes these keys itself and navigate by sentence otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fd83472 to
bdb46f0
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (3)
user_docs/en/userGuide.md:791
- The User Guide entry claims sentence navigation is supported in browse mode generally, but the PR description notes this is still unavailable for some browse mode documents (e.g. UIA-based) where the gesture will do nothing. Consider wording this as “supported in browse mode documents that support sentence navigation (e.g. Firefox/Chrome)” to avoid overpromising.
|Next sentence |alt+downArrow |alt+downArrow |Moves the caret to the next sentence and announces it. (supported in browse mode and in Microsoft Word and Outlook)|
|Previous sentence |alt+upArrow |alt+upArrow |Moves the caret to the previous sentence and announces it. (supported in browse mode and in Microsoft Word and Outlook)|
user_docs/en/changes.md:12
- This changelog entry says sentence navigation “now works in browse mode”, but per the PR description it remains unavailable in UIA-based browse mode documents (and other non-offsets TextInfos). Tweaking the wording to “many browse mode documents (e.g. Firefox/Chrome)” would better match actual availability.
* Sentence navigation (`alt+upArrow` and `alt+downArrow`) now works in browse mode and other documents, using the Windows built-in ICU library for Unicode-aware sentence boundary detection. Previously it was only supported in Microsoft Word and Outlook. (#18901, @LeonarddeR)
source/textInfos/offsets.py:566
- The docstring says sentence segmentation is done over the containing paragraph “so a sentence can span multiple lines”. In this base class,
_getParagraphOffsetscurrently falls back to_getLineOffsets, so sentences only span multiple lines when subclasses override paragraph semantics. Adjust the wording to reflect that this depends on the TextInfo implementation.
Sentences are segmented over the containing paragraph (:meth:`_getParagraphOffsets`)
using the Windows built-in ICU BreakIterator (UAX#29), so a sentence can span
multiple lines.
|
Closing until 20602 and #20603 have been merged. |
Link to issue number:
Closes #18901.
Depends on #20603.
Summary of the issue:
NVDA binds
alt+upArrowandalt+downArrowto sentence navigation commands. Browse mode inherits these commands from the cursor manager. Browse mode also bound the same keys to the command that collapses or expands the current control. Bindings from more derived classes win, so the collapse or expand binding shadowed the sentence commands. Sentence navigation was therefore unreachable in browse mode, even with the working backend from the previous PR in this stack.Description of user facing changes:
In browse mode,
alt+upArrowandalt+downArrownow move the caret by sentence in document content. Controls that use these keys themselves keep the old behaviour: they still collapse or expand. This covers comboboxes and other controls that are collapsed, expanded, have a popup, or offer autocompletion. Input help now describes the sentence commands. The user guide no longer limits sentence navigation to Word and Outlook. A changelog entry is added.Description of developer facing changes:
BrowseModeDocumentTreeInterceptoroverrides the sentence scripts withscript_moveBySentence_backandscript_moveBySentence_forward. A new helper,_isExpandableControlAtCaret, decides which behaviour applies. The two static gesture bindings tocollapseOrExpandControlare removed.Description of development approach:
The keys are no longer bound to one fixed command. Instead, the sentence scripts decide per key press which action applies. The decision looks at the focusable control at the caret. That is the same object the collapse or expand script acts on. If that control takes these keys itself, the script collapses or expands it. Otherwise the caret moves by sentence. In documents without sentence support, the keys do nothing instead of raising an error. The SentenceNav add-on resolves the same conflict in the same way.
Testing strategy:
New unit tests cover the decision helper. Controls such as comboboxes, sliders, autocomplete fields, and collapsed controls keep collapse or expand. Plain content, links, and buttons fall through to sentence navigation. The binding order was also checked to confirm the sentence scripts now receive the keys. Manual verification in Firefox and Chrome browse mode confirmed that plain text moves by sentence and that comboboxes still collapse or expand.
Known issues with pull request:
Sentence navigation is still unavailable in documents that do not use offsets-based TextInfos, such as UIA-based browse mode documents and edit controls.
Code Review Checklist: