问题
insertion.rs::do_paste 在 Windows/Linux 上的逻辑是:
- 备份当前剪贴板
- 把听写结果写入剪贴板
simulate_paste() 模拟 Ctrl+V
- 150ms 后调用
maybe_restore_clipboard(restore_plan) 恢复用户原剪贴板内容
`simulate_paste()` 只能确认 Ctrl+V 已发送,无法确认目标 app 真的接收了。如果目标处于:
- 失焦
- 不可编辑(只读区、终端只读模式、PDF viewer 等)
- 忙碌不响应粘贴
- 焦点已切走(用户在听写完瞬间切了 app)
那么:simulate_paste() 返回 OK,前端 UI 显示"已插入",但目标 app 没收到 → 150ms 后剪贴板恢复成用户原内容 → 听写文本永久丢失,连手动 Ctrl+V 找回的机会都没有。
这违反 CLAUDE.md 里写的核心契约:"用户的话不会丢"。
影响范围
- Windows / Linux:受影响
- macOS:无影响(走 AX focused-element 直写,不依赖剪贴板)
提议方案
在"录音"设置下加一个开关:「插入失败保留剪贴板」(默认关)
- 关(当前行为):粘贴后恢复用户原剪贴板。优点:不污染用户工作流;缺点:插入失败时听写文本永久丢失。
- 开:粘贴后不恢复,听写文本留在剪贴板里。用户随时能 Ctrl+V 找回;代价是用户原剪贴板被永久覆盖。
让用户根据自己的工作模式选。重度听写用户应该开;普通用户保持默认。
实现要点
Preferences 增字段 `restore_clipboard_after_paste: bool`(默认 true 保留现行行为)
- `insertion.rs::do_paste` 在非 macOS 路径根据该字段决定是否调 `maybe_restore_clipboard`
- 前端 Settings → 录音 section 加 toggle
触发场景的复现路径
- 在浏览器地址栏输入框对焦
- 按快捷键开始听写
- 说话期间手动点击桌面或别的窗口(让浏览器失焦)
- 停止听写
- 此时已无聚焦的可编辑控件,simulate_paste 仍返回 OK,但内容没进任何输入框
- 150ms 后剪贴板恢复 → 听写文本丢失
相关代码
- `openless-all/app/src-tauri/src/insertion.rs:118`(`maybe_restore_clipboard` 的 unconditional 调用)
- `openless-all/app/src-tauri/src/insertion.rs:123-128`(非 macOS `maybe_restore_clipboard` 实现)
问题
insertion.rs::do_paste在 Windows/Linux 上的逻辑是:simulate_paste()模拟 Ctrl+Vmaybe_restore_clipboard(restore_plan)恢复用户原剪贴板内容`simulate_paste()` 只能确认 Ctrl+V 已发送,无法确认目标 app 真的接收了。如果目标处于:
那么:simulate_paste() 返回 OK,前端 UI 显示"已插入",但目标 app 没收到 → 150ms 后剪贴板恢复成用户原内容 → 听写文本永久丢失,连手动 Ctrl+V 找回的机会都没有。
这违反 CLAUDE.md 里写的核心契约:"用户的话不会丢"。
影响范围
提议方案
在"录音"设置下加一个开关:「插入失败保留剪贴板」(默认关)
让用户根据自己的工作模式选。重度听写用户应该开;普通用户保持默认。
实现要点
Preferences增字段 `restore_clipboard_after_paste: bool`(默认 true 保留现行行为)触发场景的复现路径
相关代码