Skip to content

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

@appergb

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` 实现)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingwindowsWindows-specific issue

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions