Skip to content

Windows/Linux 插入失败时听写文本丢失:增加'插入失败保留剪贴板'开关 #111

Description

@appergb

问题

insertion.rs::do_paste 在 Windows/Linux 上的逻辑是:

  1. 备份当前剪贴板
  2. 把听写结果写入剪贴板
  3. simulate_paste() 模拟 Ctrl+V
  4. 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 找回;代价是用户原剪贴板被永久覆盖。

让用户根据自己的工作模式选。重度听写用户应该开;普通用户保持默认。

实现要点

  1. Preferences 增字段 `restore_clipboard_after_paste: bool`(默认 true 保留现行行为)
  2. `insertion.rs::do_paste` 在非 macOS 路径根据该字段决定是否调 `maybe_restore_clipboard`
  3. 前端 Settings → 录音 section 加 toggle

触发场景的复现路径

  1. 在浏览器地址栏输入框对焦
  2. 按快捷键开始听写
  3. 说话期间手动点击桌面或别的窗口(让浏览器失焦)
  4. 停止听写
  5. 此时已无聚焦的可编辑控件,simulate_paste 仍返回 OK,但内容没进任何输入框
  6. 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` 实现)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions