From 933daa0c92329cc4da1d2430527883d7cac6a947 Mon Sep 17 00:00:00 2001 From: wangzhizhou <824219521@qq.com> Date: Thu, 29 Oct 2026 21:55:13 +0800 Subject: [PATCH 1/2] docs: record the switch-keeps-composition change and move the baseline to build 32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both machines now run 1.0.0 build 32 (host executable ddd33b7a…), and the trial baseline follows, since IT-23 has not started counting yet. Signed-off-by: wangzhizhou <824219521@qq.com> --- ROADMAP.md | 3 ++- docs/reviews/217-1.0.0-freeze.md | 12 +++++++----- docs/reviews/221-switch-keeps-composition.md | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 64c2d04..53571eb 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -245,7 +245,8 @@ ADR-147:Terminal正常实际提交“你”及wq前缀确认后的failure/INT/ - [ ] **2026-10-27 MVP 正式发布(目标 `1.0.0`,ADR-298)**:阶段 A 在 0.1.16/26 上演练 IT-22(`docs/tasks/T-ITER-22.md`)→ 修复入库 → 阶段 B 递增 1.0.0(build 27)并双机装同一包(同时闭环「更新器自更新」)→ 阶段 C 只在 1.0.0 上做正式 IT-22、IT-15 独立重建、IT-23 五工作日 → 阶段 D `tag v1.0.0` 打在验收候选提交 → Release → Pages。 - [x] 2026-10-28 **锁定候选 1.0.0 / build 29**(报告217):提交 `11abece3`、ZIP `aca4ed5c…`、宿主执行 `4ad949e6…`,air 已装同包。装机定向复验:2.1 多词拼接 PASS、9.1 编码播报 PASS、11.1 候选跟随(6 张截图:下方/镜像/底部翻上,无压字)PASS。**IT-22 限定范围通过**(必查 11 + 抽查 8 全 PASS,其余沿用报告216 基线)。 - [x] 2026-10-28 **IT-15 独立离线重建通过(报告218)**:用户在 air 上从候选自带源码包离线重建 1.0.0/build 29,身份链与逐架构网络导入 PASS、**默认数据 4/4 逐字节一致**、空闲 0 外联;可执行文件因本机 SDK 27.0 vs 发布 26.5 不同(ADR-033 边界)。顺带修掉 `run-repro.sh` 的缺陷:原来 `cmp` 可执行文件失败会中断,导致数据表比对根本没跑,且漏比 `variant-s2t.tsv`。 -- [ ] 2026-10-29 IT-23 五工作日试用(**1.0.0 / build 31**,air 与 pro 执行 SHA 均为 `9cbe8a22…`):两台设备已装同一包(报告217 §8)。29→30 修「候选窗跟随鼠标」,30→31 只加 HUD 诊断(报告220,实为旧进程未退出);IT-23 尚未起算。 +- [ ] 2026-10-29 IT-23 五工作日试用(**1.0.0 / build 32**,air 与 pro 执行 SHA 均为 `ddd33b7a…`):两台设备已装同一包(报告217 §8)。29→30 修「候选窗跟随鼠标」,30→31 加 HUD 诊断,31→32 改「组合态切换不丢字」(ADR-302);IT-23 尚未起算。 +- [x] 2026-10-29 **组合态切换不再丢字(ADR-302,报告221,build 32)**:`toggle_width`/`set_mode` 去掉 `cancel()`(保留组合、按新模式重算且不自动上屏),Shift 切英文改为**原样上屏编码**;core 新增 3 个单测,`ime-ffi` 旧用例改为先 Esc;两台设备已装 build 32。 - [x] 2026-10-29 **「HUD 不显示」结案(报告220)**:三次报告分别是诊断开关未生效无法取证、候选窗跟随鼠标(真缺陷,build 30 修)、**换包后旧进程仍在运行**。build 31 把诊断改为文件开关并给 `showStateFeedback`/`hudCaretRect` 各分支打点;`iterate-macos-ime` 收尾清单新增「`lsof … | grep -c deleted` 必须为 0」。 - [x] 2026-10-29 **候选窗跟着鼠标而不是插入点(报告219,build 30)**:`caretRect` 给解析器传了 `allowsEmptyCaret: false`,`length()==0` 时解析直接返回 nil → 落到鼠标兜底;改为 `true`,并把回退链收敛为「本轮 → 上次成功位置 → 鼠标」,新增 3 条断言。两台设备已装 build 30。 - [~] I3/IT-12/23:IT-12 性能/内存/久用已 PASS(报告191/192/199/207);**IT-23 五工作日试用尚未开始**(模板报告211)。 diff --git a/docs/reviews/217-1.0.0-freeze.md b/docs/reviews/217-1.0.0-freeze.md index 7822d52..d1dcdbe 100644 --- a/docs/reviews/217-1.0.0-freeze.md +++ b/docs/reviews/217-1.0.0-freeze.md @@ -123,15 +123,15 @@ platforms/macos/tests/run-repro.sh \ - **静态零外联**:`./scripts/verify-no-network.sh`(或 `make verify-no-network`)通过。 - **运行时零外联**:一边打字一边 `lsof -i -a -p "$(pgrep -x Lampyris)"`,预期**无输出**。 -## 8. IT-23 试用基线:两台设备装同一个包(2026-10-29 更新为 build 31) +## 8. IT-23 试用基线:两台设备装同一个包(2026-10-29 更新为 build 32) | 项 | air(本机,arm64 / macOS 27.0.1) | pro(x86_64 / macOS 13.7.8) | |---|---|---| -| 版本 / 构建 | **1.0.0 / 31** | **1.0.0 / 31** | -| 宿主执行 SHA-256 | `9cbe8a22e7e4d5af5e67e4e60bf00e5e53bd3e7032d02dfab8264b997c1c630b` | **同值**(同一个二进制) | -| 更新程序构建号 | 31 | 31 | +| 版本 / 构建 | **1.0.0 / 32** | **1.0.0 / 32** | +| 宿主执行 SHA-256 | `ddd33b7aa2962a6b4e5cc3f662624931b67f713c6428201d61979edec17dd66e` | **同值**(同一个二进制) | +| 更新程序构建号 | 32 | 32 | | 签名 / 公证 | Developer ID + `spctl` Notarized | 同(`codesign --strict`、`stapler validate` 均 PASS) | -| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `cb8e7d05…`、词库 **690 行**(build 31 装前装后一致) | +| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `cb8e7d05…`、词库 **727 行**(build 32 装前装后一致) | | 旧版本备份 | `updates/`、`uninstalled/` 历史项 | `uninstalled/bundle.aPZKev`(0.1.16) | | 输入源 | `cn.jokerhub.inputmethod.Lampyris.default` 已启用 | 已启用;当前停在 ABC,使用时按 ⌃Space 切 | @@ -145,3 +145,5 @@ pro 的安装记录:`ev-95-pro-stage.log`(ZIP 校验 → 解包 → 停宿 > 根因与修法见报告 219。IT-23 尚未开始记第 1 天,因此换包不影响试用基线;两台设备均已升级到 30。 > **再从 30 换到 31 的原因**:31 只增加 HUD 诊断(文件开关 + 分支打点),用于证实第三次「HUD 不显示」 > 实为**旧进程仍在运行**(报告 220),不是产品缺陷。诊断文件已删除,无文件时零开销;两台设备均已在 31。 +> **31 → 32 的原因**:组合态下按 Shift/⌥M/⌥F 会丢字(报告 221 / ADR-302),改为「Shift 原样上屏编码、⌥M/⌥F 保留组合」。 +> IT-23 仍未起算,基线跟随最终行为。 diff --git a/docs/reviews/221-switch-keeps-composition.md b/docs/reviews/221-switch-keeps-composition.md index ae3ab01..99b1680 100644 --- a/docs/reviews/221-switch-keeps-composition.md +++ b/docs/reviews/221-switch-keeps-composition.md @@ -32,7 +32,7 @@ - core 新增 3 个单测(全角保留组合与候选、切模式保留缓冲区并重算、新模式无候选时保留编码且 Esc 仍可取消)。 - `ime-ffi` 的 `candidates_expose_source_codes` 原先依赖"切模式会清空缓冲",改为先 Esc 再切模式。 - 离线回归 56 文件 / 303 例、`make verify` 全绿;实机复验见 §5。 -- 实机复验(build 32,两台设备):待填。 +- 装机:air 与 pro 均为 1.0.0/build 32(执行 `ddd33b7a…`),待用户按 §5 复验三条快捷键。 ## 5. 遗留 From a35c5209c34746332419552d1808f867ad0e1469 Mon Sep 17 00:00:00 2001 From: wangzhizhou <824219521@qq.com> Date: Thu, 29 Oct 2026 22:02:37 +0800 Subject: [PATCH 2/2] fix: take the keyboard Shift and mode paths through the new behaviour Report 222: build 32 passed only the width case because the two other paths live in the host, not in the core. A lone Shift press goes through flagsChanged and called shiftTransition, which swallows the buffer and then cleared the marked text; the menu handler I patched earlier was never reached. The raw code is now captured before the transition and inserted afterwards. Cycling modes called cancelClientComposition() before setMode, so the composition died no matter what the core did; it now sets the mode, shows the chip feedback and refreshes marked text and candidates. Build 33. Signed-off-by: wangzhizhou <824219521@qq.com> --- packaging/build-number | 2 +- platforms/macos/Sources/InputController.swift | 28 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packaging/build-number b/packaging/build-number index f5c8955..bb95160 100644 --- a/packaging/build-number +++ b/packaging/build-number @@ -1 +1 @@ -32 +33 diff --git a/platforms/macos/Sources/InputController.swift b/platforms/macos/Sources/InputController.swift index 8725c89..89ce211 100644 --- a/platforms/macos/Sources/InputController.swift +++ b/platforms/macos/Sources/InputController.swift @@ -483,9 +483,10 @@ final class LampyrisInputController: IMKInputController { defer { refreshStateMenu() } if ImeConfig.string("mode") != next, !ImeConfig.setString("mode", next) { presentConfigError(); return } guard session?.mode != next else { return } - cancelClientComposition() + // ADR-302:组合中切模式保留编码,由核心按新模式重算候选(报告 222:这里原先会先取消组合)。 session?.setMode(next) showStateFeedback(StateFeedback.mode(next)) + refreshAfterStateChange() } // MARK: - 按键处理 @@ -506,13 +507,24 @@ final class LampyrisInputController: IMKInputController { session?.noteModifierChange(event) let other = flags.contains(.control) || flags.contains(.option) || flags.contains(.command) - if let session, - session.shiftTransition(isDown: flags.contains(.shift), otherModifier: other) - { - if let client = activeClient ?? (sender as? IMKTextInput) { clearMarked(client) } - candidateWindow?.hide() - // 键盘单独 Shift 与菜单/快捷键走同一提示:候选窗已隐藏,这里应弹 HUD。 - showStateFeedback(StateFeedback.language(session.isEnglish)) + if let session { + // ADR-302:切到英文前把编码原样上屏。必须在 `shiftTransition` 之前取, + // 它内部会 `cancel()` 掉缓冲区(报告 222)。 + let pendingRaw = session.isComposing && !session.isEnglish ? session.buffer : nil + let toggled = session.shiftTransition( + isDown: flags.contains(.shift), otherModifier: other) + if toggled { + let client = activeClient ?? (sender as? IMKTextInput) + if let client { clearMarked(client) } + if let raw = pendingRaw, !raw.isEmpty, let client { + client.insertText(raw, + replacementRange: NSRange(location: NSNotFound, length: 0)) + if Self.hudDiagEnabled { Self.hudDiag("shift committed raw=\(raw)") } + } + candidateWindow?.hide() + // 键盘单独 Shift 与菜单/快捷键走同一提示:候选窗已隐藏,这里应弹 HUD。 + showStateFeedback(StateFeedback.language(session.isEnglish)) + } } return false }