Files
StellarX-kaifa/开发记录/BUG/BUG-20261006-0002-阶段0B夹具缺少IME锚点且组合键规则无法命中.md
T
2026-10-07 04:09:36 +08:00

58 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BUG-20261006-0002
> 适用场景:记录问题本身,不展开完整修复方案。修复内容写入对应的 Fix 文档。
## 基本信息
- ID: BUG-20261006-0002
- 标题: 阶段 0B 夹具缺少 IME 锚点、组合态 Escape 规则无法命中且采集存在锁竞争丢失
- 状态:已修复并完成微软拼音与搜狗人工验证
- 严重性:S2
- 优先级:P0
- 模块: 阶段 0B / InputProbe / UiFixture / IMM32
- 版本 / 分支: `master`,0B 开发中未提交改动
- 环境: Windows 11、EasyX 25.9.10、ANSI HWND、CP936、DPI-unaware 96 DPI、微软拼音与搜狗人工探测
- 发现人: 用户真实 IME 人工探测 + 日志复核
- 关联 Fix ID: Fix-BUG-20261006-0002
## 问题描述
- 现象 1: `input-consume-probe` 窗口中开始中文组合后,微软拼音和搜狗候选 UI 都出现在桌面左下角,而不是探测窗口内。
- 现象 2: 人工按一次 Escape 后,配置为 `WM_KEYDOWN + VK_ESCAPE + ComposingOnly` 的规则命中数为 0。
- 现象 3: 本轮日志出现 3 条 `wndproc_lock_contention`,`recordsLost=3`,分析结果为 `inconclusive_capture_loss`。
- 影响范围: 0B-3 的真实 IME A/B 无法形成有效证据;如果误把该运行当成消费行为结果,可能把夹具缺陷错误归因于 IME 或 WndProc 消费策略。
- 期望结果: 夹具使用与 0C 同源的客户区 anchor 定位候选 UI;规则匹配 WndProc 实际可观察的原生键三元组;探测器自身不因 flush 锁竞争丢记录。
## 复现信息
- 前置条件: 运行 0B Composition 人工探针,选择微软拼音或搜狗。
- 复现步骤:
1. 点击 `StellarX.UI.input-consume-probe`,输入固定非敏感串 `ceshi`。
2. 观察候选 UI 位于桌面左下角。
3. 在组合态按一次 Escape 并关闭窗口。
4. 分析 JSONL 中的原生键和 `records_lost`。
- 复现概率:旧夹具在本轮稳定复现
- 证据目录: `TestResults/InputProbe/0B/20261006-140720-218-96b7392e-548a-44cf-9343-5d1449bf73fa`
- 人工截图: `manual-evidence/composition-candidate-position-wrong.png`
- 截图 SHA-256: `61E4A04CEE329B13BB22C919DC233A07ABF3EF6C298E64FB7B6E70F6D60DE0A3`
## 初步分析
- 候选位置根因: 0B 夹具没有调用 `ImmSetCompositionWindow` 或 `ImmSetCandidateWindow`,却要求操作者按 0C 基线判断位置;两套环境实际上不可比。
- 规则根因: 组合态按 Escape 时,WndProc 记录为 `WM_KEYDOWN + VK_PROCESSKEY(229) + scanCode 1`;IME 结束后才出现 `WM_KEYUP + VK_ESCAPE(27)`。旧规则错误假设 KeyDown 仍保留逻辑 VK。
- API 时机边界: 微软文档说明 `ImmGetVirtualKey` 只能在应用调用 `TranslateMessage` 前恢复原 VK。当前钩子已经在 EasyX WndProc,不能可靠恢复该键,只能记录真实原生值。
- 采集丢失根因: 宿主 safe-point 在状态锁内复制整个记录环,WndProc 使用 `try-lock`,争用时直接记丢失;探测器自身制造了实验失效条件。
- 证据边界: 失败运行混有多次组合,且存在采集丢失,只能证明夹具缺陷,不能区分输入法差异,也不能判断 Consume 是否安全。
## 跟踪信息
- 首次发现时间: 2026-10-06 14:07
- 最后更新时间: 2026-10-07
- 修复版本: 待提交
- 验证版本: Debug x64 探测构建、默认单元测试 15/15、UI fixture 1 轮、F24 自动 A/B、微软拼音 Forward/Consume 与搜狗运行时 fail-open 人工验证通过
- 参考: <https://learn.microsoft.com/windows/win32/api/immdev/nf-immdev-immgetvirtualkey>
- 后续关联: 固定锚点实现最初在状态锁内调用 IMM32 setter,引发 WndProc 重入自锁;详见 `BUG-20261006-0003`。
- 关闭边界: 搜狗候选态不暴露标准 Composition 生命周期,Consume 请求必须以 `ime_condition_not_met` fail-open;这是 `MustForward` 的输入法兼容结论,不是本 BUG 的残留夹具缺陷。