NVDA 2026.1 compatibility + build system modernization (v1.9.0) - #47
Merged
Conversation
Packaged add-on artifact |
Packaged add-on artifact |
Packaged add-on artifact |
Packaged add-on artifact |
NVDA 2026.1 raised its add-on API BACK_COMPAT_TO to (2026, 1, 0) (Python 3.11->3.13, 32->64-bit), disabling this add-on on manifest metadata alone. An audit against the 2026.1 source found no breaking API change beyond the gui.messageBox deprecation. This targets NVDA 2026.1 as the minimum, with no cross-version compatibility code. Code (addon/globalPlugins/EnhancedFindDialog/): - Migrate gui.messageBox -> gui.message.MessageDialog.alert at all three call sites. Also fixes a pre-existing crash: the "backend does not support regexp" path called a string as if it were gui.messageBox. - Remove the dead buildVersion.version_year > 2023 gate; drop the import. - Replace the custom config-profile machinery with shouldSuspendConfigProfileTriggers = True on the dialog, so NVDA keeps the document's active profile active while the dialog is shown. The dialog now reads/writes config.conf directly (correct profile, native dirty-marking and persistence). Removes the getActiveProfile monkey-patch, the profile capture/passing, getConfig/setConfig/ strToBool/scheduleProfileSave/_dirtyProfiles, and the _mustSaveProfile/ onStatChange dirty tracking. - Remove WIP/scratch files (installTasks.py, a.txt). Build system (ported from TimerForNVDA): - site_scons/site_tools/NVDATool typed SCons machinery, updated gettexttool, modern sconstruct (EnsurePythonVersion(3, 10), major.minor.patch validation). - buildVars.py rewritten as typed AddonInfo: version 1.9.0, minimumNVDAVersion 2026.1, lastTestedNVDAVersion 2026.1.0, MIT license, changelog filled. Manifest templates gain a changelog line. - Workflows: validate.yml (reusable), pr-checks.yml (artifact comment), release.yml (tag on master -> GitHub release). Add-on Store submission is done manually, not from CI. - flake8 4.0.1 -> 7.1.1 (old pin crashes on Python 3.13), spaces-era flake8.ini, .gitignore additions. Docs and hygiene: - Contributing docs (root + localized): gettext guidance (msgfmt + xgettext, modern Windows build, avoid frozen GnuWin32 0.14.4) and Python 3.13. - Stop tracking the generated addon/doc/en/contributing.html (*.html is gitignored; doc HTML is a scons build artifact). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
marlon-sousa
force-pushed
the
feat/nvda-2026.1-compatibility
branch
from
July 13, 2026 15:04
81ee0d8 to
ebe32f6
Compare
Packaged add-on artifact |
thgcode
approved these changes
Jul 13, 2026
Collaborator
|
Performed all tests, all passed. |
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.
Summary
Makes EnhancedFindDialog compatible with NVDA 2026.1 and modernizes the build system by porting TimerForNVDA's tooling. NVDA 2026.1 bumped its addon API
BACK_COMPAT_TOto(2026, 1, 0)(Python 3.11→3.13, 32→64-bit), which disabled this addon on manifest metadata alone. A full audit against the 2026.1 source found no breaking API change beyond thegui.messageBoxdeprecation.Release version 1.9.0. Minimum/last-tested NVDA is now 2026.1 — no cross-version compatibility code.
Code changes (
addon/globalPlugins/EnhancedFindDialog/)gui.messageBox→gui.message.MessageDialog.alertat all three call sites (not-found, invalid regexp, unsupported-backend). This also fixes a pre-existing crash: the "backend does not support regexp" path previously called a string as if it weregui.messageBox.cursorManagerHelper.py(buildVersion.version_year > 2023is always true now); dropimport buildVersion.shouldSuspendConfigProfileTriggers. Since 2026.1 is now the floor, the dialog setsshouldSuspendConfigProfileTriggers = True, so NVDA keeps the document's active configuration profile active while the dialog is shown. The dialog now reads/writesconfig.confdirectly (correct profile + automatic dirty-marking/persistence). This removes:config.ConfigManager.getActiveProfilemonkey-patch,getConfig/setConfig/getDefaultConfig/strToBool/scheduleProfileSave+_dirtyProfilesbookkeeping,_mustSaveProfile/onStatChangedirty tracking.Reading via
config.confalso restores native profile-stack fallthrough and spec-validated bools.addon/installTasks.py,a.txt).Build system modernization (ported from TimerForNVDA)
site_scons/site_tools/NVDATool/(typed SCons machinery), updatedgettexttool, modernsconstruct(EnsurePythonVersion(3, 10),major.minor.patchvalidation).buildVars.pyrewritten in typedAddonInfoform:addon_version=1.9.0,minimumNVDAVersion=2026.1,lastTestedNVDAVersion=2026.1.0, MIT license fields, changelog filled.changelogline.validate.yml(reusable),pr-checks.yml(artifact comment), andrelease.yml(tag on master → GitHub release). Add-on Store submission is done manually, not from CI.4.0.1→7.1.1(old pin crashes on Python 3.13), spaces-eraflake8.ini,.gitignoreadditions.Docs & repo hygiene
contributing.md): ported the gettext dependency guidance from EnhancedDictionaries PR Update the pipeline to generate the English README.md correctly. #22 (explainsmsgfmtandxgettext, recommends a modern Windows gettext build, warns against the frozen GnuWin32 0.14.4 that breaksscons pot) and bumped the stated Python to 3.13. Italian translated to match; other languages reuse the EnhancedDictionaries translations.addon/doc/en/contributing.html(*.htmlis gitignored; doc HTML is a scons build artifact, matching TimerForNVDA — no generated HTML is version-controlled).Add-on Store submission
release.ymlstops at creating the GitHub release.Verification done
pre-commit run --all-files— passes (flake8 clean).sconsbuildsEnhancedFindDialog-1.9.0.nvda-addon;scons potbuilds the.pot. Bundle manifest confirmed:version=1.9.0,minimumNVDAVersion=2026.1,lastTestedNVDAVersion=2026.1.0,changelogpresent.Functional test script (NVDA 2026.1)
This is a manual functional test procedure. The addon patches NVDA's live
CursorManager/OffsetsTextInfoinside a running NVDA process, so there is no unit-testable surface — behaviour must be exercised in NVDA itself.No test fixture ships with the addon. Run the cases below against any long, text-rich web page in browse mode — e.g. a Wikipedia article (https://en.wikipedia.org/wiki/NonVisual_Desktop_Access) or a Google results page. Pick your own search terms from the page as each case instructs; the important thing is the behaviour, not the exact word. Check the NVDA log (see §0) throughout.
0. Environment & setup
sconsproducesEnhancedFindDialog-1.9.0.nvda-addon. Confirm the bundle manifest:version = 1.9.0,minimumNVDAVersion = 2026.1,lastTestedNVDAVersion = 2026.1.0,changelogpresent.localdeploy.batfor a source copy).NVDA+F1.Pass condition for load (do first): after restart, the log shows the add-on loaded with no errors and no
DeprecationWarningfromgui.messageBox;NVDA+Ctrl+Fis bound to the enhanced dialog.Choosing terms: skim the page and note — a common word (
WORD) that appears many times; a word visible only near the top (TOPWORD); a word in mixed casing; a nonsense string that appears nowhere (e.g.qqzztop-absent).1. Dialog opens with all enhanced controls
Press
NVDA+Ctrl+F. Expect the dialog with, in order: combo box ("Type the text you wish to find") holding history, "Search type:" radio (Normal / Regular Expression), "Case sensitive" checkbox, "Search wrap" checkbox, OK/Cancel. Escape closes without searching.2. Normal search — forward & backward
Caret at top; Normal, Case off, Wrap off.
NVDA+Ctrl+F, typeWORD, Enter; thenNVDA+F3repeatedly; thenNVDA+Shift+F3. Expect: first match reads the whole line (context reading, not just from the match onward);F3advances through occurrences;Shift+F3walks back.3. Search history combo
After §2,
NVDA+Ctrl+F, Down/Up in the combo. Expect previously searched terms, most-recent first, most recent pre-selected; selecting + Enter searches it; typing a new term still works.4. Case sensitivity (persisted per profile)
Pick a term with more than one casing. Search lowercase with Case sensitive unchecked (matches every casing), then checked (matches only exact case). Re-opening the dialog shows the checkbox in its last-saved state.
5. Search wrap + wrap beep (forward)
Caret at bottom (
Ctrl+End).NVDA+Ctrl+F, check Search wrap, typeTOPWORD, Enter. Expect: wraps to top, short beep (440 Hz), lands onTOPWORD. Without wrap, the same search shows the "0 matches" alert.6. Single-occurrence wrap (whole-document match path)
Pick a term occurring exactly once; search it, keep the caret at/after it, keep Search wrap checked, search again. Expect: the only occurrence is at the caret; the addon still detects it via the whole-story path, beeps, and keeps the selection (no false "not found").
7. Not-found alert ("0 matches" title)
Wrap off.
NVDA+Ctrl+F, typeqqzztop-absent, Enter. Expect a MessageDialog alert titled "0 matches", bodytext "qqzztop-absent" not found. Must be aMessageDialog, notgui.messageBox— confirm noDeprecationWarninglogged.8. Regexp search — forward & backward
Caret at top. Select Regular Expression Search; try patterns matching page content, e.g.
\b\w{7,}\b,\d{4},[A-Z][a-z]+,https?://\S+.NVDA+F3/NVDA+Shift+F3walk matches forward/back. Note: with regexp selected, the Case sensitive checkbox is disabled — verify it greys out.9. Invalid regexp alert
Regexp selected. Type an invalid pattern like
[unclosed(, Enter. Expect a MessageDialog alert titled "0 matches", body "The entered text is not a valid regular expression." The dialog does not close/search. (Covers theonOkre.compileguard.)10. Regexp disabled on unsupported backend
Focus a control whose
TextInfois not anOffsetsTextInfo(e.g. an MS Word document).NVDA+Ctrl+F. Expect the "Search type:" radio disabled and forced to Normal; history shows only "normal" entries.11. Previously-crashing "backend does not support regexp" path
First do a regexp search on a web page (so the most-recent history entry is a regexp term). Then focus a non-
OffsetsTextInfocontrol (Word) without opening the dialog, and pressNVDA+F3. Historically this called a string asgui.messageBoxand crashed; it must now show a MessageDialog alert titled "0 matches", body "current textInfo backend does not support regular expression searches" — no traceback. (script_findNext/Previousfirst re-route to the dialog; the alert incursorManagerHelper.findis the backstop — confirm no crash either way.)12. Per-profile persistence — manual profile
Create/activate a manual configuration profile. With it active, set Case sensitive = on, Search wrap = on, search. Switch to default, open dialog. Re-activate manual, open dialog. Expect states saved against the active profile: manual keeps on/on; default keeps its own independent values; survives close/reopen and profile switches.
13. Per-profile persistence — triggered profile (
shouldSuspendConfigProfileTriggers)This is the case that specifically exercises the profile-trigger machinery. The addon no longer captures the active profile itself; it relies on NVDA 2026.1 suspending profile triggers while the dialog (which sets
shouldSuspendConfigProfileTriggers = True) is shown. A manual profile (case 12) stays active regardless of focus, so it does not test this — a triggered profile does, because opening the dialog moves focus off the document..iniunder the NVDA user configprofiles/folder, section[EnhancedFindDialog].[EnhancedFindDialog]section persists in the app-specific.ini(saved on NVDA exit). No profile-switch churn/errors in the log when the dialog opens over the triggered profile.Regression / log checklist
gui.messageBoxDeprecationWarningshouldSuspendConfigProfileTriggers)Secure mode sanity (optional): on the secure/sign-in screen,
NVDA+Ctrl+Ffalls back to NVDA's built-in Find dialog (the addon disables itself in secure mode). No addon errors logged.🤖 Generated with Claude Code