Skip to content

Conversation

@LuciferM242
Copy link

Add comprehensive screen reader accessibility support

Summary

This PR implements comprehensive screen reader accessibility for Moonlight Qt, making the application fully usable with NVDA, JAWS, Narrator, VoiceOver, and Orca.

Motivation

I installed Moonlight and discovered it had no accessibility support for screen readers. As someone who relies on screen readers, I wanted to contribute accessibility improvements to make this app usable for the visually impaired community.

Changes Made

Core Components

  • NavigableToolButton: Added accessibleName property and Accessible.Button role
  • NavigableItemDelegate: Added accessibleName/accessibleDescription properties for grid items
  • NavigableMenuItem: Added Accessible.MenuItem role with press actions
  • NavigableDialog: Added Accessible.Dialog role
  • NavigableMessageDialog: Added accessibility to dialog labels

Main Views

  • main.qml: Added accessibility to window, toolbar, title, and all toolbar buttons
  • PcView.qml: Added accessibility to PC grid with dynamic status announcements (Online/Offline, Paired status)
  • AppView.qml: Added accessibility to app grid, Resume/Quit buttons, with Running/Not running states

Settings

  • AutoResizingComboBox: Added accessibleDescription property and ComboBox role
  • SettingsView.qml:
    • All 25 CheckBoxes now have Accessible.CheckBox role with toggle actions
    • All 7 ComboBoxes have accessible descriptions
    • Bitrate Slider has Accessible.Slider role with value announcements
    • All 7 section headers (GroupBoxes) announce cleanly without HTML tags

Streaming Screens

  • StreamSegue.qml: Added StatusBar role for dynamic connection status ("Starting...", "Connecting...", etc.)
  • QuitSegue.qml: Added StatusBar role for quit progress announcements

Testing

  • ✅ Tested with Windows Narrator
  • ✅ Tested with NVDA (NonVisual Desktop Access)
  • ✅ Tested with JAWS (Job Access With Speech)
  • ✅ All controls properly announce their purpose and state
  • ✅ Navigation works seamlessly with Tab/Arrow keys
  • ✅ Settings section headers announce without HTML formatting

Implementation Details

  • Uses Qt's built-in accessibility framework (Accessible.* properties)
  • No changes to application logic or behavior
  • Maintains all existing visual styling and HTML formatting
  • Screen readers receive plain text announcements while visual users see styled text
  • All interactive elements now have proper ARIA-equivalent roles

Files Modified

12 QML files in app/gui/:

  • NavigableToolButton.qml
  • NavigableItemDelegate.qml
  • NavigableMenuItem.qml
  • NavigableDialog.qml
  • NavigableMessageDialog.qml
  • main.qml
  • PcView.qml
  • AppView.qml
  • AutoResizingComboBox.qml
  • SettingsView.qml
  • StreamSegue.qml
  • QuitSegue.qml

Development Notes

Most of this code was written with assistance from Claude Code (Anthropic's AI coding assistant). While I've tested it thoroughly with multiple screen readers, please feel free to edit, modify, or improve any part of this implementation. I'm not claiming ownership of this approach - my only goal is to make Moonlight accessible to the visually impaired community. If you see better ways to implement any of this, please go ahead and make changes directly. I welcome all suggestions, edits, and improvements!

Impact

This PR makes Moonlight Qt fully accessible for blind and visually impaired users, enabling them to:

  • Navigate all menus and settings independently
  • Launch and manage game streaming sessions
  • Configure all application settings
  • Receive real-time status updates during streaming

Thank you for considering this contribution. Feel free to push commits directly to this PR or request changes - I'm flexible and just want to help make Moonlight accessible for everyone!

Moonlight Accessibility Contributor and others added 4 commits January 9, 2026 21:37
Implements comprehensive accessibility support for screen readers
including NVDA, JAWS, Narrator, VoiceOver, and Orca.

Core Components:
- NavigableToolButton: Added accessibleName property and Accessible.Button role
- NavigableItemDelegate: Added accessibleName/accessibleDescription for grid items
- NavigableMenuItem: Added Accessible.MenuItem role with press action
- NavigableDialog: Added Accessible.Dialog role
- NavigableMessageDialog: Added accessibility to dialog label

Main Views:
- main.qml: Added accessibility to window, toolbar, and all toolbar buttons
- PcView.qml: Added accessibility to PC grid with dynamic status announcements
- AppView.qml: Added accessibility to app grid, Resume/Quit buttons

All interactive elements now properly announce their purpose and state
to screen reader users.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Adds comprehensive screen reader support to all SettingsView controls:

Components:
- AutoResizingComboBox: Added accessibleDescription property and ComboBox role

Settings Controls (all 33 controls):
- All 25 CheckBoxes: Added Accessible.CheckBox role with toggle actions
  (V-Sync, frame pacing, audio/video settings, input settings, etc.)
- All 7 ComboBoxes: Added accessible descriptions
  (resolution, FPS, audio config, language, decoder, codec)
- Bitrate Slider: Added Accessible.Slider role with value announcements

All settings are now fully navigable and operable with screen readers.
Screen readers announce control names, current values, and checked states.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Implements screen reader support for the streaming lifecycle screens:

StreamSegue.qml:
- Added Accessible.StatusBar to stage label for dynamic connection status
  ("Starting App...", "Connecting...", etc.)
- Added Accessible.StaticText to hint text for disconnect instructions

QuitSegue.qml:
- Added Accessible.StatusBar to quit status label
  (announces "Quitting AppName..." to screen reader users)

Screen readers now announce all connection states and quit progress,
ensuring users are informed throughout the streaming session lifecycle.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Add Accessible.name properties to all GroupBox section headers to
provide plain text versions for screen readers, avoiding HTML tag
announcements.

Fixed sections:
- Basic Settings
- Audio Settings
- Host Settings
- UI Settings
- Input Settings
- Gamepad Settings
- Advanced Settings

Screen readers now announce "Basic Settings grouping" instead of
"<font color=skyblue>Basic Settings</font> grouping".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@LuciferM242 LuciferM242 force-pushed the feature/accessibility-improvements branch from bc25574 to 76278fc Compare January 9, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant