uttrflow / uttrflow/uttrflow-swift

Hover-revealed row buttons stay invisible when they have keyboard focus, including Delete

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

Description

## What happens

Four row types in the main window hide their buttons with `.opacity(0)` until the pointer is over the row. The comments say this is so a keyboard or VoiceOver can still reach the buttons. It does let focus reach them, but nothing makes them visible when focus arrives, because visibility depends only on `isHovered`:

- `Sources/Uttrflow/Main/HomePageView.swift:135-137`: the Open button on each recent dictation.
- `Sources/Uttrflow/Main/DictationPageView.swift:118-138`: each row's icon buttons and its More menu.
- `Sources/Uttrflow/Main/DictionaryPageView.swift:87-91`: Edit, Retire and Delete on each word.
- `Sources/Uttrflow/Main/SnippetsPageView.swift:74-78`: Edit and Delete on each snippet.

A SwiftUI view at opacity 0 still takes keyboard focus, and its focus ring is drawn at the same opacity. With Full Keyboard Access on, Tab moves onto buttons the user can't see, including Delete.

VoiceOver is fine, because the rows also expose the actions through `rowActions` (`Sources/Uttrflow/Main/MainPieces.swift:519-529`). Sighted keyboard users are the ones affected.

## Why it matters

A keyboard-only user tabbing through the Dictionary sees focus vanish for three stops per row, then reappear somewhere else. They can press Space on an invisible Delete without knowing it's there. This affects people who can't use a pointer, and anyone who has turned on Full Keyboard Access.

## How to reproduce

1. Turn on System Settings, Keyboard, Keyboard navigation.
2. Open the Dictionary page with a few words, click the first row's word so the window is key, then press Tab repeatedly. Focus disappears while it passes over each row's hidden buttons.

## Acceptance criteria

- A row's buttons are visible while the pointer is over the row **or** while any of its buttons has keyboard focus. `@FocusState` on the row, or `.onFocusChange` on each button feeding the same flag as `onHover`, would do.
- Pointer behaviour is unchanged.
- The same fix applies to all four rows, ideally in one shared modifier next to `rowActions` in `MainPieces.swift`, so the next row type gets it for free.

Contributor guide

Open the contributing guide

Research direction

Start with the shared row-actions area in Sources/Uttrflow/Main/MainPieces.swift:519-529, then inspect the opacity and hover handling in HomePageView.swift, DictationPageView.swift, DictionaryPageView.swift, and SnippetsPageView.swift. Reproduce with Keyboard navigation enabled and verify each row's buttons appear on pointer hover or keyboard focus while pointer behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.