Skip to main content

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 from vision.providerBase.VisionEnhancementProvider, which provides:
  • Event registration framework
  • Settings management
  • Lifecycle management (initialization/termination)
  • Configuration persistence

Provider Settings

Providers also define a settings class inheriting from VisionEnhancementProviderSettings:

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.py
2

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
Vision providers run continuously and can impact performance. Optimize drawing operations and avoid memory leaks.

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 classes
  • vision.visionHandlerExtensionPoints: Event extension points
  • vision.constants: Context types and constants
  • locationHelper: Rectangle helpers (RectLTRB, RectLTWH)
  • winGDI: GDI+ drawing functions
  • windowUtils: Custom window creation

Context Types

Providers can highlight different contexts:
  • Context.FOCUS: Currently focused object
  • Context.NAVIGATOR: Navigator object (object review)
  • Context.BROWSEMODE: Browse mode caret position
  • Context.FOCUS_NAVIGATOR: Focus and navigator overlap

Extension Points

Available extension points in EventExtensionPoints:
  • post_focusChange: After focus changes
  • post_reviewMove: After navigator object moves
  • post_browseModeMove: After browse mode caret moves
  • post_mouseMove: After mouse moves
  • post_caretMove: After caret moves in edit fields

Example Providers

Study these providers in source/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