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

Open
#600 0 comments 0 reactions 0 assignees View on GitHub
area:dictation bug help wanted P2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.