Core Components
NVDA’s architecture consists of several interconnected components:NVDA Objects
Representations of GUI controls and widgets
Events
System for handling accessibility events
Scripts & Gestures
Input handling and command binding
Plugins
App modules and global plugins
Architecture Layers
1. API Layer
NVDA supports multiple accessibility APIs through specialized classes:- IAccessible/MSAA: Windows legacy accessibility API
- IAccessible2: Extended accessibility interface
- UI Automation (UIA): Modern Windows accessibility API
- Java Access Bridge (JAB): Java application support
- Window: Direct Win32 window support
source/NVDAObjects/ with subdirectories for each API.
2. Object Layer
All GUI elements are represented as NVDA Objects, which provide:- Standardized properties (name, role, value, states)
- Navigation (parent, children, next, previous)
- Event handling
- Text access through TextInfo objects
3. Plugin Layer
Plugins customize NVDA’s behavior through:- App Modules: Application-specific functionality
- Global Plugins: System-wide features
- Overlay Classes: Custom NVDA Object behaviors
Base Object System
NVDA uses a sophisticated base object system defined inbaseObject.py:
AutoPropertyObject
Provides automatic property generation from getter/setter methods:Setting
cachePropertiesByDefault = True on a class caches all properties by default. Individual properties can override this with _cache_propertyName = True/False.ScriptableObject
Provides script and gesture binding capabilities:Dynamic Class Creation
One of NVDA’s most powerful features is dynamic class creation. When an NVDA Object is created, it:- Determines the API class (IAccessible, UIA, etc.)
- Finds overlay classes through
findOverlayClasses() - Allows plugins to add classes via
chooseNVDAObjectOverlayClasses() - Constructs a dynamic class combining all chosen classes
- Initializes overlay classes by calling
initOverlayClass()on each
Event Flow
When an accessibility event occurs:- OS/API fires event (e.g., focus change)
- NVDA receives event through API monitoring
- Event propagates through handler chain:
- Global Plugins
- App Module
- Tree Interceptor (if applicable)
- NVDA Object itself
- Handler processes or calls
nextHandler()to continue
Script Resolution
When a user presses a key:- Input captured by NVDA
- Gesture normalized to identifier (e.g., “kb:NVDA+t”)
- Script search in priority order:
- User gesture map
- Locale gesture map
- Braille display driver gestures
- Global Plugins
- App Module
- Tree Interceptor
- NVDA Object with focus
- Focus ancestors (if script has
canPropagate=True) - Global Commands
- Script executed if found
Text Access
NVDA provides text access through the TextInfo system:- NVDAObjectTextInfo: Default implementation for object properties
- DisplayModelTextInfo: Screen scraping fallback
- Specialized TextInfo classes: For editable text, documents, etc.
- Unit-based movement (character, word, line, paragraph)
- Text extraction and formatting info
- Bounding rectangles for screen location
- Bookmarking and comparison
Memory Management
NVDA uses several techniques for efficient memory management:- Weak references: For cached objects like app modules and tree interceptors
- Garbage collection tracking: Through
garbageHandler.TrackedObject - Cache invalidation: Properties cached only for one core pump cycle
- Dynamic class caching: Reuses dynamically created classes
Threading Model
NVDA uses a main thread for most operations with:- Queue handler: For sequencing operations
- Event queue: For processing events in order
- Script execution: Synchronous on main thread
- Speech/braille: Queued for output
Configuration System
NVDA’s configuration follows a layered approach:- Default config: Built-in defaults
- User config: User’s configuration directory
- Configuration profiles: Context-specific settings
- Scratchpad: Developer testing area
Next Steps
NVDA Objects
Deep dive into NVDA Object system
Events
Learn about event handling
Scripts & Gestures
Master input handling
Writing Plugins
Create your first plugin
