Skip to content

Give Avalonia controls real accessible names (#5498, #5499) - #5501

Merged
Gabriel Dufresne (GabrielDuf) merged 3 commits into
mainfrom
fix/avalonia-accessible-names
Oct 9, 2026
Merged

Gabriel Dufresne (GabrielDuf) merged 3 commits into
mainfrom
fix/avalonia-accessible-names

Conversation

@GabrielDuf

@GabrielDuf Gabriel Dufresne (GabrielDuf) commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Screen readers announced several focusable controls by their Avalonia type name (Avalonia.Controls.Grid, StackPanel, Shapes.Ellipse), and the Package Details action dropdown repeated the main button's name.

Why class names were announced

When a ContentControl has no AutomationProperties.Name, Avalonia 12's peer falls back to a direct TextBlock child, then to Content.ToString(), which is the type name for any panel or shape content. Two places hit this because the focusable element is a template part while the name lives elsewhere:

  • Expander: focus lands on the template's ToggleButton#ExpanderHeader, and Avalonia never forwards the Expander's name to it. Expanders that were already named (policy editor, agent policy inspector) still announced their header panel's type.
  • DataGridCell: the cell is the focusable peer and ignores the name set on its content, so even the selection checkbox and the Name column's already-named Grid announced class names.

Changes

  • Styles.Common.axaml: two app-wide styles. One TemplateBinds the Expander header toggle's name to the Expander's. The other forwards a DataGridCell's content name to the cell. A null forwarded name keeps Avalonia's TextBlock fallback, so unnamed expanders and plain-text cells behave as before.
  • Package pages: the Sources, Filters and Search mode expanders and the source-tree checkboxes are named. Every package-list column template is named with its displayed value.
  • Package-list warnings: the Version, New version and Installer host cell names append the same tooltip text as the amber warning icon (unverified installed version, installer host changed). The installer-host warning is security-relevant and was otherwise silent. The names are re-raised when the async host check flags a change.
  • Package Details:
    • the Installation options expander is named
    • the screenshot previous/next buttons are named
    • the indicator pips read "Screenshot N of M", and the current one adds ", current"
    • the action dropdown is now "More options" instead of repeating "Install" / "Update to version X" / "Uninstall"
  • lang_en.json: 4 new keys (Previous screenshot, Next screenshot, Screenshot {0} of {1}, Screenshot {0} of {1}, current).

Verification

  • Build passes; dotnet format whitespace and style are clean.
  • Read through Windows UI Automation on the running app:
    • Updates and Installed pages: 105 package-list cells, none exposing an Avalonia.* name. Cells read values such as Git.Git, 2.55.0.3 and 60.3 MB.
    • Filter pane: the expanders read Sources, Filters and Search mode.
    • Package Details (opened with uniget package show --id Git.Git --source winget): Installation options, Previous/Next screenshot, and pips Screenshot 1 of 3, current. Pressing Next moves current to pip 2.
    • [BUG] Main action and dropdown buttons share the same accessible name in Package Details #5499 before/after: the dropdown read Install next to the Install main button on the unfixed build, and reads More options with the fix.

Not covered

  • No NVDA/Narrator pass. This verifies the UIA names screen readers receive, not the spoken output.
  • No package on the test machine had an active warning, so the warning-name text was not exercised live.
  • Not changed here: the Operation history and Manage shortcuts grids still have cells that expose class names. With the cell-forwarding style in place, each now only needs a name on its template. The install-options tab scroll arrows are also unnamed.

Closes #5498
Closes #5499

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The accessible names are correctly propagated and updated across the affected controls.

0 open findings

What changed in this PR

Improves Avalonia accessibility by replacing internal control-type announcements with meaningful localized names.

Changes:

  • Forwards accessible names through Expander and DataGrid templates.
  • Names package cells, warnings, screenshot controls, and action menus.
  • Adds required English localization keys.
File Description
AbstractPackagesPage.axaml Names filters, source controls, and package cells.
PackageDetailsWindow.axaml.cs Updates screenshot pip names dynamically.
PackageDetailsWindow.axaml Names detail actions and screenshot controls.
PackageCollections.cs Exposes warning-aware cell names.
Styles.Common.axaml Forwards names to focusable template controls.
lang_en.json Adds screenshot accessibility strings.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@randy-but-a-ro randy-but-a-ro Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Pull request was approved automatically: the AI review is complete and all its review threads are resolved. 🎉

Integration Details
{
	"deliveryId": "c5225b40-c410-11f1-8864-72fc27b5812a",
	"headSha": "9edf4efef6aedf52f738e0312357c56d039fd40c",
	"reviewer": "copilot-pull-request-reviewer[bot]"
}

@GabrielDuf
Gabriel Dufresne (GabrielDuf) merged commit 752de8f into main Oct 9, 2026
7 checks passed
@GabrielDuf
Gabriel Dufresne (GabrielDuf) deleted the fix/avalonia-accessible-names branch October 9, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants