uttrflow / uttrflow/uttrflow-swift
The paste keystroke is key code 9, which is ⌘K rather than ⌘V on Dvorak and other layouts that move V
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
Every paste Uttrflow makes presses a fixed virtual key code:
```swift
// Sources/UttrflowInput/SystemInput.swift:77-78
/// Virtual key code for V, positional and so correct on any keyboard layout.
private static let vKeyCode: CGKeyCode = 9
```
`sendPaste()` (`SystemInput.swift:82-88`) posts that key with `.maskCommand`. Key code 9 is a *position*, the key that types V on a US QWERTY board. The comment has it backwards: an application matches ⌘ shortcuts on the **character** the current layout gives that key, not on its position. On a layout that puts another letter there, the posted event is a different shortcut:
- US Dvorak: key code 9 types `k`, so the "paste" is ⌘K (in many apps: insert link, clear, or open a search or switcher).
- Any other layout that moves V behaves the same way, with whatever letter sits at that position.
A layout with a separate ⌘ map (the "… QWERTY ⌘" variants) and non-Latin layouts where the system falls back to a Latin map for shortcuts probably still work, but nothing here checks.
The same key code is used on three paths:
- dictation's paste strategy (`PasteboardTextInsertionEngine`, `Sources/UttrflowInput/PasteboardTextInsertionEngine.swift:44`);
- the clipboard panel's text paste, through the same coordinator (`Sources/Uttrflow/AppDelegate.swift:1075-1087`);
- the clipboard panel's picture paste (`Sources/Uttrflow/AppDelegate.swift:1039`).
## Why it matters
The paste strategy is how most dictations reach browsers and web-runtime apps, because the Accessibility write does not work there (`Docs/insertion.md`). For someone on an affected layout, those dictations fire a different shortcut into the document. The paste confirmation then gives up, so the best case is "Inserted — not confirmed" with nothing inserted and the words left on the clipboard. The worst case is that ⌘K does something in the app.
## How to reproduce
Needs a real Mac. Nothing here sends keystrokes on the owner's machine.
1. System Settings › Keyboard › Input Sources: add and select "Dvorak".
2. Open a plain text editor window with some text selected.
3. `uttrflow-dev insert --via paste "hello"`, then click into the editor during the countdown.
4. Expected: `hello` replaces the selection. Suspected: ⌘K's action runs, and `uttrflow-dev` prints "no sign of the words".
Please report the layout, the app, and what happened. A second run under a Devanagari layout, a Cyrillic layout and "Dvorak – QWERTY ⌘" would settle the other cases.
## Acceptance criteria
- The key code for ⌘V is resolved from the layout the target will interpret it with: the key that produces `v` in the current keyboard layout, or in the ASCII-capable layout the system uses for shortcuts when the current source has no Latin letters. Key code 9 is only the fallback when no layout can be read.
- Text Input Sources is read on the main queue and cached, as `CompositionProbe` already does (`Docs/predict-ime.md`, "Text Input Sources must be called on the main queue"). It is refreshed on `kTISNotifySelectedKeyboardInputSourceChanged`.
- The lookup is a pure function from a layout table to a key code, tested for QWERTY, AZERTY, Dvorak and a layout with a ⌘ map. `Docs/input-synthetic-keystrokes.md` explains the rule, and the wrong comment at `SystemInput.swift:77` is corrected.
Contributor guide
Research direction
Start with Sources/UttrflowInput/SystemInput.swift, especially sendPaste(), then read Docs/input-synthetic-keystrokes.md and the Text Input Sources guidance in Docs/predict-ime.md. Compare the existing CompositionProbe approach and trace the paste paths through PasteboardTextInsertionEngine.swift and AppDelegate.swift. Done means layout-specific lookup tests cover QWERTY, AZERTY, Dvorak, and ⌘ maps, refresh behavior is covered, and the outdated comment is corrected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, swift
- Domain
- accessibility, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100