No accessibility attributes + hardcoded English strings (a11y + i18n gap) #28
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Every
MouseAreain the widget lacksaccessible.nameandaccessible.description. Screen readers receive no semantic information about interactive elements.In addition, a large number of user-facing strings are hardcoded American English literals scattered throughout QML and JavaScript. There is no centralized string table, no
qsTr()/qsTranslate()usage, and no infrastructure for linguistic localization.Impact
Proposed Path Forward — Permissions & Accessibility
Resolves: #16 (over-declared permissions), #23 (hardcoded popout dimensions), #28 (no accessibility + hardcoded strings)
Overview
These three issues are independent but small. #16 is a one-line manifest fix. #23 is a layout improvement. #28 is a larger i18n/a11y effort that I'll scope to a minimal viable improvement (accessible names on MouseAreas) rather than a full translation infrastructure, which is out of scope for this pass.
Plan
Step 1 — Remove unused permissions (fixes #16)
Change
plugin.jsonpermissions from:to:
The plugin never reads or writes DMS settings. Only
processis needed for launchingtailscaleand clipboard commands.Step 2 — Dynamic popout sizing (fixes #23)
Replace hardcoded
popoutWidth: 360andpopoutHeight: 400with dynamic bindings. Quickshell'sPluginComponentsupports implicit sizing. Set:Also remove the
Math.min(..., 200)cap on the ListView height, allowing it to grow with content. The ListView height becomes:If there are no peers, the list has zero height. The popout shrinks accordingly. Add a
minimumHeightorminimumWidthif Quickshell supports it, otherwise useMath.maxwith a sensible minimum.Step 3 — Add accessible attributes (partial fix for #28)
Add
accessible.nameandaccessible.descriptionto every interactiveMouseArea:accessible.name: "Toggle Tailscale"; accessible.description: "Connect or disconnect from Tailscale"accessible.name: "Copy hostname"; accessible.description: "Copy " + modelData.hostname + " to clipboard"accessible.name: "Copy IP address"; accessible.description: "Copy " + modelData.ip + " to clipboard"accessible.name: "Set exit node"; accessible.description: "Route through " + modelData.hostnameaccessible.name: "Clear exit node"; accessible.description: "Remove current exit node"accessible.name: "Tailscale toggle"; accessible.description: "Right-click to toggle Tailscale connection"Do NOT implement full i18n infrastructure (qsTr, translation files, etc.) — that's a larger architectural change. The accessible names are in English for now but at least screen readers get semantic information.
Success Criteria
plugin.jsondeclares only["process"]permission.popoutWidthandpopoutHeightare dynamically bound to content size, not magic numbers.MouseAreahasaccessible.nameandaccessible.description.AFK Classification
Partial AFK. The permission and accessibility changes are pure text edits. The dynamic popout sizing requires understanding Quickshell's sizing API — the agent can make reasonable bindings but may need HITL to verify the popout actually resizes correctly and doesn't clip content or look broken at edge cases (zero peers, many peers, etc.).
Files Modified
tailscalectl/plugin.json— permissions arraytailscalectl/TailscaleWidget.qml— popout dimensions, ListView height, accessible attributes on all MouseAreasAlso resolves: #16, #23
Yeah, you don't just get to say "I'm not doing that because it's hard" and call that a plan to implement resolution to this issue. I'm fine keeping focus narrow now and working on the localization effort later. But if you're not going to plan to close this issue out, because you're skipping some of it, you should create a new issue with narrower scope you will fix and reference it here, or open a new, narrower issue with what you won't fix here.
I recommend the latter. Open a new issue that focuses purely on the localization part you plan to skip. Reference this issue.
Proposed Path Forward — Permissions & Accessibility (Revised)
Resolves: #16 (over-declared permissions), #23 (hardcoded popout dimensions), partial #28 (accessible attributes only)
Overview
#16 is a one-line manifest fix. #23 is a layout improvement. #28 has two parts: accessible attributes (in scope) and full i18n/localization (out of scope for this pass). Per @jtmorris's feedback, a new issue will be created for the i18n scope.
Plan
Step 1 — Remove unused permissions (fixes #16)
Change
plugin.jsonpermissions from:to:
Step 2 — Dynamic popout sizing (fixes #23)
Replace hardcoded
popoutWidth: 360andpopoutHeight: 400with dynamic bindings:Remove the
Math.min(..., 200)cap on the ListView height. ListView height becomes:If there are no peers, the list has zero height. The popout shrinks accordingly.
Step 3 — Add accessible attributes (partial fix for #28)
Add
accessible.nameandaccessible.descriptionto every interactiveMouseArea:accessible.name: "Toggle Tailscale"; accessible.description: "Connect or disconnect from Tailscale"accessible.name: "Copy hostname"; accessible.description: "Copy " + modelData.hostname + " to clipboard"accessible.name: "Copy IP address"; accessible.description: "Copy " + modelData.ip + " to clipboard"accessible.name: "Set exit node"; accessible.description: "Route through " + modelData.hostnameaccessible.name: "Clear exit node"; accessible.description: "Remove current exit node"accessible.name: "Tailscale toggle"; accessible.description: "Right-click to toggle Tailscale connection"Step 4 — Create new issue for i18n scope
Open a new issue titled "Implement i18n/localization for Tailscale plugin strings" referencing #28. This tracks the full translation infrastructure (qsTr, translation files, etc.) that is deferred to a future pass.
Success Criteria
plugin.jsondeclares only["process"]permission.popoutWidthandpopoutHeightare dynamically bound to content size.MouseAreahasaccessible.nameandaccessible.description.AFK Classification
Partial AFK. Permission and accessibility changes are pure text edits. Dynamic popout sizing requires HITL to verify the popout resizes correctly at edge cases (zero peers, many peers).
Files Modified
tailscalectl/plugin.json— permissions arraytailscalectl/TailscaleWidget.qml— popout dimensions, ListView height, accessible attributesAdded basic Accessible roles; full i18n deferred. Human to-do: verify with screen reader + provide translations. Merged to vibes.
Advanced via merge
daab237(basic Accessible roles added). Full i18n/a11y verification pending. The plugin is confirmed working by @jtmorris. Human code review required before merging to testing.