Over the past week, I've made solid progress on implementing accessibility into the Godot game engine. Here's what I've achieved so far.
Getting Focused
Focus-tracking is critical for any screen reader. If I don't know which element has focus, and in what state the widget currently is, I simply cannot interact with the interface.
Fortunately, Godot's Control widget implements signals indicating when focus is gained or lost. I was blocked for several weeks because, while I'd written code to add this signal to newly-instantiated widgets, the code ran too late in the scene's lifetime to catch and augment every widget. Ultimately I had to add accessible widgets to a common group, then scrape the final scene tree to add any that were missed in the initial pass.
With focus-tracking implemented, I began crafting presentations for each widget class. A button, for instance, might present itself to screen readers as "2D: button". I can now tab through all controls on the editor's main screen and, with one exception, each provides at least a basic hint to its identity and function.
Drilling Down
Focus is only a small piece of the puzzle, however. Interface elements must be keyboard-navigable. To that end, I began working on enhancing the presentation of LineEdit. LineEdit
controls should speak text as it is inserted or deleted. They should also speak text as it is arrowed past.
My initial implementation added a caret_moved
signal emitted whenever the cursor changed position. Just this morning a better approach was suggested that didn't need a signal, and I'm currently evaluating whether this will meet my needs. Even though my first attempt missed its mark, I'm glad that the Godot developers seem responsive to the necessity for engine changes to improve accessibility.
If all goes well, I'll push these changes later today. Keep an eye on the repository for the latest changes.
Speaking Out
The accessibility addon currently prints text to the console. Ultimately, it will need to use either text-to-speech or the user's native screen reader. Last week I begun work on godot-tts, an addon that exposes a simple text-to-speech API under Windows and Linux. Windows uses Tolk to interface directly with either SAPI or a running screen reader. On Linux, Speech Dispatcher provides convenient access to an underlying speech engine. Unfortunately I can't seem to expose my speech API to GDScript, but I have some thoughts on why that might be and will explore those this week.
Where Next?
This week I hope to finalize my work on LineEdit
, submitting whatever engine changes are needed to get it working with the accessibility addon. I'd also like to implement keyboard control for at least one more widget, as well as to determine why the TTS API isn't available to scripts.