Conversation
Closes #17749 Summary of the issue: #17744 introduced pyright using it's default server nodeenv. The pyright python package recommends installing pyright[nodejs] for a faster and more reliable server. Hwever we couldn't use it while NVDA was 32bit. This is because the node wheel binaries required a 64bit environment. Now that NVDA has migrated to 64bit, we should update the pyright package version to using nodejs.
…mote (#18528)" (#19106) This reverts commit 2fa3658. ### Reverts PR Reverts #18528 ### Issues fixed Fixes #19076 ### Issues reopened Reopens #15905 ### Reason for revert - Add-on API solution doesn't work - extracting SSL from context is dangerous - Regression with NVDA remote ### Can this PR be reimplemented? If so, what is required for the next attempt - Instead use trust store directly rather than injecting into all SSL contexts
Closes #18831 ### Summary of the issue: Remote Access was using the deprecated `braille.filter_displaySize` extension point. It was also using `displaySize` instead of `displayDimensions.numCols`, meaning that in the case that a user with a multi-line display was controlling a computer with a single-line display that was wider than the leader's display, braille from the follower would wrap at the width of the leader display. While this would not result in information loss, it was unexpected behaviour. ### Description of user facing changes: In remote access sessions where one or more users have multi-line braille displays connected, only the width of these displays will be considered when finding the shared display width. For instance, if leader connects with a DotPad (8x20 cells) and follower connects with a Hims Brailleedge 40 (1x40 cells), the display width for the session will be constrained to 20 cells. ### Description of developer facing changes: None ### Description of development approach: Replace usage of `braill.filter_displaySize` with `braille.filter_displayDimensions` in `_remoteClient.session`. Also renamed `_remoteClient.localMachine.LocalMachine.handleFilterDisplaySize` to `_handleFilterDisplayDimensions`. Replace usages of `braille.handler.displaySize` with `braille.handler.displayDimension.numCols` where appropriate in `_remoteClient`. ### Testing strategy: Created a session in which the leader was using a DotPad and the follower was using a Brailleedge40. ### Known issues with pull request: Users may desire the existing behaviour of all rows of multi-line displays being considered. We cannot support multi-line displays over Remote Access without changing the protocol. NV Access does not have a clear policy on when we can change the Remote Access Protocol and in what ways.
… workarounds (#19117) Closes #18757 ### Summary of the issue: NVDA includes Windows 8.x Start screen workarounds which are no longer needed. ### Description of user facing changes: None ### Description of developer facing changes: Revmoes Windows 8.x Start screen support symbols from the File Explorer app modules: `SuggestionListItem`, `SearchBoxClient`, `GridTileElement`, `GridListTileElement`, `GridGroup`, `ImmersiveLauncher`. ### Description of development approach: Removed the no longer used Windows 8.x Start screen attributes, test it after compiling NVDA on Windows 10/11. ### Testing strategy: Manual: make sure Windows 10/11 File Explorer support code such as notificaiton area and UI property objects do not cause errors for NVDA. ### Known issues with pull request: None
### Summary of the issue: We're two Python patches behind. ### Description of user facing changes: NOne ### Description of developer facing changes: None ### Description of development approach: * Grep for "3\.13\.7", change to 3.13.9. * Removed some 32-bit left-overs. ### Testing strategy: CI ### Known issues with pull request: None
Closes #7455 ### Summary of the issue: In browse mode documents, the number of ítems for lists is not reported in braille, just via speech output. ### Description of user facing changes: The number of ítems Will be appended to lst for lists in browse mode documents. ### Description of developer facing changes: None ### Description of development approach: Use the _childcontrolcount attribute of text info fields to get the number of ítems of lists, and set the appropriate roleText when the number of ítems of a list is available. ### Testing strategy: Tested locally, checking that the number of ítems is reported for lists in browse mode. ### Known issues with pull request: In rare cases, the number of items can be reported via speech output, not in braille, or in braille, not speech. Here is an example of a webpage where the number of items is reported just via speech. I've observed this just when the list contains 1 element. In braille, in Spanish, in this webpage, pressing l to reach a list with 1 item, I read the word "fin" (end). This is not read via speech. Seems a non standard control (like an empty list inside a menu): https://duckduckgo.com/ I've seen, once, that the number of items was reported just in braille, not speech. If I find the webpage I'll include it here.
### Summary of the issue: NVDA builds are intended to upload debug symbols to Mozilla. This makes it easier to diagnose issues related to NVDA's in-process code in Firefox (both crash analysis and profiling), which helps both projects. Unfortunately, this broke years ago for various reasons. ### Description of user facing changes: None. ### Description of developer facing changes: Mozilla crash reports and profiles will show useful symbols for NVDA code. I haven't included a change log entry for NVDA because this doesn't impact NVDA developers normally, only if they're working with Firefox. ### Description of development approach: 1. The version of dump_syms.exe in miscDeps from Google Breakpad is very outdated and probably no longer works. Mozilla completely rewrote this a few years ago. Download that from GitHub releases and use that instead. 2. mozillaSyms.py uses relative paths, but the script was moved in bd6b99e, which broke these paths. Update the script accordingly. 3. The structure of NVDA's lib directory has changed significantly in the last few years. Furthermore, NVDA now supports more architectures (arm64, arm64ec). Update mozillaSyms.py accordingly. 4. Remove some unnecessary actions from the uploadSymbols CI job. ### Testing strategy: Confirmed that [symbols were uploaded successfully in a try run](https://github.com/nvaccess/nvda/actions/runs/18735136393/job/53440453068). ### Known issues with pull request: None.
## Summary of the issue: Lilli.dll is a 32-bit DLL, so the MDV Lilli display can't be used with 64-bit builds of NVDA. ### Description of user facing changes: TheLilli display can be used again. ### Description of developer facing changes: None ### Description of development approach: Update miscDeps ### Testing strategy: This DLL was reported to work by MDV. ### Known issues with pull request: None
Resolves #18171 ### Summary of the issue: Some configuration can still be written to disk when running from the launcher. ### Description of user facing changes: These configurations can no-longer be saved to disk from the launcher. ### Description of developer facing changes: None ### Description of development approach: * [x] Speech dictionaries: return early from `speechDictHandler.SpeechDict.save` if `shouldWriteToDisk` returns `False`. * [x] Punctuation/symbol pronunciation: Return early from `characterProcessing.SymbolPronunciations.save` if `shouldWriteToDisk` returns `False`. * [x] Input gestures: return early from `inputCore.GlobalGestureMap.save` if `shouldWriteToDisk` returns `False`. * [x] Configuration profiles: Use `not NVDAState.shouldWriteToDisk()` rather than `globalVars.appArgs.secure` when deciding whether to force the config profiles dialog's new, triggers, rename and delete buttons to be disabled. * [x] Create: Use `not NVDAState.shouldWriteToDisk()` rather than `globalVars.appArgs.secure` when deciding whether to return early from `config.ConfigManager.createProfile`. * [x] Modify: Use `not NVDAState.shouldWriteToDisk()` rather than `globalVars.appArgs.secure` when deciding whether to return early from `config.ConfigManager.saveProfileTriggers`. * [x] Rename: Use `not NVDAState.shouldWriteToDisk()` rather than `globalVars.appArgs.secure` when deciding whether to return early from `config.ConfigManager.renameProfile`. * [x] Delete: Use `not NVDAState.shouldWriteToDisk()` rather than `globalVars.appArgs.secure` when deciding whether to return early from `config.ConfigManager.deleteProfile`. ### Testing strategy: #### Speech dictionaries: * Build a launcher. * Run the launcher, and ensure that existing speech dictentries work as expected. * Add a newentry and press Ok. * Ensure the new entry works as expected. * Restart NVDA, and ensure that the new entries were not persisted. #### Symbol pronunciations * Run from source. Modify a symbol. Ensure that the new pronunciation works as expected. * Restart the source copy. Ensure the modification has persisted. * Create a launcher. Run it. Modify a symbol. Ensure that the new pronunciation works as expected. * Start the instaled copy of NVDA. Ensure that the modified symbol has not been persisted. #### Input gestures: * Build a launcher. * Create a new gesture in the installed copy (in my case, `NVDA+conrol+shift+t` to report the time. Check that it works. Restart NVDA and use the gesture t ensure it has been persisted to disk. * Start the launcher. Use the new gesture to ensure it works in the launcher. * Add a new gesture (in my case, `NVDA+control+shift+r` to report the time. Perfor the gesture to ensure that it works as expected. * Check the log outpu to ensure that a message was logged about gestures not being saved. * Restart the installed copy. Ensure that the gesture created in the launcher copy does not work, but the gesture created in the installed copy does. #### Config profiles * Build a launcher. * From the installed copy, create a new configuration profile. * Run the launcher. Open the config profiles dialog. Attempt to create, update or delete a profile. * From the NVDA Python Console, attempt to call all of `config.conf.createProfile`, `config.conf.renameProfile`, `config.conf.deleteProfile`, and `config.conf.saveProfileTriggers`. Observe the log to ensre the functions return early. ### Known issues with pull request: None.
Fixes #19028 ### Summary of the issue: Papenmeier braille displays don't work with 64-bit NVDA. ### Description of user facing changes: Papenmeier displays should work again. ### Description of developer facing changes: * `ftdi2.py` has been moved from `miscDeps` into `nvda`, and significantly refactored. ### Description of development approach: * [x] Copy `ftdi2.py` from `miscdeps/python` to `source/ftdi2/__init__.py` * [x] Reimplement `ftExceptionDecorator` as a ctypes `errcheck` function * [x] For each of the `_PY_*` functions, look up the corresponding function in the [D2XX Programmer’s Guide](https://ftdichip.com/document/programming-guides/) (revision 1.6) and implement the corresponding ctypes prototype in `ftd2xx.py` * [x] Convert enumerations to actual `Enum`s, and move to `ftd2xx.py` * [x] Verify struct definitions * [x] Rename the various pythonic functions and methods according to NV Access' house style * [x] Update the copyright headers and docstrings * [x] Compare the old `ftdi2.py` wth the new `ftdi2` package and document API differences * [x] Remove `ftdi2.py` from miscdeps (PR nvaccess/nvda-misc-deps#46) * [x] Update miscdeps ### Testing strategy: Asked affected users to test try builds. ### Known issues with pull request: None ### Code Review Checklist: - [x] 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 - [x] UX of all users considered: - Speech - Braille - Low Vision - Different web browsers - Localization in other languages / culture than English - [x] API is compatible with existing add-ons. - [x] Security precautions taken. --------- Co-authored-by: Michael Curran <mick@nvaccess.org>
…ble. (#19146) Fixes #13897. ### Summary of the issue: Currently, in web browsers, NVDA treats controls with a 0 width or height and no children as invisible. While this makes sense in theory, there are quite a few instances in the wild where authors use off-screen content to expose something to screen readers without exposing it visually. Because it's not visible, they sometimes don't necessarily consider that the width or height is relevant and end up with 0 width/height, making it completely inaccessible in NVDA browse mode. This is most common for custom radio buttons and check boxes, but I've also seen it for custom text editors and some other controls. I would argue this is misguided authoring on multiple levels, but ultimately, this is causing real problems for NVDA users across the web and our first responsibility is to users. This was implemented a long time ago when the web was a lot simpler and there has been a shift over the years towards trusting explicit semantics rather than fragile visual heuristics. Finally, as far as I've been able to determine, no other screen reader does this, which is problematic for interoperability. This means there is content which works in every other screen reader except NVDA. ### Description of user facing changes: In browse mode in web browsers, NVDA no longer sometimes treats controls with 0 visual width or height as invisible. This technique is sometimes used to make content accessible to screen readers without it being visible visually. Such controls will now be accessible in browse mode where they weren't before. ### Description of developer facing changes: None. ### Description of development approach: In the gecko_ia2 vbuf backend, removed the code which results in isVisible being set to false if width or height is 0. ### Testing strategy: In both Firefox and Edge: 1. Tested with the [CodePen example](https://codepen.io/blindguynw/pen/MWLXKvB) from #13897 (comment). Before the change: radio buttons do not appear in browse mode. After the change: they do. 2. Tested with this simple test case: `data:text/html,before<div role="radio" aria-label="control"></div>after` Before the change: the radio button does not appear in browse mode. After the change: it does. 3. Loaded [the Monaco Editor website](https://microsoft.github.io/monaco-editor/). Before the change: quick nav to edit field often didn't find anything, though sometimes it would appear on the first load and then disappear when refreshed. After the change: quick nav to edit field always finds the editor. ### Known issues with pull request: @seanbudd noted in #13897 (comment) that NV Access supports making this a setting. While I understand the desire for caution here, there is currently no way to have settings like this that affect vbuf backends without a significant amount of work. It can't be done like layout tables because it needs to affect the content that is rendered into the buffer, not just what semantic information gets reported. It might be slightly more feasible to do this for pages loaded after the setting is changed, but that is probably confusing for users and is still a reasonable chunk of work. Meanwhile, this issue would remain unfixed and continue to cause problems for users, potentially on a daily basis. I accept that if this causes unanticipated problems, it might need to be reverted. It's a simple enough change that this can be done without much churn. --------- Co-authored-by: Leonard de Ruijter <3049216+LeonarddeR@users.noreply.github.com>
…is not displayed in braille (#19109) Fixes #18993 ### Summary of the issue: When navigating the list of messages in Outlook Classic, the navigator object is moved from the focus, showing unexpected information in braille. ### Description of user facing changes: The list of messages can be navigated in Outlook Classic, without receiving unexpected information in braille. ### Description of developer facing changes: None. ### Description of development approach: In the `ContactEditField` class of the Outlook app module, call to `api.setNavigatorObject` for the `event_valueChange`, has been modified setting `isFocus` to `True` ### Testing strategy: - Navigate the list of messages and chek that unexpected information is not presented in braille. - Compose messages using fields like To or CC, and check that side effects are not produced. ### Known issues with pull request: The navigator object is still moved, so that the reported navigator object doesn't match the reported focus.
Fixes issue found while working on #19059 Summary of the issue: In #19059, commit 9595711, an error is raised during check Pot: scons: *** [tests\checkPot] IndexError : list index out of range Traceback (most recent call last): File "D:\a\nvda\nvda\.venv\Lib\site-packages\SCons\Action.py", line 1434, in execute result = self.execfunction(target=target, source=rsources, env=env) File "D:\a\nvda\nvda\tests\sconscript", line 21, in checkPotAction return checkPot.checkPot(source[0].abspath) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^ File "D:\a\nvda\nvda\tests\checkPot.py", line 142, in checkPot msgid += getStringFromLine(line) ~~~~~~~~~~~~~~~~~^^^^^^ File "D:\a\nvda\nvda\tests\checkPot.py", line 201, in getStringFromLine quoted = line.split(" ", 1)[1] ~~~~~~~~~~~~~~~~~~^^^ IndexError: list index out of range Error: Process completed with exit code 1. The test should pass or fail but no error should be raised. The error occurs if a msgid command containing a multi-line string is followed by a msgid_plural command. This had probably never happened before the string introduced in #19059. Description of user facing changes: The Python script to check Pot does not raise an error before completing. Description of developer facing changes: N/A Description of development approach: Take into account the presence of msgid_plural token. Taken into account that a multi-line string in the msgid command can end: either with a msgstr command or a msgid_plural command
Fix-up of #18974 Summary of the issue: One newly translatable string needs to support plural forms: "{malicious} out of {total} malware scanners detected this add-on as potentially malicious." In English, there is no difference, since "detected" uses the same form at singular or plural; but in other languages, not. There are also languages where scanners pluralization needs to change. Description of user facing changes: The information will have correct pluralization form. After discussion, I have tried to find a wording where only one of the two numbers needs an agreement to avoid splitting and re-building the sentence. Description of developer facing changes: N/A Description of development approach: Use npgettext instead of pgettext.
There was a problem hiding this comment.
Pull Request Overview
This PR merges changes from the master branch into the beta branch, primarily focusing on license updates, dependency changes, and code refactoring. The major change is updating NVDA's license from GPL-2 only to GPL-2 or later.
- Updated NVDA's license from GPL-2 to GPL-2 or later, including full GPL-3 text in copying.txt
- Removed truststore dependency and related certificate handling code, replacing with native urllib.request
- Refactored ftdi2 module into a proper package with improved type safety and naming conventions
Reviewed Changes
Copilot reviewed 34 out of 35 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| copying.txt | Added GPL-3 license text and updated references to support GPL-2 or later |
| pyproject.toml | Updated license classifier and removed truststore dependency |
| source/versionInfo.py | Updated license description to GPL-2 or later |
| source/updateCheck.py | Replaced requests library with urllib.request for update checks and moved certificate handling |
| source/utils/networking.py | File deleted - functionality moved to updateCheck.py |
| source/ftdi2/ftd2xx.py | New file with FFI bindings for FTD2XX DLL |
| source/ftdi2/init.py | New file with pythonic interface for ftdi2 module |
| source/brailleDisplayDrivers/papenmeier.py | Updated to use refactored ftdi2 API |
| source/config/init.py | Replaced globalVars.appArgs.secure checks with NVDAState.shouldWriteToDisk() |
| user_docs/en/changes.md | Added changelog entries and removed deprecated items |
Comments suppressed due to low confidence (3)
source/ftdi2/ftd2xx.py:1
- Corrected spelling of 'existin' to 'existing'.
# A part of NonVisual Desktop Access (NVDA)
source/ftdi2/ftd2xx.py:1
- Missing space after 'The' before backtick - should be 'The
none'.
# A part of NonVisual Desktop Access (NVDA)
source/ftdi2/ftd2xx.py:1
- Missing closing backtick after 'set_baud_rate' - should be 'set_baud_rate
tosetBaudRate`'.
# A part of NonVisual Desktop Access (NVDA)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| level = field.get("level") | ||
| if level: | ||
| props["positionInfo"] = {"level": level} | ||
| if role == controlTypes.Role.LIST and (int(childControlCount := field.get("_childcontrolcount", 0))) > 0: |
There was a problem hiding this comment.
[nitpick] The walrus operator with int() conversion and comparison makes this line overly complex. Consider splitting into multiple lines for readability.
| if role == controlTypes.Role.LIST and (int(childControlCount := field.get("_childcontrolcount", 0))) > 0: | |
| childControlCount = int(field.get("_childcontrolcount", 0)) | |
| if role == controlTypes.Role.LIST and childControlCount > 0: |
| #### Python | ||
|
|
||
| [Python](https://www.python.org/), version 3.13.7, 32 bit. | ||
| [Python](https://www.python.org/), version 3.13.9, 64-bit. |
There was a problem hiding this comment.
[nitpick] Inconsistent bit-width specification - changed from '32 bit' to '64-bit' (note the hyphen). Should maintain consistent formatting with the original style.
| [Python](https://www.python.org/), version 3.13.9, 64-bit. | |
| [Python](https://www.python.org/), version 3.13.9, 64 bit. |
| if vision.handler: | ||
| vision.handler.handleGainFocus(self) | ||
| api.setNavigatorObject(self) | ||
| api.setNavigatorObject(self) |
There was a problem hiding this comment.
The indentation change moves this call inside the if vision.handler: block, changing the behavior. If vision.handler is None, setNavigatorObject will no longer be called.
| api.setNavigatorObject(self) | |
| api.setNavigatorObject(self) |
No description provided.