## 当前状态(2026-11-01) 用户明确要求 **#30保留**。正式产品已有Unicode标量/宽格基础、Qt文字字节传输、IME组合/提交/取消(#205/#230),但不是完整文字交互。#155是本项IME验收子项,不重复计作独立产品工作包。原生前置#26/#39已闭,可独立推进;#39的Alacritty字素成功不能转作自主核心能力。 ## 本轮实现(2026-11-01) 已推送联合源码 `f20fe0b`:正式 Qt 新增无修饰 Home/End/Insert/Delete/PageUp/PageDown,并接入可见物理页基础正反拖选高亮。Home/End 复用既有 DECCKM 编码;本轮端到端验的是普通模式。独立 ReadConsoleW 接收端精确验证31B及代理项在导航键两侧的替换顺序;Shift+Insert 不会变成普通 Insert,Ctrl 字母除C的边界保持。 Qt 三项在同次联合执行通过,含真实子进程、固定 ConPTY、输入隔离和自然回收。新增鼠标检查使用公开消息及 offscreen 图像;不等于物理键鼠、原生 IME 或 CF 验收。[固定源码、原始失败和验证边界](https://github.com/JavaZeroo/termforge/blob/f72c5c4f68dd7eb579ad1e523762333b135aa074/experiments/shell/results/2026-11-01-r2-core-input/README.md)。已随 `f72c5c4` 推送 main。 同一提交的 [正式 Qt/固定 ConPTY CI](https://github.com/JavaZeroo/termforge/actions/runs/41321493769) 与 [Windows/Linux 总回归](https://github.com/JavaZeroo/termforge/actions/runs/41321493796) 均成功;[既有参考构建回归](https://github.com/JavaZeroo/termforge/actions/runs/41321493937)另列,不转作正式核心能力或性能验收。 系统复制/粘贴、选词/选行、历史浏览/自动滚动、Find 与八会话组合仍未完成;#155 按既定合同继续。本项不关闭。 ## 剩余四层合同 - [ ] **核心文字**:明确Unicode版本、字素边界/宽度、有界标记与spill策略;核对ZWJ/keycap等固定样本、分块/逐字节、宽格擦除及resize/历史交叉。当前Unicode15逐scalar和最多16marks不等于完整字素。 - [ ] **Qt呈现与交互**:核对实际glyph/fallback/网格;接入选择、复制、粘贴、Find与#29映射,使用实际CF与独立child字节预期。 - [ ] **键盘与IME**:与#28核对应用模式、编辑/修饰键、代理项和bracketed paste;当前Ctrl字母除C不支持,改变前按原版证据处理。#155继续候选身份、字体变化、Ctrl-C交付/消费以及输出/resize/焦点/隐藏/关闭交叉。 - [ ] **组合会话**:在同一正式构建完成Copy→Paste→IME与八会话目标隔离,记录取消、关闭、错误和回收;两会话或旧Win32工作流不能替代。 [Qt入口](https://github.com/JavaZeroo/termforge/blob/main/src/qt/README.md) · [固定拼音](https://github.com/JavaZeroo/termforge/blob/main/research/ui/results/2026-10-30-qt-ime-fixed-pinyin/README.md) · [N11有限对照](https://github.com/JavaZeroo/termforge/blob/main/docs/research/qt-ime-candidate-panel-reference-2026-11-01.md)。 N11来自历史冻结Qt源5fab30b:输出后面板停旧位两侧一致、resize延后点均更新;原版字体放大未触发、面板身份未证明。不能覆盖当前main全输入验收。R2单屏96/144由#35最终配置核对;跨屏归#297/R4。
Activity
JavaZeroo commentedon Oct 25, 2026
调查记录(保持 OPEN,未形成验收):
后续分别验收源字节、子控制台、独立模型与 TermForge 的文字/单元格,保留分解形式、选择复制和已知策略差异;不修改负载、超时或断言来掩盖问题。当前没有 R2 完成或真实呈现结论。
JavaZeroo commentedon Oct 25, 2026
已推送限定校验
730b5cde632bb33e2411686442a3b9c7255a64c5,本 issue 的完整 Unicode/IME 验收仍保持 OPEN。已验证:22 个纯校验与篡改负例、无窗口 ConPTY fixture、默认/候选各两轮常规工作流,以及隔离 1008×681 的完整 F 场景。五路各 32000 条记录和原 90 秒上限未改变;26 检查点和 18 个会话身份/回收通过,
complete_workflow_verified=false。校验不再假设直接源字节等于最终屏幕:完整源文件、真实子控制台
CHAR_INFO、实际运输尾部与独立pyte==0.8.2布局分别核对,TermForge 必须保留 e+U+0301 的分解形式。pyte的 NFC 结果只用于布局,不能替代原文。多点、少点、错行、错误尺寸/代次、缺少完成边界和分解形式变化均拒绝。调查入口与只读
FindUnicodeMetrics.java已同步到research/README.md。静态 Ghidra 事实不冒充运行时或 WindTerm 等价;完整字素/emoji、IME、真实 DPI、fallback、#36/#38 和实际呈现仍未完成。JavaZeroo commentedon Oct 25, 2026
已推送限定输入切片
fe0240051d8cc7e508362df9578c2a3c4e4a2d08与证据文档e3d10baa5cbd6c44d2ff90913fe9ad06a30e3f8b;本 issue 继续保持 OPEN。e + U+0301、单个 emoji、👩💻(ZWJ)和1️⃣(keycap)经 WM_CHAR → ConPTY → 真实ReadConsoleW接收端逐字节一致。默认/候选各两轮,四份接收文件均为 84 字节,SHA-256 为30a48ee8a238d1e6757a69ec5d7ec3848c694b9d8c9edc342e45ae1a0c0cc305;AltGr、编辑键和代理项边界仍在同一断言内。experiments/shell/results/2026-10-26-unicode-keyboard/validation.json;FEATURES、EVIDENCE 和场景说明已同步。源码/二进制/接收文件哈希已复核。这只完成精确输入字节验收,不证明新增样本的字素整形、单元格、glyph/fallback、选择复制、完整 IME 或应用键盘模式,也不构成 WindTerm 等价。未截图、未操作前台输入,
presented_done=null。后续继续分别验收真实 ConPTY 屏幕与绘制路径,R2 路标不因此关闭。JavaZeroo commentedon Oct 25, 2026
限定原文/glyph 实现与测试已推送:
18c36ce8a38fd4bbd3f09acd224b35e0852b3160。本 issue 与完整字素合同继续保持 OPEN。test_candidate_tui全组通过,其中固定 Unicode 真实场景两轮及十组篡改负例通过。👩与💻,keycap 为一格。这些仅是观察,未接受为完整聚类/宽度合同。完整流式分段由新建子项 #39 承担,[R2-07][文字] 验收复杂 Unicode、IME 与键盘/选择语义 #30 已有原生 blocked-by 关系;没有静默新增依赖。只读 WindTerm 调查只能确认整串/逐 scalar 测量路径,不能确定实际 ZWJ/keycap 网格宽度。完整默认/候选回归正在执行,最终证据和计数随后提交;不宣称完整 Unicode/IME、真实呈现或 R2 完成。
JavaZeroo commentedon Oct 25, 2026
限定证据已推送:
c73871e(实现为18c36ce)。完整记录见experiments/shell/results/2026-10-26-unicode-renderer/validation.json。本切片只通过原文保留、单元格观测和实际 glyph-run/布局宽度验证;完整 ZWJ/keycap 聚类与宽度仍由 #39 阻塞,完整 Unicode/IME、选择、真实 DPI、呈现和 R2 均未完成。
JavaZeroo commentedon Oct 30, 2026
结论
核对对象:HEAD
d3f24d6(落后origin/main两个提交,差异不涉下表文件)。5 项清单:0 项完成,3 项部分,2 项未实现。产品核心按 Unicode 15.0.0 逐 scalar 宽度(experiments/core/unicode_width.hpp:1-2),组合标记以marks<=16附到基格(experiments/core/screen.hpp:407-411),没有字素聚类(ZWJ 会拆成多个宽字);Qt 侧无 clipboard/selection。清单逐项状态
src/qt/unicode_input_test.cpp,src/qt/README.md:43:中文/NFD/nonBMP/ZWJ/keycap 精确 UTF-8,含代理项未配对正反例:92、:197);宽度/分解保留见screen.hpp:404-411。缺:无字素聚类(👩💻拆格)、Qt 无缺字/fallback 审计(对比 Win32experiments/presentation/render.hpp:109-142的 GlyphAudit)、无命中/选择复制src/qt/terminal_widget.hpp:172-188,src/qt/shell_smoke.cpp:361-386(preedit 不发送、commit 到达、cancel 写 0 字节);固定微软拼音真实事件序列与光标锚点research/ui/results/2026-10-30-qt-ime-fixed-pinyin/README.md:12-34。缺:与 resize/zoom/标签切换/隐藏/关闭的交叉(Qt 无 zoom);候选窗不可观测;resize 后 caret rect 未复核(:142-152只在查询时现算)unicode_input_test.cpp:92,197);缺:Qt 键映射只有 Return/Backspace/Tab/方向键(terminal_widget.hpp:104-121),无 Home/End/Delete/Insert/PgUp/PgDn、无 Ctrl/Alt 编辑组合;无 DECCKM(?1,terminal.hpp:33-50只认?1049/?7);产品源码无2004src/qt无 clipboard/selection(检索 0);八会话 R1 只在 Win32 实验 shell(experiments/shell/test_workflow_sessions.py:85,191-208)docs/FEATURES.md:44只写候选.4的 Unicode 17 合同;产品核心的 Unicode 15.0 +marks<=16+ 无有界 spill 未写入;Qt 字体策略仅src/qt/terminal_widget.hpp:242-249(固定 Roboto Mono,无 fallback 描述)下三个切片
切片 1 · Qt 编辑/导航/修饰键精确字节
src/qt/terminal_widget.hpp(:104-121键映射扩展 Home/End/Delete/Insert/PgUp/PgDn 与 Ctrl/Alt 编辑组合;以experiments/shell/keyboard.hpp既有预期字节为准,不另立策略)、src/qt/unicode_input_test.cpp(新增用例)。qt_unicode_input(35 s、offscreen、独立shell_input_client.exe接收端)断言每个键的精确字节与修饰键差异,并保留未配对代理项/不可用目标的负例。#28的字节预期)。切片 2 · IME 与 resize/标签切换/隐藏/关闭交叉
src/qt/terminal_widget.hpp(preedit 在失焦/隐藏/关闭时按"未提交即丢弃"处理,绝不写入会话;resize/字体变化后重新查询 caret rect)、src/qt/shell_smoke.cpp(新增阶段)、结果记录experiments/shell/results/2026-10-30-qt-ime-cross/validation.json。qt_cpp_shell新阶段:组合中 resize / 切标签 / 隐藏并关闭,断言另一会话收不到任何组合字节、已提交文字不重复、caret rect 在新网格内;失败即红,不放宽断言。切片 3 · 产品核心按 #39 合同实现 ZWJ/keycap 聚类与宽度
experiments/core/screen.hpp(put增加聚类前置状态:ZWJ/VS16/区域指示符/keycap,只生成单个 lead 与其 2 格尾格)、experiments/core/unicode_width.hpp+generate_width.py(仅在确需新表时)、CMakeLists.txt(grapheme_cluster_core)。experiments/core/grapheme_cluster_test.cpp并扩展experiments/core/test_unicode.py:👩💻单 lead/两格、1️⃣单格、NFD 原文保留、分块与逐字节一致、1 列屏幕拒绝/Recovery 替换;与 Qt 绘制只用cell.width(terminal_widget.hpp:201-213)对齐。docs/research/streaming-graphemes.md已发布的 [R2-07][文字] 裁决并实现流式复杂字素聚类与宽度 #39 合同,不新增行为选择)。边界
.4的 Unicode 17 字素实现能否直接搬入产品核心(字形/宽度表差异未核对,仅引用合同)。Merge pull request #239 from JavaZeroo/feat/function-keys
Merge pull request #240 from JavaZeroo/feat/qt-function-keys
JavaZeroo commentedon Oct 30, 2026
现状记录:Qt 入口的
Ctrl+字母目前是契约上不支持的我试着给 Qt 入口补齐
Ctrl+A…Z(发 0x01–0x1A,与 Win32 侧WM_CHAR的字节一致),CI 的qt_unicode_input立刻变红,原因是一条早已写死的断言:即:除 Ctrl+C 之外,Qt 入口的 Ctrl+字母必须不被处理,这是既有的验收契约(
src/qt/unicode_input_test.cpp:159-161)。同一用例还锁定了既有字节串Ab9+ CR/TAB/DEL +0x03+ 四个方向键序列(:164)。我的处置
顺带确认
Win32 入口的 Ctrl+字母是经
WM_CHAR得到 C0 字节的,与 Qt 入口的"只支持 Ctrl+C"并不一致——这个差异本身值得记录,但按现行契约,Qt 侧保持原样。边界
JavaZeroo commentedon Oct 31, 2026
本机可验证的部分已固化在 core 测试里
本项验收要求在「自主 C++ 和 Qt 声明配置」下核对原始标量、字素边界、宽度/光标、实际 glyph、复制与子进程接收,并完成固定 IME 与同次八会话交叉。我把其中不依赖 GUI/真实输入的那一层先摸清,便于把范围写实。
已固化(
experiments/core/test_unicode.py,15 项,本机通过)覆盖项:CJK 宽度与 ASCII、四字节标量、歧义宽度按窄处理、组合字符贴右边距、剩一列时的宽字换行、宽字主/尾单元的覆盖与擦除、SGR 与 reset(含亮色与选择性 reset)、SGR 不取消 pending-wrap、带样式的宽字进入历史、擦除使用当前样式、非法 UTF-8 与不支持序列、单列放不下宽字。
这些用例对每个固定 chunk 大小都跑一遍,因此覆盖的是解析层的分块无关性,不是渲染层。
仍未覆盖(属于本项剩余验收)
experiments/shell的选择/剪贴板场景里,未与本项交叉建议
把本项按上表拆成「核心解析层(已固化)/Qt 呈现层/真实输入层/交叉会话层」四块验收,各自指向已有证据或明确标为缺口;否则「复杂 Unicode 验收」会一直是一个无法判定的整体。
本条只做覆盖核对,不关闭本项,也不修改验收标准。