Skip to content

[Windows][feature] 新增「始终使用 SendInput」开关,避免听写后输入法无法还原 #733

Description

@HKLHaoBin

背景

Windows 听写 session 开始时,Coordinator 会调用 windows_ime.prepare_session() 临时切换到 OpenLess TSF 输入法;识别结束后通过 restore_session 还原用户原输入法。

部分用户反馈:听写结束后输入法仍停留在 OpenLess,或无法切回原中文输入法(与 #469 同类问题,修复后仍有个体差异)。

现有设置项 「允许非 TSF 兜底」allowNonTsfInsertionFallback)只在 TSF 提交失败之后才走 SendInput(KEYEVENTF_UNICODE)不会跳过 session 开头的输入法切换。即使用户已开启「流式输入」(Windows 上逐字插入已是 SendInput),begin_session 仍会切 TSF。

需求

新增 Windows 专用偏好开关(opt-in,默认关闭):

  • 前端字段:windowsSendInputInsertionOnly
  • Rust 字段:windows_sendinput_insertion_only

开启后的行为

阶段 行为
begin_session 跳过 prepare_session(),不切 OpenLess TSF
一次性插入 直接 insert_via_non_tsf_fallback / insert_via_unicode_keystrokes
流式插入 继续 SendInput Unicode,全程不切输入法
失败兜底 仍受「允许非 TSF 兜底」控制(SendInput 失败后是否复制剪贴板)

关闭时(默认)

保持现有 TSF 优先 → SendInput/剪贴板兜底链路不变。

设置 UI

设置 → 录音与输入 → 插入与剪贴板(仅 Windows):

  • 开关:始终使用 SendInput(不切换输入法)
  • 位置:「允许非 TSF 兜底」上方
  • 说明:部分应用(如 Word)可能不如 TSF 稳定

实现要点(供后续 PR)

  • types.rs:新增偏好字段 + serde default false
  • dictation.rsbegin_session_as 条件跳过 prepare;end_session 插入分支
  • coordinator.rsinsert_via_non_tsf_fallback 供 dictation 调用;dictation_error_code 在 SendInput-only 模式下不报 windowsImeTsfRequired
  • RecordingInputSection.tsx + 5 语言 i18n

不在范围

  • Android IME(仍走 accessibility / clipboard)
  • 修改 OpenLess TSF DLL 或 restore 逻辑本身
  • 将默认值改为 true
  • 合并「允许非 TSF 兜底」与新区块(语义不同:主路径 vs 失败后兜底)

测试计划

  1. 开关关:听写开始切 OpenLess IME,结束后还原(与现版一致)
  2. 开关开:听写开始/结束任务栏输入法不变;记事本可正常插入
  3. 开关开 + 关闭「非 TSF 兜底」:SendInput 失败时不复制剪贴板
  4. 流式输入 + 开关开:全程不切输入法
  5. 单元测试:windows_sendinput_insertion_only default/round-trip;SendInput-only 时 dictation_error_code 不返回 windowsImeTsfRequired

关联

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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