Repository navigation
Accessibility audit of Lite and the Viewer: name 1,400+ column filter, sidebar and tab buttons for UI Automation, and pin it - #4696
Merged
Conversation
…mation reads "Filter <column>" Every DataGrid column header carries a ColumnFilterButtonStyle button whose only content is the Segoe MDL2 funnel glyph (U+E71C, a private-use character), so UIA gave it a name no screen reader can speak. Each button now carries AutomationProperties.Name="Filter <the header caption beside it>". Applied alike to the Lite and Viewer twin files; the theme files are untouched. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NKkGR7ZBZavtGbVYcK58GC
…red icon buttons a UI Automation name in Lite and the Viewer Content that is an element tree (a StackPanel holding a glyph and a label, a panel Header) leaves UIA with the ToString() fallback, and glyph-only buttons (the "<<" sidebar toggle, +/- zoom, the close X, the month arrows) were read out as the raw glyph. Each now carries AutomationProperties.Name, in XAML or AutomationProperties.SetName where the control is built in code (server tabs, plan sub-tabs, their close buttons, the wait drill-down and shared DataGrid filter buttons). Twin files got the same change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NKkGR7ZBZavtGbVYcK58GC
…e and the Viewer has a UI Automation name source One shared scan (Darling.Tests/XamlAccessibleNames.cs, linked into Lite.Tests like CSharpSourceWalker) and one test per app. Content or Header that is an element tree, or a string with no letter or digit (a private-use glyph, a plus sign, an X), does not count; AutomationProperties.Name / LabeledBy or real text does. The allowlist is exact in both directions and names the issue for each exception: the five PlanViewerControl.xaml glyph buttons (#4692, held by the plan-viewer lane). Proven RED by removing one name in each app. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NKkGR7ZBZavtGbVYcK58GC
Every row's picker was named "Pick a color", so a screen reader listed identical buttons. Each now reads "Pick a color for <slot label>".
erikdarlingdata
marked this pull request as ready for review
September 29, 2026 00:38
This was referenced Sep 29, 2026
erikdarlingdata
added a commit
that referenced
this pull request
Sep 29, 2026
Reverts #4696 (9a0562d). This removes the UI Automation names #4696 added in Lite, the Darling Viewer and PerformanceMonitor.Ui, and the source-scan pins that required them (Lite.Tests.XamlAccessibleNameTests, Darling.Tests.ViewerXamlAccessibleNameTests and their shared XamlAccessibleNames scan). The tree matches dev as it was before #4696.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #4684 (the UI Automation pass that started this). No issue to close.
Why
A UI Automation (UIA) pass found #4684 (selecting the "+" plan tab adds two tabs). Every tab, button, menu item and toggle in Lite and the Darling Viewer is checked on three questions: can UIA and the keyboard reach it, does it have a name, and does UIA Invoke do what a click does. This is an audit from source (a Python scanner over every .xaml plus the code-behind that builds controls or wires mouse handlers; scratch only, not committed). There is no live walk yet.
Almost all of it was one defect. Every DataGrid column header carries a filter button whose only content is the Segoe MDL2 funnel glyph (U+E71C, a private-use character), so UIA gave roughly 1,400 buttons a name nobody can hear.
What changes
Names only (
AutomationProperties.Namein XAML,AutomationProperties.SetNamewhere the control is built in code). Nothing changes on screen and no theme key changes. Twin files got the same fix.ColumnFilterButtonActiveStyle.PerformanceMonitor.Ui): the sidebar buttons whose content is a glyph-plus-labelStackPanel(Open Plan Viewer, Import Data, Import Settings, View Log, Open Log Folder, Settings, About, and the Viewer's Add Server, Add Multiple, Manage Servers, Manage Tags); "Toggle sidebar" on the<<button; the Plan Viewer tab and its close button; Expander headers and CheckBoxes whose content is an element (AutomationProperties.Name="{Binding DisplayName}"); "Enabled" on the check boxes in the mute-rule and notification-route grids; the Time Range slicer toggle; and inPerformanceMonitor.Ui, Zoom In, Zoom Out, Close Properties (Blocking chain and Deadlock graph) and the calendar's Previous month / Next month arrows.{Binding Text, ElementName=ImportDataButtonText}) because that label changes to "Importing..." while it runs.SetName): each server tab and its close button (Lite and ViewerMainWindow.xaml.cs), each plan sub-tab and its close button (ServerTab.Plans.cs,ViewerServerTab.Plans.cs; the Plan viewer: selecting the "+" tab through UI Automation adds two empty sub-tabs #4684 ToString shape), the wait drill-down and shared DataGrid filter buttons, and the theme colour picker's "..." button, named for its slot ("Pick a color for ") so the rows don't all read the same.Lite.Tests/XamlAccessibleNameTests.csandDarling.Tests/ViewerXamlAccessibleNameTests.cs, both over one shared scan (Darling.Tests/XamlAccessibleNames.cs, compiled into Lite.Tests by a link line likeCSharpSourceWalker). EveryButton,ToggleButton,MenuItemandTabItemoutside aControlTemplateneedsAutomationProperties.Name/LabeledBy, or aContent/Headerthat is text (a binding or resource counts). An element tree or a string with no letter or digit does not count, which is exactly the Plan viewer: selecting the "+" tab through UI Automation adds two empty sub-tabs #4684 shape. The allowlist compares exactly in both directions and names the issue per entry.Audit table (scanner, before then after this PR)
Interactive elements checked: Lite 1,278 (1,235 XAML elements, 24 code-built controls, 8 code-wired mouse handlers, 7 ContextMenu hosts, 4 code-built ContextMenus); Viewer 1,319 (1,274 / 21 / 12 / 8 / 4); shared Ui 76 (41 / 21 / 9 / 1 / 4). Scanned kinds: Button, RepeatButton, ToggleButton, CheckBox, RadioButton, MenuItem, TabItem, Hyperlink, ComboBox, Expander, plus anything with a MouseLeftButton/Mouse/PreviewMouse/DoubleClick handler.
ControlTemplateparts in the three themes (not instances) + 1 scanner false positive (a MenuItem whose Header is a string built withnew string(' ', n)); Viewer 19 = 18ControlTemplateparts (theme files and two local ComboBox templates) + the same false positive; Ui 8 = all plan viewer (#4692)ControlTemplates (the theme files and two local ComboBox templates)MainWindow.xamlBorders)After this PR the pin finds exactly 5 unnamed governed elements in each app, all in
PerformanceMonitor.Ui/PlanViewerControl.xaml(lines 21, 23, 246, 334, 373: zoom in, zoom out and three close X buttons), owned by #4692.Left alone on purpose (hands off, reported not fixed):
StandalonePlanViewerController.cs(line 91 "+" tab header, 224subCloseBtn, 231subTabStackPanel header),PlanViewerControl.Rendering.cs(110 node click onMouseLeftButtonUp, 489-503AttachOriginNavigationwarning link onMouseLeftButtonDown),PlanViewerControl.Properties.cs:1072,PlanViewerControl.xaml(21, 23, 51, 246, 289, 322, 334, 340, 373), and the Viewer'sThemes/*.xaml(PR #4685). No theme file was edited in either app.Issues filed (no
in-progresslabel)Test plan
dotnet buildof Lite.Tests and Darling.Tests: 0 Warning(s), 0 Error(s), before and after mergingorigin/dev.Lite.Tests.XamlAccessibleNameTests(1/1) andDarling.Tests.ViewerXamlAccessibleNameTests(1/1).AutomationProperties.Name="Toggle sidebar"fromMainWindow.xamlfailed each pin withNO NAME SOURCE (1 found, 0 allowed): ...MainWindow.xaml|Button|ToggleSidebar_Click; restored, both green again.Viewer(after mergingorigin/dev): Total 2017, Failed 0, Skipped 127 (live PostgreSQL classes; no rig here).Lite.Testssuite (after mergingorigin/dev): Total 5556, Failed 0, Skipped 0, Errors 0, 181 s.Notes
ColumnFilterButtonStylebutton is left unnamed).Lite.Tests.csprojgains one link line for the shared scan (same idiom asCSharpSourceWalker).CHANGELOG
SECTION: Fixed
ENTRY:
REF:
[Accessibility audit of Lite and the Viewer: name 1,400+ column filter, sidebar and tab buttons for UI Automation, and pin it #4696]: Accessibility audit of Lite and the Viewer: name 1,400+ column filter, sidebar and tab buttons for UI Automation, and pin it #4696