Toolbar: prior dictation recovery hides active and paused Read controls
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- macos, swift
- Domain
- accessibility, desktop
Research direction
Start with Sources/LocalVoice/FloatingToolbar.swift, especially FloatingResult.pending (lines 43–49) and FloatingToolbar.content (lines 147–150), then trace the application-method/result-selection seam and production host. Reproduce the mixed state with an older dictation recovery and Read preparing, playing, and paused; verify the revealed controls match the live reading state while preserving the recovery. Cover the collision at the selection seam and through the production host, then repeat the playing and paused checks in signed installed Preview.
Written by the indexing model from the issue text.
Description
Outcome and priority
P2 functional defect, reproduced in installed Preview. An older dictation recovery takes over the revealed floating toolbar during a new active or paused reading. The compact mark correctly reports Read, but its click reveals Retry transcription / Record again instead of the reading's controls. The person must reopen the main Read page to pause, resume or stop.
Build and native reproduction
Workbench Preview 2.3.0, build 20260928223302, clean source c3fff97d686c2f6a575c2967abc81cc49bc4d8d4, macOS 26.5.1 (25F80), Apple M5. Verified through fresh in-app Copy build details and native Paste, with bundle metadata cross-check. Integration held installs for this segment.
- Start with an existing unretried dictation recovery. Home says “A capture is kept for recovery”; the toolbar's recovery card says “A recording was recovered. Use Retry transcription.” Leave it intact.
- On Read, enter synthetic text (this run: 2,458 characters), use a Mac voice at 180 words/min, and choose Listen.
- Close the main window. The compact toolbar's accessible description is Read, its help is “Reading aloud”, and its value is “Reading aloud, Needs attention”. It is compact, with no separate reading HUD observed.
- Click the compact mark once. The revealed content is Dictation needs attention, Retry transcription, Record again, and Dismiss dictation error. There is no Pause or Stop reading in that pointer-revealed content.
- Reopen the main window through Window > Open Workbench. Read is still playing: 31.125375 seconds of 2:43, with Pause and Stop available there.
- Pause on Read at 38.869375 seconds, close the main window and click the compact mark again. Its help says “Reading paused” and its value includes Paused, but the same old dictation recovery card appears, with no Resume or Stop reading.
Observed in both playing and paused states within one native run. Returning to the main Read page preserved the paused playhead exactly. Stop there worked; the original Read draft, voice and pace were restored, and the old recovery remains available. No recovery was retried or dismissed. Private AX/screenshots remain in the QA session.
Native counterexample: focused entry works
On the same build with the same recovery still pending, Window > Focus floating toolbar revealed the ordinary Read row. Pause reading changed to Resume reading; Resume restored Pause reading. More kept the old recovery commands under Dictation needs attention and separately offered Read > Stop reading. That Stop ended only the synthetic reading. This narrows the failure to pointer-result presentation overriding the live row; the transport owner itself worked. Read text, voice and pace were restored again.
Owner and bounded cause
FloatingResult.pending, lines 43–49 checks dictation phase/preview state, then returns .dictationFailure for any captureFailure. It does not first exclude active/preparing/paused Read. Only its subsequent reading-failure branch checks the reading lifecycle.
FloatingToolbar.content, lines 147–150 gives that pending result the whole pointer-revealed surface instead of the live action row. This disagrees with the method's own “if nothing live has taken the host since” rule and #134's active-work priority. Batch 5 head 159254985957681c7d6d665c0a934a415c339b8b still has the same pending-result gate; its timer/menu/accessory changes do not repair this case.
Resolve deferred results against the same live-state priority used by the truthful next action. Preserve the old recovery and its warning; do not fix this by clearing its error, retrying it or discarding its journal when Read begins. Make it reachable again after the newer work ends. Keep the one host and existing state owner.
Acceptance
- With an old synthetic dictation recovery present, Read preparing/playing/paused reveals Cancel generation, Pause or Resume respectively, with Stop reading reachable where applicable. The mark and revealed controls agree.
- Clicking the compact mark still only reveals; it never pauses, retries or starts an unrelated capture on that first click.
- The old recovery's text/audio/journal survive starting, pausing, resuming and stopping Read, with no replay. Its recovery controls remain reachable after Read ends.
- Cover the mixed state at the application-method/result-selection seam and through the production host. Separate “reading alone” and “recovery alone” snapshots do not cover this collision.
- Check the corresponding active-owner gate for narration and dictation with older deferred results; those combinations are regression scope, not additional native failures claimed by this report.
- Repeat the playing and paused pointer-reveal steps in signed installed Preview and record Copy build details. Record keyboard-entry behavior separately; it may take a different host path.
Child of #134 T4/C1/C8, found during its installed retest; indexed by #164. Searched existing open/recent recovery+toolbar and reading+toolbar requests; #152 owns geometry and #156 owns routine cues, neither this result-versus-live priority failure. No implementation or acceptance is claimed.
- Dominant language
- Swift
- Stars
- 0
- Forks
- 1
- Avg merge
- 8h 5m
- Merged PRs (30d)
- 215
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Ship-Work/workbench
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
documentation good first issue help wanted
Difficulty 2/5 Half a day Newbie friendliness 74/100
Ship-Work/workbench#29 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 55/100
Maintainers usually reply within 1 day
All issues in Ship-Work/workbench
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
swiftlang/swift-format#1312 ·
-
LiquidGlass / LiquidGlassContainer (iOS): padded content measured at the outer width and overflows by the paddingPossibly taken @aleclarson claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
NativeScript/NativeScript#11561 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 1/5 Under an hour Newbie friendliness 65/100
omacom/try-omarchy#402 ·
Maintainers usually reply within 1 day
-
area: build-and-ci S3: minor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
manaflow-ai/cmux#22595 · 1 comment ·
Maintainers usually reply within 1 day