uttrflow / uttrflow/uttrflow-swift

VoiceOver hears nothing when a dictation starts, finishes or fails: no state change is announced

Open
#551 0 comments 0 reactions 0 assignees View on GitHub
accessibility area:dictation bug P1
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

Nothing in the app posts an accessibility announcement. `grep -rn "NSAccessibility.post\|AccessibilityNotification" Sources/` on main returns no match.

Every piece of dictation feedback lives in the floating button, which is a non-activating panel that never becomes key (`Sources/Uttrflow/Dock/DockPanelController.swift:9-12`, `:174-190`). VoiceOver focus stays in the app the user is typing into, so the button's label changes (`Sources/UttrflowPipeline/DictationPresenter.swift:30-110`: "Listening. Let go to finish.", "Working on what you said.", "Inserted: …", the failure message) are never spoken. The only other surface is the menu bar extra, which is silent until opened. The start and stop cues are sounds, but a failure ("Didn't catch that.", "Microphone access is required…") has no sound and no announcement.

## Why it matters

A VoiceOver user presses the shortcut and gets no confirmation that the microphone opened, that the words were inserted, or why nothing arrived. Dictation is the feature a screen-reader user is most likely to rely on.

## How to reproduce

1. `make app`, turn on VoiceOver, focus a text field in TextEdit.
2. Hold the dictation shortcut, say a sentence, release.
3. Nothing is spoken about the dictation's state. Repeat holding the shortcut in silence: "Didn't catch that" is shown on the button and never spoken.

## Acceptance criteria

- Recording started, words inserted (or copied instead of typed) and every failure are announced with `NSAccessibility.post(element:notification: .announcementRequested, userInfo:)` at an appropriate priority (failures high).
- The announcement for "inserted" does not read the whole dictation back unbounded; `DictationPresenter`'s labels currently append the full `outcome.text` (`DictationPresenter.swift:62, 73, 83, 90`), which for a 4-minute dictation is several minutes of speech. A short preview or word count is enough.
- The wording comes from one place (the presenter), with a unit test per state.
- The pull request says how it was checked with VoiceOver.

Contributor guide

Open the contributing guide

Research direction

Start with Sources/UttrflowPipeline/DictationPresenter.swift:30-110 and the DockPanelController references at Sources/Uttrflow/Dock/DockPanelController.swift:9-12 and :174-190. Trace the dictation start, insertion or copy, and failure states, then add unit coverage for each announcement and verify the wording does not read the full outcome.text. Run make app with VoiceOver using the TextEdit reproduction steps, including a failed silent dictation.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
accessibility, desktop
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.