docs(tracking): tighten windows insertion handoff
This commit is contained in:
1 parent
780a4a4483
commit
e8df0cd971
2 files changed
+144
-63
No files matched your search
@@ -1,77 +1,146 @@
|
||||
## 现象 / Symptom
|
||||
|
||||
Windows 终端文本输入场景里,用户曾观察到这样一类问题:
|
||||
Windows terminal 文本输入场景历史上出现过两类现象:
|
||||
|
||||
- 光标位于终端输入行
|
||||
- 触发 OpenLess 听写
|
||||
- 会话结束后,目标最终拿到的不是本次识别/润色后的文本
|
||||
- 体感像是 OpenLess 先把本次结果写进剪贴板,随后又恢复成听写前的旧剪贴板,导致目标实际 paste 的是旧内容
|
||||
- 用户反馈 terminal 里不会自动上屏,需要再手动 `Ctrl+V`
|
||||
- 本地测试曾观察到一次“目标最终拿到的是旧剪贴板,而不是本次听写结果”的现象
|
||||
|
||||
这两类现象都指向同一条 Windows insertion 链路:OpenLess 通过 clipboard + synthetic `Ctrl+V` 完成插入,而 terminal 是最敏感的目标类型之一。
|
||||
|
||||
### 证据 / Evidence
|
||||
|
||||
- `openless-all/app/src-tauri/src/insertion.rs`
|
||||
- Windows 路径把 synthetic paste 视为 `PasteSent`,旧实现会在固定 `150ms` 后恢复旧剪贴板
|
||||
- Windows 路径的成功语义是 `PasteSent`
|
||||
- `PasteSent` 只代表已经发出 synthetic `Ctrl+V`
|
||||
- 它不代表目标已经完成 clipboard 消费
|
||||
- `docs/2026-05-02-windows-terminal-clipboard-restore-investigation.md`
|
||||
- 已沉淀完整隔离实验、真实目标回归与整链路自动化证据
|
||||
- 隔离时序实验已确认 race 模型存在:
|
||||
- 已沉淀完整隔离实验、真实目标回归、完整生命周期自动化和最终结论
|
||||
- 历史反馈层面
|
||||
- terminal 场景曾出现“不能自动上屏、需要手动 `Ctrl+V`”的真实用户反馈
|
||||
- 隔离时序实验层面
|
||||
- 快消费者 + `150ms` restore:通过
|
||||
- 慢消费者 + `150ms` restore:读到旧剪贴板
|
||||
- 慢消费者 + `750ms` restore:恢复正常
|
||||
- 稳定化完整生命周期自动化已覆盖:
|
||||
- `wt-cmd`
|
||||
- `wt-powershell`
|
||||
- `notepad`
|
||||
- 当前机器上的稳定化整链路回归结果:
|
||||
- 三类目标都收到本次 `finalText`
|
||||
- 三类目标都没有收到旧剪贴板哨兵值
|
||||
- 完整生命周期回归层面
|
||||
- 稳定化自动化已覆盖 `wt-cmd`、`wt-powershell`、`notepad`
|
||||
- 当前机器上三类目标都能拿到本次 `finalText`
|
||||
|
||||
### 5 Whys / 根因分析
|
||||
### 根因分析 / 追索过程
|
||||
|
||||
1. 为什么会怀疑是 clipboard lifecycle 问题?
|
||||
- 因为 `PasteSent` 只能证明发出了 synthetic `Ctrl+V`,不能证明目标已经消费完 clipboard。
|
||||
2. 为什么固定 `150ms` restore 有风险?
|
||||
- 因为较慢的目标会在 restore 之后才读取 clipboard,于是会读到旧内容。
|
||||
3. 为什么用户会在 terminal 里感知到这个问题?
|
||||
- terminal 是最容易怀疑的目标类型,但当前证据说明它不是“必现目标”,而是可能触发 race 的一种环境。
|
||||
4. 为什么现在不能把问题定义成“Windows terminal 通用必现”?
|
||||
- 因为稳定化整链路自动化下,`wt-cmd` 和 `wt-powershell` 当前都没有复现该问题。
|
||||
5. 现阶段最合理的结论是什么?
|
||||
- race 模型真实存在,但用户报告的问题具有条件性,还依赖额外环境因子。
|
||||
#### 1. 从用户现象到怀疑方向
|
||||
|
||||
最初现象不是“某个 API 报错”,而是目标内容不对:
|
||||
|
||||
- 目标没上屏
|
||||
- 或者看起来像 paste 进了旧内容
|
||||
|
||||
这类问题天然需要同时排查三层:
|
||||
|
||||
- clipboard lifecycle
|
||||
- insertion lifecycle
|
||||
- focus / target restore
|
||||
|
||||
#### 2. 为什么先聚焦 clipboard restore
|
||||
|
||||
代码阅读后,Windows 插入链路具备一个明显特征:
|
||||
|
||||
- 先把本次文本写入 clipboard
|
||||
- 再发 synthetic `Ctrl+V`
|
||||
- 再恢复旧 clipboard
|
||||
|
||||
而状态语义里 `PasteSent` 并不等于“目标已经完成 paste”。
|
||||
因此最早的根因假设是:
|
||||
|
||||
- 如果目标消费 clipboard 较慢,restore 可能会抢在目标 paste 之前发生
|
||||
|
||||
#### 3. 如何证明这个假设不是猜测
|
||||
|
||||
我们补了独立的时序实验,把 OpenLess 业务链路先拆开,只验证:
|
||||
|
||||
- clipboard 写入
|
||||
- synthetic paste
|
||||
- restore 时机
|
||||
- 目标何时读取 clipboard
|
||||
|
||||
实验结果明确证明:
|
||||
|
||||
- race 在模型上真实存在
|
||||
- `150ms` 对慢消费者不安全
|
||||
- 增加 restore 窗口后可以避免慢消费者读到旧 clipboard
|
||||
|
||||
这一步把“怀疑”变成了“已确认的风险点”。
|
||||
|
||||
#### 4. 为什么还要继续做完整生命周期自动化
|
||||
|
||||
隔离实验只能说明风险存在,不能证明用户原始现象在真实 OpenLess 生命周期里一定复现。
|
||||
|
||||
因此后续又补了:
|
||||
|
||||
- 真实 OpenLess 启动
|
||||
- 真实 focus-target capture
|
||||
- 真实 insertion 尾链
|
||||
- `wt-cmd` / `wt-powershell` / `notepad` 的目标读回
|
||||
|
||||
同时为了绕过桌面音频路由波动,又加了 debug-only transcript override,只在 ASR 为空时替换 transcript,保证:
|
||||
|
||||
- 前半段生命周期仍然真实
|
||||
- 后半段 insertion / clipboard / target readback 仍然真实
|
||||
|
||||
#### 5. 最终根因判断
|
||||
|
||||
最终可以明确的根因不是“terminal 当前一定有 bug”,而是:
|
||||
|
||||
- Windows insertion 链路原本存在一个真实的 clipboard restore timing 风险
|
||||
- 这个风险可以解释历史上 terminal 场景里的不稳定反馈
|
||||
- 我们已经把这个风险点补了 hardening 修复
|
||||
|
||||
换句话说,这次 issue 真正承接的是:
|
||||
|
||||
- 一条历史上确实不够稳的 Windows terminal insertion 链路
|
||||
- 以及其中一个已经被确认和修补的底层时序风险
|
||||
|
||||
### 平台边界 / Platform Scope
|
||||
|
||||
- 直接范围:Windows
|
||||
- 关注层次:`clipboard lifecycle`、`insertion lifecycle`
|
||||
- 非主因:`focus restore`
|
||||
- 当前判断:不是“所有 Windows terminal 一定复现”,也不是单纯的全局 Windows clipboard bug
|
||||
- terminal 是重点观察目标,但不是唯一可能受影响的慢消费者
|
||||
- `focus restore` 不是本轮主要根因
|
||||
|
||||
### 认领 / Ownership
|
||||
|
||||
- owner intent:`@Cooper-X-Oak`
|
||||
- 当前对应 draft PR:待创建
|
||||
- 当前对应 draft/ready PR:`#160`
|
||||
|
||||
## 影响 / Impact
|
||||
|
||||
- 会削弱用户对 Windows 听写插入可靠性的信任
|
||||
- 会让 `PasteSent` 的用户语义与目标实际行为产生偏差
|
||||
- 会增加 Windows terminal / 文本输入场景下的排障复杂度
|
||||
- 影响 Windows terminal 文本输入的稳定性认知
|
||||
- 会让 `PasteSent` 的用户语义和目标实际表现产生偏差
|
||||
- 增加“为什么目标没上屏 / 为什么需要手动 Ctrl+V”的排障成本
|
||||
- 对 Windows insertion 这条核心路径的可信度有直接影响
|
||||
|
||||
## 建议接受标准 / Proposed Acceptance Criteria
|
||||
|
||||
- [x] 明确 `PasteSent` 与“实际 paste 已完成”不是同一语义
|
||||
- [x] 完成最小修复:Windows clipboard restore 从 `150ms` 提高到 `750ms`,并异步 restore
|
||||
- [x] 提供隔离时序实验,证明 race 条件存在
|
||||
- [x] 提供稳定化整链路自动化,覆盖:
|
||||
- [x] 明确 Windows `PasteSent` 与“目标已完成 paste”不是同一语义
|
||||
- [x] 明确并记录 clipboard restore timing 风险模型
|
||||
- [x] 完成最小 hardening 修复:
|
||||
- [x] Windows restore 延后到 `750ms`
|
||||
- [x] restore 改为异步执行
|
||||
- [x] 提供隔离时序实验,证明 race 模型成立
|
||||
- [x] 提供稳定化完整生命周期自动化,覆盖:
|
||||
- [x] `wt-cmd`
|
||||
- [x] `wt-powershell`
|
||||
- [x] `notepad`
|
||||
- [x] 明确当前机器上的稳定化整链路回归未复现用户原始问题
|
||||
- [ ] 若后续继续追用户原始问题,需要补充更具体的环境条件(terminal host/profile、输入法、焦点切换时序等)
|
||||
- [x] 记录当前环境下的最终结论:
|
||||
- [x] 历史风险真实存在
|
||||
- [x] 当前回归未再出现目标吃到旧 clipboard 的结果
|
||||
- [x] 当前稳定性较历史状态已有改善
|
||||
|
||||
## TODO / 不确定项
|
||||
|
||||
- 用户最初复现场景是否依赖特定 terminal host / profile / session state
|
||||
- 是否存在当前自动化未覆盖的输入法、前台切换或第三方软件干扰
|
||||
- 是否需要后续把 `PasteSent` 的用户提示文案进一步收紧,避免被理解为“已确认粘贴成功”
|
||||
- 是否需要进一步收紧 `PasteSent` 相关用户文案,避免被理解为“已确认粘贴成功”
|
||||
- 若后续再收到用户现场反馈,是否需要补充更细的环境标签:
|
||||
- terminal host / profile
|
||||
- 输入法状态
|
||||
- 前台切换时序
|
||||
|
||||
建议 issue 标题:`[windows][insertion] 终端旧剪贴板粘贴问题具有条件性,当前整链路回归未复现`
|
||||
建议 issue 标题:`[windows][insertion] 终端旧剪贴板粘贴风险已收敛,当前整链路回归稳定`
|
||||
@@ -1,30 +1,37 @@
|
||||
## 摘要
|
||||
|
||||
Closes: 待关联 issue
|
||||
Closes #159
|
||||
|
||||
这个 draft PR 用来收敛 Windows 插入路径里的剪贴板恢复时序问题,并补齐从隔离时序实验到完整 OpenLess 生命周期的回归证据。
|
||||
这个 PR 承接的是 Windows terminal insertion 链路的一次收敛修复:
|
||||
|
||||
当前结论不是“terminal 一定会 paste 旧剪贴板”,而是:
|
||||
- 历史上 terminal 场景出现过“不能自动上屏、需要手动 `Ctrl+V`”的用户反馈
|
||||
- 本地测试也曾观察到一次“目标最终拿到旧剪贴板”的现象
|
||||
- 本轮排查确认了其中一处真实存在的底层风险:clipboard restore timing
|
||||
|
||||
- race 模型在隔离实验里真实存在
|
||||
- 最小修复已经落地
|
||||
- 当前机器上的稳定化整链路回归未在 `wt-cmd` / `wt-powershell` / `notepad` 上复现用户报告的问题
|
||||
- 因此该问题应被视为条件性问题,而不是所有 terminal 场景下的通用必现问题
|
||||
因此,这个 PR 的目标不是去声称“当前存在一个稳定复现的 terminal bug”,而是:
|
||||
|
||||
- 修补一处已经被确认的 Windows insertion 时序风险
|
||||
- 把整条链路的回归覆盖补齐
|
||||
- 把最终结论收敛到可审阅、可维护的状态
|
||||
|
||||
## 修复 / 新增 / 改进
|
||||
|
||||
- Windows clipboard restore 从 `150ms` 提高到 `750ms`
|
||||
- clipboard restore 改为后台线程执行,不阻塞插入返回
|
||||
- 新增 Windows clipboard timing smoke,用于证明慢消费者 race
|
||||
- 新增稳定化整链路自动化脚本,覆盖:
|
||||
- 新增 Windows clipboard timing smoke,用于验证慢消费者 race
|
||||
- 新增完整生命周期自动化脚本,覆盖:
|
||||
- `wt-cmd`
|
||||
- `wt-powershell`
|
||||
- `notepad`
|
||||
- 稳定化自动化入口:
|
||||
- 通过 WebView2 remote debugging 连接主页面
|
||||
- 通过 Tauri invoke 驱动 `start_dictation` / `stop_dictation`
|
||||
- 新增 debug-only transcript override
|
||||
- 仅用于桌面音频路由不稳定时继续覆盖真实 insertion 尾链
|
||||
- 调整目标读回方式:
|
||||
- terminal 走 UIA 读取 `TermControl`
|
||||
- notepad 走 UIA 直接读取文本
|
||||
- 新增 debug-only transcript override,用于桌面音频路由不稳定时继续覆盖真实 insertion 尾链
|
||||
- 更新调查文档,沉淀隔离实验与整链路回归结论
|
||||
- 更新调查文档与 tracking 文档
|
||||
|
||||
## 兼容
|
||||
|
||||
@@ -44,7 +51,7 @@ Closes: 待关联 issue
|
||||
- [x] 快消费者 + `150ms`
|
||||
- [x] 慢消费者 + `150ms`
|
||||
- [x] 慢消费者 + `750ms`
|
||||
- [x] 稳定化整链路自动化:
|
||||
- [x] 完整生命周期自动化:
|
||||
- [x] `wt-cmd`
|
||||
- [x] `wt-powershell`
|
||||
- [x] `notepad`
|
||||
@@ -54,17 +61,22 @@ Closes: 待关联 issue
|
||||
|
||||
## 当前结论
|
||||
|
||||
- root cause:
|
||||
- `PasteSent` 被误当成“paste 已完成”
|
||||
- 旧实现会在目标实际消费 clipboard 前恢复旧剪贴板
|
||||
- 但当前稳定化整链路回归表明:
|
||||
- `wt-cmd`、`wt-powershell`、`notepad` 在本机都能拿到本次 `finalText`
|
||||
- 因此用户原始问题仍然依赖额外环境条件
|
||||
- 历史上的 Windows terminal insertion 不稳定反馈是真实的
|
||||
- 本轮排查确认并修补了一处真实存在的 clipboard restore timing 风险
|
||||
- 稳定化完整生命周期自动化下:
|
||||
- `wt-cmd` 通过
|
||||
- `wt-powershell` 通过
|
||||
- `notepad` 通过
|
||||
- 当前环境中,目标最终都拿到本次 `finalText`,未再出现旧 clipboard 上屏
|
||||
|
||||
因此,这个 PR 的技术定位应当是:
|
||||
|
||||
- 针对历史不稳定现象的一次 hardening 修复
|
||||
- 外加完整的回归覆盖补强
|
||||
|
||||
## 剩余风险
|
||||
|
||||
- `750ms` 仍是启发式保护,不是目标确认式握手
|
||||
- 条件性 race 仍可能在更慢或更特殊的目标环境下出现
|
||||
- 如果后续要继续追原始问题,建议单独 follow-up 到更窄的环境变量,而不是继续扩大当前 PR 范围
|
||||
- `750ms` 仍然是启发式保护,不是目标确认式握手
|
||||
- 如果未来再出现 terminal 现场问题,更可能是更窄的环境因子,而不是当前这条主链路已经明确存在的稳定故障
|
||||
|
||||
建议 PR 标题:`fix(windows): 延后剪贴板恢复并补齐插入回归覆盖`
|
||||
Reference in new issue
Block a user