Overview
Vision enhancement providers add visual highlighting and other visual aids to NVDA, helping low-vision users track the focus, navigator object, and other elements on screen. Providers can draw highlights, magnify content, or apply color filters.Architecture
Base Class
All vision providers inherit fromvision.providerBase.VisionEnhancementProvider, which provides:
- Event registration framework
- Settings management
- Lifecycle management (initialization/termination)
- Configuration persistence
Provider Settings
Providers also define a settings class inheriting fromVisionEnhancementProviderSettings:
Creating a Basic Provider
Minimal Provider Structure
Full Implementation: NVDA Highlighter
The built-in NVDA Highlighter is a complete example showing all key features:Provider Initialization
Event Registration
Highlight Window Implementation
The highlight window is a transparent, topmost window that draws rectangles:Window Creation
Drawing Highlights
Advanced Features
Multi-Monitor Support
Efficient Repainting
Settings Integration
Testing Your Provider
1
Create provider file
Place your provider in
source/visionEnhancementProviders/yourprovider.py2
Restart NVDA
Restart NVDA or reload plugins
3
Enable provider
Open NVDA Settings > Vision and enable your provider
4
Test functionality
- Verify visual effects appear correctly
- Test with focus changes
- Test with navigator object movement
- Verify multi-monitor support
- Test settings changes take effect
Best Practices
Performance
Keep drawing operations efficient - highlights update frequently during navigation
Thread Safety
All drawing must happen on the GUI thread. Use wx.CallAfter if needed
Resource Cleanup
Always release GDI/GDI+ resources and unregister from event extension points
Error Handling
Handle exceptions gracefully - don’t crash NVDA if drawing fails
Common Issues
Highlights Don’t Appear
- Verify window is created and sized correctly
- Check that layered window attributes are set
- Ensure transparency is configured properly
- Verify GDI+ initialization succeeded
Highlights in Wrong Position
- Check coordinate system (screen vs client coordinates)
- Verify multi-monitor positioning logic
- Ensure location rectangles are valid
- Account for DPI scaling if needed
High CPU Usage
- Implement dirty region tracking
- Don’t redraw on every event
- Batch updates when possible
- Use efficient graphics operations
Highlights Not Updating
- Verify event extension points are registered
- Check that nextHandler() is always called
- Ensure InvalidateRect() is called appropriately
- Test that event handlers aren’t silently failing
Reference
Key Modules
vision.providerBase: Base provider classesvision.visionHandlerExtensionPoints: Event extension pointsvision.constants: Context types and constantslocationHelper: Rectangle helpers (RectLTRB, RectLTWH)winGDI: GDI+ drawing functionswindowUtils: Custom window creation
Context Types
Providers can highlight different contexts:Context.FOCUS: Currently focused objectContext.NAVIGATOR: Navigator object (object review)Context.BROWSEMODE: Browse mode caret positionContext.FOCUS_NAVIGATOR: Focus and navigator overlap
Extension Points
Available extension points inEventExtensionPoints:
post_focusChange: After focus changespost_reviewMove: After navigator object movespost_browseModeMove: After browse mode caret movespost_mouseMove: After mouse movespost_caretMove: After caret moves in edit fields
Example Providers
Study these providers insource/visionEnhancementProviders/:
NVDAHighlighter.py: Full-featured highlighting provider_exampleProvider_autoGui.py: Example with dynamic settings
Developer Guide
See the NVDA Developer Guide for complete plugin development information
