Skip to content

Don't report out of spelling or grammar error if speech reporting is not selected#19933

Closed
nvdaes wants to merge 0 commit intonvaccess:betafrom
nvdaes:fixSpellingErrors
Closed

Don't report out of spelling or grammar error if speech reporting is not selected#19933
nvdaes wants to merge 0 commit intonvaccess:betafrom
nvdaes:fixSpellingErrors

Conversation

@nvdaes
Copy link
Copy Markdown
Collaborator

@nvdaes nvdaes commented Apr 11, 2026

Link to issue number:

None.

Summary of the issue:

In NVDA 2026.1, ability to report errors in braille or with sounds while reading has been added. When the cursor is moved out of a spelling or grammar error, if NVDA is configured to report errors in braille or via sounds, "out of spelling or grammar error is reported", even if it's not configured to report errors via speech.

Description of user facing changes:

None. Fixup for beta.

Description of developer facing changes:

None.

Description of development approach:

Check if NVDA is configured to report errors via speech, in addition to checking if extraDetails is True.

Testing strategy:

Tested manually.

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.

@nvdaes
Copy link
Copy Markdown
Collaborator Author

nvdaes commented Apr 11, 2026

cc: @CyrilleB79

@nvdaes nvdaes changed the title fixSpellingErrors Don't report out of spelling error if speech reporting is not selected Apr 11, 2026
@nvdaes nvdaes changed the title Don't report out of spelling error if speech reporting is not selected Don't report out of spelling or grammar error if speech reporting is not selected Apr 11, 2026
@nvdaes nvdaes marked this pull request as ready for review April 11, 2026 06:23
@nvdaes nvdaes requested review from a team as code owners April 11, 2026 06:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an NVDA 2026.1 regression where “out of spelling/grammar error” could be announced even when error reporting via speech is disabled, by gating those announcements on the speech-enabled flag (in addition to extraDetail).

Changes:

  • Only announce “out of spelling error” / “out of grammar error” when spelling/grammar reporting via speech is enabled.
  • Large set of additional updates across NVDA (tests, docs, config/spec changes, new modules/features such as asyncio loop, magnifier, speech dictionary refactor, etc.).
  • Build/CI/docs/tooling updates (translation check workflow, dependency bumps, markdownlint/pre-commit changes).

Reviewed changes

Copilot reviewed 127 out of 133 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
user_docs/en/changes.md Adds 2026.2 changelog section / reorganizes markdownlint disable markers.
tests/unit/test_speech.py Adjusts unit test sequence to include turning character mode off.
tests/unit/test_remote/test_localMachine.py Formatting-only change in lambda expression.
tests/unit/test_magnifier/init.py Package init for magnifier unit tests (file present in PR).
tests/unit/test_asyncioEventLoop.py Adds unit tests for asyncio event loop helper runCoroutineSync.
tests/unit/test_addonStoreNetwork.py Adds unit tests for Add-on Store downloader directory cleanup error handling.
tests/system/robot/symbolPronunciationTests.py Updates expected speech spacing in selection tests.
tests/system/robot/chromeTests.robot Adds Chrome system tests for NVDA+K link destination reporting.
tests/system/robot/chromeTests.py Implements Chrome system tests for link destination reporting scenarios.
tests/sconscript Removes SCons checkPot alias script (migrated to batch script).
tests/manual/nvdaUI/addonStore.md Markdown table formatting tweak.
tests/checkPot.py Updates translation string ignore list and exits with result code.
source/winBindings/magnification.py Adds MagSetFullscreenTransform binding and required ctypes import.
source/winAPI/_powerTracking.py Uses ngettext for battery percentage string.
source/winAPI/_displayTracking.py Adds displayChanged extension point; modernizes typing.
source/virtualBuffers/MSHTML.py Adds quick-nav searchable attrs for “slider” node type.
source/virtualBuffers/gecko_ia2.py Adds quick-nav searchable attrs for “slider” node type.
source/virtualBuffers/init.py Refactors screen layout toggle into _toggleScreenLayout.
source/utils/raii.py Introduces RAII helpers (OnDelete, makeAutoFree).
source/utils/_deprecate.py Extends RemovedSymbol to optionally call value supplier.
source/UIAHandler/remote.py Refactors Word extension pattern retrieval; adds sentence movement via remote ops.
source/UIAHandler/browseMode.py Adds UIA quick-nav iterator support for “slider”.
source/touchHandler.py Adds browse touch mode handling; introduces TouchMode enum and deprecations.
source/textUtils/init.py Adds supplementary Unicode normalization mapping for decorative Latin letters.
source/textInfos/init.py Improves link destination discovery for nested elements/graphics in links.
source/synthDrivers/oneCore.py Adds punctuation silence support and setting exposure for OneCore.
source/synthDriverHandler.py Adds PunctuationSilenceSetting factory method.
source/speechDictHandler/dictFormatUpgrade.py Logging cleanup and minor refactors while upgrading voice dictionaries.
source/speechDictHandler/definitions.py New centralized speech dictionary definition/registration system.
source/speechDictHandler/init.py Replaces old dictionaries API with new definitions system + deprecations.
source/speech/speech.py Stores last speech; improves spelling/selection speech; fixes “out of error” speech gating.
source/speech/init.py Registers pre-speech hook to track last spoken content.
source/screenCurtain/_screenCurtain.py Notifies magnifier when screen curtain toggles.
source/nvwave.py Moves _lastActiveTime initialization earlier (typing cleanup).
source/NVDAObjects/UIA/wordDocument.py Improves page number propagation and adds UIA remote sentence navigation fallback logic.
source/NVDAObjects/UIA/init.py Adds COM-error-safe cacheable property getter and uses it in state computation.
source/NVDAObjects/IAccessible/winword.py Formatting-only change in lambda used for table cell access.
source/NVDAObjects/behaviors.py Uses ngettext for progress bar percentage speech.
source/mouseHandler.py Adds/updates type annotations for screen geometry helpers.
source/mathPres/MathCAT/MathCAT.py Refactors MathCAT navigation to command-based scripts; adds gesture scripts dynamically.
source/mathPres/init.py Initializes MathCAT navigation scripts during provider setup.
source/logHandler.py Refactors error-sound config to use new PlayErrorSound enum.
source/languageHandler.py Fixes return type of getLanguageDescription to `str
source/gui/speechDict.py Updates speech dictionary GUI to new dictionary types/entry types.
source/gui/installerGui.py Adds post-install dialog with restart/start/exit options; updates portable path message.
source/gui/configManagement.py Adds factory reset undo dialog workflow.
source/gui/addonStoreGui/viewModels/store.py Formatting-only change to action validity check lambda.
source/gui/addonStoreGui/controls/storeDialog.py Sorting/selection behavior adjustments; adds search-rank sorting during filtering.
source/gui/addonStoreGui/controls/messageDialogs.py Formatting-only change to filter lambda grouping.
source/gui/addonStoreGui/controls/addonList.py Updates list selection typing; syncs sorting with new sortable fields.
source/gui/init.py Adds magnifier panel entry; changes reset-to-default menu flow to show undo dialog.
source/core.py Initializes/terminates background asyncio event loop during NVDA lifecycle.
source/config/configSpec.py Adds config keys (speech dictionaries, braille auto-scroll rate, magnifier, touch browse elements); expands playErrorSound range.
source/config/configFlags.py Introduces PlayErrorSound enum with display strings.
source/config/init.py Adds config helper methods (get/set, percent conversions, clamped increment).
source/buildVersion.py Bumps version major to 2 (2026.2 dev).
source/brailleTables/__tables.py Adds Estonian 6-dot table; renames Italian table label.
source/brailleDisplayDrivers/freedomScientific.py Simplifies Bluetooth device predicate formatting.
source/brailleDisplayDrivers/dotPad/driver.py Adds multi-button gesture support and new gesture ID format for DotPad.
source/brailleDisplayDrivers/dotPad/defs.py Adds DP_KeyGroup and DP_Command.secondByte helper.
source/brailleDisplayDrivers/brailliantB.py Refactors Bluetooth detection predicate grouping.
source/brailleDisplayDrivers/baum.py Adds Orbit Reader 40 device IDs/names.
source/braille.py Adds braille auto-scroll support and disables auto-scroll on various interactions.
source/autoSettingsUtils/autoSettings.py Typing cleanup; updates supported setting type alias.
source/appModules/whatsapp_root.py Adds app module to disable browse mode by default for WhatsApp WebView2 app.
source/appModules/explorer.py Adjusts File Explorer product info/version reporting.
source/addonStore/network.py Adds error handling around rmtree in downloader init/cancelAll.
source/addonHandler/init.py Adds add-on manifest support for speechDictionaries translations.
source/_magnifier/utils/types.py Adds magnifier-related enums/types and display strings.
source/_magnifier/utils/spotlightManager.py Implements spotlight mode manager and zoom animation logic.
source/_magnifier/utils/focusManager.py Implements magnifier focus tracking logic.
source/_magnifier/utils/filterHandler.py Defines color filter matrices and helper for MAGCOLOREFFECT.
source/_magnifier/utils/init.py Magnifier utils package init (file present in PR).
source/_magnifier/fullscreenMagnifier.py Implements fullscreen magnifier using Windows Magnification API.
source/_magnifier/config.py Adds magnifier configuration helpers and zoom level utilities.
source/_magnifier/init.py Magnifier module initialization/termination and accessors.
source/_bridge/runtimes/synthDriverHost/synthDriverHost.py Adds optional audio brokering via WavePlayer proxy injection.
source/_bridge/runtimes/synthDriverHost/config.py Minor formatting/parentheses cleanup in lambda.
source/_bridge/components/services/nvwave.py Adds RPYC WavePlayer service and feeder service.
source/_bridge/components/proxies/synthDriver.py Removes audio ducking suspender logic from proxied synth drivers.
source/_bridge/components/proxies/nvwave.py Adds WavePlayer proxy implementation and remote feeder connection.
source/_bridge/clients/synthDriverHost32/launcher.py Exposes WavePlayer service and enables audio brokering flag on proxy install.
source/_bridge/base.py Adds handle duplication and pipe creation helpers for dependent RPYC services.
source/_asyncioEventLoop/utils.py Adds coroutine scheduling helpers (runCoroutine, runCoroutineSync).
source/_asyncioEventLoop/_state.py Adds shared state for asyncio loop/thread.
source/_asyncioEventLoop/init.py Adds initialization/termination of background asyncio event loop thread.
security.md Updates security severity definitions and response timelines.
sconstruct Removes tests sconscript invocation; adds SCons UserError import.
runcheckpot.bat Adds batch script to generate pot and validate translator comments.
pyproject.toml Dependency/version bumps; adds fuzzysearch.
projectDocs/testing/automated.md Updates translation check instructions to use runcheckpot.bat.
projectDocs/issues/triage.md Adds ADR-required label guidance and links to major change process.
projectDocs/issues/githubIssueTemplateExplanationAndExamples.md Documents new ADR templates.
projectDocs/dev/userGuideStandards.md Markdown table formatting updates.
projectDocs/dev/proposingMajorChanges.md Adds documentation for ADR process for major changes.
projectDocs/dev/developerGuide/sconscript Adjusts SCons Return placement and license header.
projectDocs/dev/createDevEnvironment.md Updates liblouis version.
projectDocs/dev/contributing.md Major rewrite/expansion of contributing guidelines; updates translation check command.
projectDocs/dev/buildingNVDA.md Updates build instructions (removes checkPot command).
projectDocs/dev/addons.md Updates add-on store/template links.
projectDocs/community/expertsList.md Markdown table formatting updates.
nvdaHelper/vbufBackends/gecko_ia2/gecko_ia2.cpp Improves label visibility heuristic by checking accessible text content.
nvdaHelper/localWin10/oneCoreSpeech.h Exposes punctuation silence support/get/set exports.
nvdaHelper/localWin10/oneCoreSpeech.cpp Implements punctuation silence support functions.
nvdaHelper/archBuild_sconscript Adds CET compatibility linker flag for non-arm64 targets.
ensureuv.ps1 Bumps uv version.
ci/scripts/tests/typeCheck.ps1 Captures pyright output via Tee-Object.
ci/scripts/tests/translationCheck.ps1 Updates to runcheckpot.bat.
ci/README.md Expands CI docs and fork setup guidance; wording updates.
.pre-commit-config.yaml Adds actionlint; bumps tool versions; changes checkPot hook to runcheckpot.bat.
.markdownlint.jsonc Adds compact table column style rule.
.github/workflows/testAndPublish.yml Updates artifact action versions; adds chrome_link system test tag.
.github/ISSUE_TEMPLATE/16-adr_major_project.md Adds advanced ADR issue template (markdown).
.github/ISSUE_TEMPLATE/06-adr_major_project.yaml Adds ADR issue template (YAML form).
.gitattributes Consolidates text/eol attributes into one line.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 79 to 83
def getType(self) -> EntryType:
typeRadioValue = self.typeRadioBox.GetSelection()
if typeRadioValue == wx.NOT_FOUND:
return speechDictHandler.ENTRY_TYPE_ANYWHERE
return (EntryType.ANYWHERE,)
return DictionaryEntryDialog.TYPE_LABELS_ORDERING[typeRadioValue]
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getType is annotated to return EntryType, but when no radio selection is found it returns a 1-tuple (EntryType.ANYWHERE,). This will break downstream comparisons (e.g. entryType != EntryType.REGEXP) and may cause type/runtime errors. Return EntryType.ANYWHERE (not a tuple) in this branch.

Copilot uses AI. Check for mistakes.
Comment on lines +1050 to +1062
def getConfigValue(self, *keyPath: *tuple[str, str, *tuple[str, ...]]) -> any:
"""
Retrieves the value of a configuration key.
:param keyPath: The path to the configuration key to retrieve.
:return: The value of the specified configuration key.
"""
return functools.reduce(lambda d, x: d.get(x), keyPath, self)

def setConfigValue(
self,
value: bool | int | float | str,
*keyPath: *tuple[str, str, *tuple[str, ...]],
) -> None:
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new getConfigValue / setConfigValue signatures use invalid type-annotation syntax (*keyPath: *tuple[...]) and -> any (lowercase) which will cause a syntax/type error when importing this module. Use a normal vararg annotation (e.g. *keyPath: str) or a tuple[str, ...] parameter, and return typing.Any (or omit the return annotation) instead.

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +113
r_fd, w_fd = os.pipe()
if push:
w_file = os.fdopen(w_fd, "wb", 0)
r_handle = makeAutoFree(HANDLE, CloseHandle)(msvcrt.get_osfhandle(r_fd))
if duplicateIntoProcess:
r_handle = self._duplicateHandleForProcess(r_handle, win32con.GENERIC_READ)
else:
os.set_inheritable(r_fd, True)
return w_file, r_handle
else:
r_file = os.fdopen(r_fd, "rb", 0)
w_handle = makeAutoFree(HANDLE, CloseHandle)(msvcrt.get_osfhandle(w_fd))
if duplicateIntoProcess:
w_handle = self._duplicateHandleForProcess(w_handle, win32con.GENERIC_WRITE)
else:
os.set_inheritable(w_fd, True)
return r_file, w_handle
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_createPipe converts the pipe file descriptors to OS handles via msvcrt.get_osfhandle, but it never closes the original r_fd / w_fd after wrapping/duplicating. This can leak descriptors/handles for every dependent connection. After creating the FileIO for the parent side, explicitly close the unused fd in the parent (or use msvcrt.open_osfhandle/os.fdopen consistently so ownership is clear) to avoid leaks/double-closes.

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +28
def initialize():
"""Initialize and start the asyncio event loop."""
log.info("Initializing asyncio event loop")
_state.eventLoop = asyncio.new_event_loop()
asyncio.set_event_loop(_state.eventLoop)
_state.asyncioThread = Thread(target=_state.eventLoop.run_forever, daemon=True)
_state.asyncioThread.start()
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize calls asyncio.set_event_loop(_state.eventLoop) on the main thread, but the loop is then run in a different background thread. This can interfere with any main-thread code that uses asyncio.get_event_loop() (it will now return a loop running in another thread). Prefer setting the event loop inside the background thread (i.e. thread target sets set_event_loop then run_forever), and avoid mutating the main thread’s current loop.

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +16
## 2026.2

### Important notes

### New Features

* Added the ability to automatically scroll the braille display. (#18573, @nvdaes)
* After installing or updating NVDA, a dialog now offers options to restart Windows, start the installed copy, or exit the installer. (#19268, #19718, @kefaslungu)
* NVDA now includes a built-in Magnifier feature that allows you to zoom and magnify parts of the screen. (#19228, @Boumtchack)
* The magnifier supports various zoom levels, color filters (normal, grayscale, inverted), and different focus tracking modes.
* Color filters can help users with visual impairments or light sensitivity by inverting or desaturating screen colors.
* A spotlight mode is available for presentations or focused reading tasks.
* All magnifier settings can be configured in a new "Magnifier" panel in NVDA Settings.
* The magnifier cannot be used simultaneously with Screen Curtain for security reasons.
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description/title indicate a small beta fix for spelling/grammar error reporting, but this PR also adds a full new 2026.2 changelog section (and many other unrelated changes across the codebase). Please split unrelated changes into separate PRs or update the PR description/scope so reviewers can accurately assess risk and intent.

Copilot uses AI. Check for mistakes.
@nvdaes nvdaes marked this pull request as draft April 11, 2026 17:41
@nvdaes nvdaes force-pushed the fixSpellingErrors branch from 1dd1f4a to a3f90c3 Compare April 11, 2026 17:45
@nvdaes nvdaes marked this pull request as ready for review April 11, 2026 18:50
@nvdaes
Copy link
Copy Markdown
Collaborator Author

nvdaes commented Apr 11, 2026

@copilot, can you provide feedback now?

@nvdaes nvdaes closed this Apr 11, 2026
@nvdaes nvdaes force-pushed the fixSpellingErrors branch from e2d3a92 to 000ebb3 Compare April 11, 2026 19:48
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.

2 participants