4.9 KiB
4.9 KiB
Accessibility redesign — everything that's real
Approved mock: home-mocks/accessibility.html (scratchpad, :8642). Spec wins over mock on
conflict. Tabless leaf stays.
Goals
- Magnifier keybinds: Super+= / Super+- / Super+0 step the zoom from anywhere, through the
shell so the stored preference stays truthful and the OSD shows the level. Mechanism: the
binds call
qs ipc call accessibility zoom in|out|reset; a new IPC target routes toAccessibility.stepZoom(), which computes (×1.25 steps, clamp to the schema's 1.0–5.0), commits through the normal verified-preference path, and posts the OSD. No new script; a dead shell means dead zoom keys, which is honest (everything else in the shell is dead too). - Reduce motion becomes true:
Theme.qml'sdur*tokens gate onSettings.animationsEnabled(0 when off) so the bar/dock/OSD/panels genuinely still. - Visual alerts: new schema key
visualAlerts(bool, def false, groupaccessibility); when on, a one-shot screen-edge flash (per-screen overlay, single animation per event, never looping) fires whereverNotifs.playBelldecides a notification sounds (including when the audible bell is skipped forsound: falseapps? No — the flash follows the same eligibility as the bell EXCEPT the eventSounds gate: visual alerts are for people who can't hear the bell, so the flash fires on bell-eligible notifications even when event sounds are off. Pin that.) - Honest Orca control: running state (pgrep poll on page open + after actions), Start/Stop; the a11y-bus readiness line. No gsettings screen-reader toggle (gsd-owned, inert — refused).
- The primitives get accessible:
SliderRow,ToggleRow,SwitchRow,ActionRow,ChoiceRow,SegmentRow,SettingRow(activatable),OptionPickerRow,PickerRowgainAccessible.role/Accessible.name(from label; detail as description),activeFocusOnTabon the interactive element, key handling (Space/Enter activates, Left/Right steps sliders and segments), and a visible focus indicator (the titlebar close-button border pattern). No API or visual-at-rest changes. - Page rebuilt per mock: Vision / Motion / Hearing / Keyboard & pointer / Screen reader;
dimStrengthgated ondimInactive; magnifier "1× is off" honesty (schema gainsunit: "×"-style display via the page detail — fix the deadzeroLabel); the honesty box for sticky/slow/bounce with the probed-not-assumed copy; mono-audio NOT YET row; "Open Keyboard" jump. - Cleanups:
DESKTOP-PARITY.md's stale AccessX claim corrected; search entries for magnifier/zoom/orca/screen reader/high contrast/reduce motion/visual alerts.
Non-goals: mono audio (deferred with the on-page honesty), sticky/slow/bounce/hover/mouse
keys (refused with receipts), gsettings enable-animations/screen-reader-enabled writes
(inert), shell text scaling.
Ownership
- A:
config/PreferenceSchema.qml(visualAlerts; magnifierFactor detail/unit fix),config/dot/hypr/keybinds.lua(three zoom binds — CHECK for collisions with existing Super+=/-/0 binds first; pick free chords and update the mock copy via B if needed),shell.qml(accessibility IPC target),services/Accessibility.qml(stepZoom, orcaRunning- start/stop, poll discipline),
services/Notifs.qml(flash trigger signal per goal 3), NEWmodules/notifications/VisualBell.qml(+ per-screen wiring in shell.qml),config/dot/hypr/DESKTOP-PARITY.md(stale claim),services/OsdState.qml/OsdModel.jsonly if the zoom OSD needs a new kind (coordinate with C on osd-model-contract).
- start/stop, poll discipline),
- B: the nine row primitives (accessibility additions only — zero API/visual-at-rest
change),
modules/settings/AccessibilityPage.qmlrebuild (+ any new components + qmldir). Reuse KeycapChord for the chord display. - C:
services/SettingsSearch.qml, NEWtests/quickshell/accessibility-contract(page structure; zoom IPC path commits through the verified-preference path and never calls hyprctl keyword; visual bell one-shot — noloops: Animation.Infinite, no Timer-driven repeat; flash follows bell eligibility but not the eventSounds gate; primitives carry Accessible.name + activeFocusOnTab — sweep all nine files; Orca control uses process state, never gsettings),osd-model-contract(zoom kind if added), reconcile any contract pinning Theme durations or the primitives' file contents, backlog Phase 14, README count (174 → 175 expected), docs/commands regen at the end (schema changed).
Hard rules: no live mutations (no zoom application, no orca start/stop, no gsettings writes, no hyprctl keyword/reload); hermetic stubs only; valid QML at every save (primitives are used by EVERY page — a broken SliderRow takes the whole settings app down, so B edits them one at a time with a reload-check between each). B programs against A's pinned APIs; A updates this spec before changing them.