Screen readers on macOS¶
How it works¶
On macOS, Lights Off uses the accessible_output2 Python library to send speech to
VoiceOver. The library is installed automatically as a dependency on macOS:
accessible_output2>=0.17; sys_platform == 'darwin'
At module load time lights_off/speak.py does:
from accessible_output2 import outputs
_speaker = outputs.auto.Auto()
Auto() selects the best available output driver. On a standard macOS system this routes
through AppKit's NSSpeechSynthesizer, which feeds into VoiceOver's speech channel.
VoiceOver¶
VoiceOver is Apple's built-in screen reader. Enable it with Command + F5 or via System Settings → Accessibility → VoiceOver.
Lights Off does not require VoiceOver to be running. When VoiceOver is off, speech is still delivered through the macOS TTS engine (the same voices used by VoiceOver), so you will hear content even with VoiceOver disabled.
Changing the speech voice¶
The voice used by Lights Off is the System Voice configured in: System Settings → Accessibility → Spoken Content → System Voice.
Changing it there also changes what you hear in Lights Off.
Apple Silicon notes¶
accessible_output2 is a pure-Python wrapper around macOS system APIs and works natively
on Apple Silicon. No Rosetta 2 is required for TTS.
Supported output backends¶
accessible_output2 supports several output drivers. On macOS the driver used is
outputs.osx_sapi.OSXSAPI (wraps NSSpeechSynthesizer) or
outputs.auto.Auto (auto-detects). You can check which driver is active:
from accessible_output2 import outputs
driver = outputs.auto.Auto()
print(driver.__class__.__name__)
Troubleshooting¶
No speech on macOS.
1. Open System Settings → Accessibility → Spoken Content and verify the System Voice is
set and works with the Speak button.
2. Ensure accessible_output2 is installed: pip show accessible_output2.
3. If running in a terminal, check that the app has Accessibility permissions in
System Settings → Privacy & Security → Accessibility.
VoiceOver and Lights Off speaking at the same time. VoiceOver will also narrate focus changes in the wxPython window. This is normal. If it is distracting, you can silence VoiceOver with Control while Lights Off speaks through the TTS engine independently.