Skip to content

fix(insertion): make Windows/Linux paste shortcut configurable (#360)#377

Merged
appergb merged 3 commits into
betafrom
fix/issue-360-paste-shortcut
May 10, 2026
Merged

fix(insertion): make Windows/Linux paste shortcut configurable (#360)#377
appergb merged 3 commits into
betafrom
fix/issue-360-paste-shortcut

Conversation

@appergb
Copy link
Copy Markdown
Collaborator

@appergb appergb commented May 9, 2026

User description

Summary

  • [area] #360:模拟粘贴硬编码 Ctrl+V,kitty / alacritty / wezterm / gnome-terminal / foot 等 Linux 终端只接受 Ctrl+Shift+V,听写文本只剩在剪贴板里,看起来像"什么也没插入"。
  • 新增 PasteShortcut 枚举(CtrlV / CtrlShiftV / ShiftInsert)作为 UserPreferences 字段,串到 simulate_paste 的 enigo 路径;Settings → 录音 多了"模拟粘贴快捷键"一行,仅在非 macOS 显示(macOS 走 AX 直写不受影响)。
  • 默认 CtrlV 与历史行为一致,老配置文件没有 pasteShortcut 字段时 #[serde(default)] 回退到默认值——不破坏既有用户。

Why this scope

issue 里用户提到两点:(1) 加粘贴方式配置,(2) 按前台程序自动检测。前者满足验收标准;后者在 Linux 上实际很难做(Wayland 多数情况下根本拿不到前台窗口的 class,X11 要再依赖 xprop/xdotool)。本 PR 只做 (1)——一个全局选择器,3 个预设覆盖现实里能遇到的所有终端。如果以后有需求再加自动检测。

Files changed

  • src-tauri/src/types.rsPasteShortcut 枚举 + UserPreferences.paste_shortcut(默认 CtrlV),串接 wire 类型 / Default / Deserialize
  • src-tauri/src/insertion.rssimulate_paste(shortcut) 走新 paste_keys() helper;insert / insert_via_clipboard_fallback 三平台签名都带 paste_shortcut(macOS 忽略)。modifier 按下/释放严格对称,中途失败反向释放避免卡键。
  • src-tauri/src/coordinator.rs — 从 prefspaste_shortcut,串到三个 insert 调用点 + Windows IME 兜底链。
  • 前端 src/lib/types.tssrc/lib/ipc.tssrc/lib/stylePrefs.test.tssrc/pages/Settings.tsx
  • i18n:zh-CNzh-TWenjako 各加 5 个 key。

Test plan

  • cargo test --manifest-path src-tauri/Cargo.toml --lib181 passed, 0 failed,新增 3 个测试:
    • paste_shortcut_defaults_to_ctrl_v — 默认值 + 老配置反序列化都回到 CtrlV
    • paste_shortcut_round_trips_explicit_values — 三种取值的 JSON 互转
    • paste_keys_match_configured_shortcut — 枚举 → enigo Key 映射(cfg(not(macos)) 门控)
  • cargo check --manifest-path src-tauri/Cargo.toml(host = aarch64-apple-darwin)干净
  • npm run build(tsc + vite build)干净
  • 手动验证:macOS 上看 Settings → 录音 看不到这一行(capability.adapter !== 'macEventTap' 门控)
  • 手动验证:Linux + kitty 上选 Ctrl+Shift+V 后听写能粘进去
  • 手动验证:Windows + Windows Terminal 上 CtrlV / CtrlShiftV 都能工作
  • 手动验证:老配置文件(无 pasteShortcut 字段)启动后不报错、行为不变

Linux cross-target check 在我本机被 x11 crate 的 pkg-config sysroot 卡住——CI ubuntu-22.04 runner 有 sysroot,应该没问题;新加的代码 cfg 门控完全镜像现有的 cfg(target_os = "windows") 模式,没引入新形态。

Closes #360


PR Type

Bug fix, Enhancement, Tests


Description

  • Add PasteShortcut config for Windows/Linux paste key ([area] #360)

    • New enum PasteShortcut with CtrlV, CtrlShiftV, ShiftInsert
    • UserPreferences.paste_shortcut field (default CtrlV, backward compatible)
  • Refactor simulate_paste to handle multiple modifiers safely

    • paste_keys() maps shortcut to modifiers+primary key
    • Press modifiers in order, click primary, release in reverse; partial release on error
    • Fix DoubleEndedIterator compile error on Linux with slice indexing
  • Plumb shortcut setting through coordinator → insertion call chain

    • insert, insert_via_clipboard_fallback, Windows IME fallback paths all carry the preference
    • macOS path keeps consistent signature but ignores the value
  • Add UI selector under Settings → Recording (non‑macOS only)

    • i18n labels for EN, JA, KO, ZH‑CN, ZH‑TW
    • Frontend types, IPC mock, style test mock updated
  • Unit tests for default value, deserialization round‑trip, and key mapping


Diagram Walkthrough

flowchart LR
  A["Settings UI (select)"] -- "updates" --> B["UserPreferences.paste_shortcut"]
  B -- "read by" --> C["Coordinator end_session"]
  C -- "calls with shortcut" --> D["TextInserter::insert / fallback"]
  D -- "invokes" --> E["simulate_paste(shortcut)"]
  E -- "maps via" --> F["paste_keys()"]
  F -- "produces" --> G["(modifiers, primary)"]
  G -- "feeds" --> H["enigo key press/release"]
Loading

File Walkthrough

Relevant files
Enhancement
6 files
types.rs
Define PasteShortcut enum and add to preferences                 
+50/-0   
insertion.rs
Refactor simulate_paste for configurable shortcut               
+103/-21
coordinator.rs
Thread paste_shortcut through Windows IME and fallback paths
+7/-3     
dictation.rs
Pass paste_shortcut from prefs to insert calls                     
+3/-1     
types.ts
Add PasteShortcut type to UserPreferences interface           
+11/-0   
ipc.ts
Update mock settings with new pasteShortcut field               
+1/-0     
Configuration changes
1 files
Settings.tsx
Add paste shortcut selector UI (non‑macOS)                             
+19/-0   
Tests
1 files
stylePrefs.test.ts
Include pasteShortcut in test preferences mock                     
+1/-0     
Documentation
5 files
en.ts
English translations for paste shortcut setting                   
+5/-0     
ja.ts
Japanese translations for paste shortcut setting                 
+5/-0     
ko.ts
Korean translations for paste shortcut setting                     
+5/-0     
zh-CN.ts
Simplified Chinese translations for paste shortcut setting
+5/-0     
zh-TW.ts
Traditional Chinese translations for paste shortcut setting
+5/-0     

模拟粘贴硬编码 Ctrl+V,kitty / alacritty / wezterm / gnome-terminal /
foot 等 Linux 终端只接受 Ctrl+Shift+V,听写文本只剩在剪贴板里,看起来
像"什么也没插入"。issue #360 报告了 kitty 这个具体场景。

新增 `PasteShortcut` 枚举(`CtrlV` / `CtrlShiftV` / `ShiftInsert`)作为
UserPreferences 字段,串到 simulate_paste 的 enigo 路径。Settings →
录音 多了"模拟粘贴快捷键"一行,仅在非 macOS 显示(macOS 走 AX 直写
不受影响)。默认 `CtrlV` 与历史行为一致,老配置文件没有 pasteShortcut
字段时 `#[serde(default)]` 回退到默认值,不破坏既有用户。

涵盖:
- types.rs:新枚举 + 字段 + UserPreferencesWire 串接
- insertion.rs:simulate_paste(shortcut),paste_keys 把枚举拆成
  (modifiers, primary),按下/释放严格对称,中途出错也反向释放避免卡键
- coordinator.rs:从 prefs 读取,串到三个 insert 调用点 + Windows IME 链
- 前端 TS 类型 / Settings 选择器 / 5 种语言 i18n
- 单元测试:默认 CtrlV、JSON 反序列化、paste_keys 三种映射

cargo test --lib 全部 181 通过;npm run build 干净。
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

… release

`TakeWhile<Iter, _>` 不实现 `DoubleEndedIterator`,所以 `.take_while(..).rev()`
在 Linux target 上编译不过(macOS host 因为整段 cfg(not(macos)) 没编译,所以
之前 cargo check 没暴露)。改用 `modifiers[..pressed].iter().rev()`:切片的
Iter 实现 DoubleEndedIterator,可以安全 `.rev()`。

顺手简化错误恢复路径:用一个 `first_err` 累加器,press → click → release
三段任何一段先报错都先记下来,最后一次性返回。语义跟原版 simulate_paste
对齐,不留卡键。

cargo test --lib 仍然 181 passed。
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

PR Reviewer Guide 🔍

(Review updated until commit 26e31f2)

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

360 - Partially compliant

Compliant requirements:

  • 修复无法在kitty等使用Ctrl+Shift+V的终端中输入文字的问题(通过新增全局粘贴快捷键配置解决)
  • 添加粘贴方式的配置

Non-compliant requirements:

  • 根据当前前台程序针对性的配置和处理(未实现按程序自动检测粘贴快捷键)

Requires further human verification:

  • 可以在各种terminal中插入文字(需实际在kitty、alacritty、wezterm等终端中测试配置后的插入效果)
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

Persistent review updated to latest commit 644dc63

…hortcut

# Conflicts:
#	openless-all/app/src-tauri/src/coordinator.rs
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 26e31f2

@appergb appergb merged commit ff5e8f8 into beta May 10, 2026
4 checks passed
pull Bot pushed a commit to yimmy23/openless that referenced this pull request May 10, 2026
10 PRs landed on beta this cycle:
- Open-Less#377 paste shortcut configurable (issue Open-Less#360)
- Open-Less#386 TS UserPreferences updateChannel alignment
- Open-Less#387 focus_target leak on Processing-phase cancel
- Open-Less#388 [严重] MacHotkeyAdapter::shutdown stops CFRunLoop + tap
- Open-Less#389 emit_capsule window.show/hide off audio thread
- Open-Less#390 QA / dictation hotkey routing race
- Open-Less#391 audio-mute spawn_blocking (async hygiene)
- Open-Less#392 hotkey supervisor + global dispatcher exit signal
- Open-Less#393 post-audit logic-review hotfixes (QA mute .await + focus_target Processing branch)
- Open-Less#394 in-process credentials cache (kills repeated Keychain prompts)

Bump 4 files: package.json, tauri.conf.json, Cargo.toml, Cargo.lock.
@appergb appergb deleted the fix/issue-360-paste-shortcut branch May 10, 2026 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[area]

1 participant