Magnifier Readme for future developers - #20880
Boumtchack wants to merge 12 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The only noted issue is a minor documentation clarification.
Review effort: Lite
Findings: 1
What changed in this PR
Adds developer handover documentation for NVDA’s Magnifier module.
Changes:
- Documents architecture, runtime behavior, API pitfalls, and conventions.
- Records limitations, technical debt, and future work.
- Provides testing and maintenance guidance.
| File | Description |
|---|---|
source/_magnifier/README.md |
Adds comprehensive Magnifier development documentation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Clarified unit test organization and details in README. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
|
||
| 5. **`MagSetInputTransform` requires UIAccess**, so an installed copy of NVDA. On a portable copy or when running from source, the call fails with `WinError 5` (access denied). The code checks `systemUtils.hasUiAccess()` up front, then on `WinError 5` sets `_inputTransformSupported` to `False` and continues without it. Consequence: **touch cannot be properly tested from source**. You need an installed build. | ||
|
|
||
| 6. **Native errors arrive as `OSError`**, thanks to the bindings' `errcheck`. COM/UIA errors coming from focus tracking arrive as `COMError` (for example `RPC_E_DISCONNECTED` in recent Notepad). The loop catches both. |
There was a problem hiding this comment.
What are "native errors"?
More generally, what is called "native" in this documentation? Seems to be the Windows Magnification API, but a confirmation would be welcome.
There was a problem hiding this comment.
yeah exactly, I will clarify that
CyrilleB79
left a comment
There was a problem hiding this comment.
Thanks for this documentation.
Some small remarks / improvements which do not prevent at all this PR to be merged (even as is).
| | **Blocking touch input while the magnifier runs** (flag in `touchHandler`, alert sound, warning dialog) | Degraded the feature and coupled a core NVDA module to the magnifier. Replaced by `MagSetInputTransform`, the primitive Windows provides for exactly this case. **Lesson: before adding a mechanism to NVDA's core, exhaust the Magnification API.** | | ||
| | **Repeating 8 ms timer with `timeBeginPeriod(1)`** | `timeBeginPeriod` changes the clock resolution for the whole system and costs power. A repeating timer does not re-arm cleanly after an error. The smoothness problem was solved by the mouse hook. | | ||
| | **Calling the Magnification API from the mouse hook** | Slows down the mouse for the whole system (section 3.4). | | ||
| | **API initialized once per session** | Conflicted with Screen Curtain. Replaced by the dummy cycle (section 5, pitfall 2). | |
There was a problem hiding this comment.
Why couldn't the same API be used by both screen curtain and magnifier? That would avoid the screen "light flash" (no color filter) between inverted color filter and black screen of screen curtain. E.g.:
- magnifier color active with color inversion.
- Command to enable screen curtain
- disable magnification (zzom)
- screen curtain changes color filter to black screen
- Command to disable screen curtain
- change color filter to color inversion
- restore zoom level
|
|
||
| ### 4.2 Configuration | ||
|
|
||
| * **Never read `config.conf["magnifier"]` outside `config.py`.** Add a getter/setter in `config.py`, then use it everywhere (commands, panel, classes). |
There was a problem hiding this comment.
Why? Is it specific to magnifier? In other part of NVDA, we just use config.conf directly.
| 1. `_managePanning()`: if the user panned manually and the focus moves, manual panning mode ends. | ||
| 2. If not in manual panning mode, `currentCoordinates` receives the position computed by the `FocusManager`. | ||
| 3. `_doUpdate()` (implemented by the subclass) applies the transform. | ||
| 4. On `OSError` or `COMError`: consecutive error counter. At 3, `_attemptRecovery()`. |
There was a problem hiding this comment.
Why specifically these errors are filtered?
| This document is for whoever takes over development of NVDA's built-in magnifier. | ||
| It explains how the module is built, why it is built that way, which pitfalls have already been hit, and what is left to do. | ||
|
|
||
| The starting point is the magnifier as shipped in NVDA 2026.2. |
There was a problem hiding this comment.
What does it mean?
If you mean that this documentation describes the magnifier as shipped in 2026.2, it is not 100%: there are two exceptions which are part of 2026.3:
| source/contentRecog/recogUi.py| Uses_magnifier.isActive() to pick Windows Graphics Capture instead of GDI during OCR, so recognition sees the real screen rather than magnified or filtered pixels. |
Seems to me that Windows Graphic Capture is only used in 2026.3.
* Full-screen features: zoom from 100% to 5000% in steps of 50, three color filters, two tracking modes (center, relative), tracking of four sources (mouse, system focus, review cursor, navigator object), manual panning, animated screen overview ("spotlight"), moving the mouse to the center of the view, automatic error recovery, coexistence with Screen Curtain, touch support.
"moving the mouse to the center of the view" has only been introduced in 2026.3.
|
Also one question for NV Access reviewers: this documentation uses quite often |
|
One more question: Would it be worth to add the references of PRs that have been reverted? (e.g. true center) |
Link to issue number:
Summary of the issue:
Synthetisation of the work I've done in the past regarding NVDA Magnifier, this documentation is for anyone who would want to work on it in the future.
It regroups some of the processes we've been through and why.
Description of user facing changes:
Description of developer facing changes:
Helper for Magnifier developement
Description of development approach:
Testing strategy:
Known issues with pull request:
Code Review Checklist: