Skip to main content

Overview

NVDA Objects represent controls and widgets in applications. By creating custom NVDA Object classes (overlay classes), you can:
  • Enhance accessibility of poorly accessible controls
  • Provide better names, descriptions, and role information
  • Customize how text content is accessed
  • Add custom scripts and event handlers to specific controls
  • Fix broken accessibility implementations
Custom NVDA Objects use the overlay class pattern - you create classes that add functionality without modifying the base implementation.

NVDA Object Hierarchy

Every widget is represented by an NVDA Object that provides:
str
The label/name of the control (e.g., “OK”, “File name”)
Role
The type of control (from controlTypes.Role: BUTTON, EDITABLETEXT, CHECKBOX, etc.)
str
The current value (e.g., percentage of scrollbar, content of edit field)
set[State]
Current states (from controlTypes.State: FOCUSED, SELECTED, CHECKED, etc.)
str
Additional descriptive information (usually from tooltip)
tuple
Screen coordinates: (left, top, width, height)
navigation.py

Creating Overlay Classes

Overlay classes are chosen through the chooseNVDAObjectOverlayClasses method in app modules or global plugins:

Overlay Class Rules

  • Insert overlay classes at the beginning of clsList (index 0)
  • Overlay classes must inherit from an appropriate base class (usually the API class like IAccessible or Window)
  • Multiple overlay classes can be added; they’re resolved in order
  • More specific classes should be inserted earlier

Customizing Properties

Override property getters to customize object information:

Handling Events

Overlay classes can handle events specific to their instances:
events.py

Event Methods in Objects

When events are defined on NVDA Objects (not app modules/global plugins), the signature is different:

Adding Scripts

Add keyboard commands specific to certain controls:
scripts.py

Initialization

Use initOverlayClass to initialize overlay classes:
initialization.py

Text Support

Implement text support for controls by providing a TextInfo class:

Behaviors

NVDA provides behavior mixins for common functionality:
behaviors.py

Common Behaviors

mixin
Provides caret tracking and text editing support
mixin
Dialog-specific functionality
mixin
Progress bar announcement logic
mixin
Enables row/column navigation with arrow keys
mixin
Reports typed characters in applications that don’t fire character events

Practical Examples

Example 1: Custom Button with Icon

customButton.py

Example 2: Enhanced List Item

enhancedList.py

Example 3: Custom Tree Item

customTree.py

Example 4: Custom Data Table

dataTable.py

Caching Properties

Use _cache dictionary for expensive computations:
caching.py

API-Specific Base Classes

Different accessibility APIs require different base classes:
apiClasses.py

Testing

1

Create app module or global plugin

Implement chooseNVDAObjectOverlayClasses method.
2

Define overlay classes

Create your custom NVDA Object classes.
3

Place in scratchpad

Put files in appropriate scratchpad directory.
4

Enable NVDA speech viewer

Tools > Speech Viewer to see what NVDA announces.
5

Test with object navigation

Use NVDA object navigation to examine objects.

Debugging

Best Practices

Performance:
  • Cache expensive computations
  • Don’t perform long operations in property getters
  • Clear caches appropriately when properties change
  • Use _cache dictionary for caching
Code Quality:
  • Always call super() methods unless overriding completely
  • Provide meaningful names and descriptions
  • Test with multiple applications
  • Handle missing/None values gracefully
  • Document complex logic

Common Patterns

patterns.py