Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/qt-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
"-DTERMFORGE_CONPTY_BACKEND_DIR=$dependencyRoot/conpty" `
"-DTERMFORGE_MSVC_RUNTIME_DIR=$dependencyRoot/crt"
- name: Build Qt product and independent smoke
run: cmake --build build/qt-cpp --config Release --target termforge_qt_shell qt_cpp_shell_smoke qt_cpp_resize_smoke qt_unicode_input_test qt_unicode_render_test qt_terminal_modes_test qt_hidden_retention_test qt_history_navigation_test qt_selection_migration_test qt_find_test qt_scrollbar_size_test qt_clipboard_system_test --parallel 2
run: cmake --build build/qt-cpp --config Release --target termforge_qt_shell qt_cpp_shell_smoke qt_cpp_resize_smoke qt_unicode_input_test qt_unicode_render_test qt_eight_session_test qt_terminal_modes_test qt_hidden_retention_test qt_history_navigation_test qt_selection_migration_test qt_find_test qt_scrollbar_size_test qt_clipboard_system_test --parallel 2
- name: Record complete path-free runtime manifests
run: |
python tools/msvc_runtime.py manifest --directory build/qt-cpp/qt-bin/Release --executable termforge_qt_shell.exe
Expand All @@ -55,6 +55,8 @@ jobs:
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
python tools/msvc_runtime.py manifest --directory build/qt-cpp/qt-unicode-render-bin/Release --executable qt_unicode_render_test.exe
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
python tools/msvc_runtime.py manifest --directory build/qt-cpp/qt-eight-session-bin/Release --executable qt_eight_session_test.exe
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
python tools/msvc_runtime.py manifest --directory build/qt-cpp/qt-modes-bin/Release --executable qt_terminal_modes_test.exe
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
python tools/msvc_runtime.py manifest --directory build/qt-cpp/qt-hidden-retention-bin/Release --executable qt_hidden_retention_test.exe
Expand Down Expand Up @@ -82,13 +84,14 @@ jobs:
build/qt-cpp/qt-resize-bin/Release/runtime-manifest.json
build/qt-cpp/qt-unicode-bin/Release/runtime-manifest.json
build/qt-cpp/qt-unicode-render-bin/Release/runtime-manifest.json
build/qt-cpp/qt-eight-session-bin/Release/runtime-manifest.json
build/qt-cpp/qt-modes-bin/Release/runtime-manifest.json
build/qt-cpp/qt-hidden-retention-bin/Release/runtime-manifest.json
build/qt-cpp/qt-history-bin/Release/runtime-manifest.json
build/qt-cpp/qt-selection-bin/Release/runtime-manifest.json
build/qt-cpp/qt-clipboard-bin/Release/runtime-manifest.json
- name: Run Qt offscreen smoke in its owned Job
run: ctest --test-dir build/qt-cpp -C Release -R '^(qt_cpp_(shell|resize)|qt_unicode_input|qt_unicode_render|qt_terminal_modes(_retained)?|qt_hidden_retention|qt_history_navigation|qt_selection_migration|qt_find|qt_scrollbar_size)$' --no-tests=error --verbose
run: ctest --test-dir build/qt-cpp -C Release -R '^(qt_cpp_(shell|resize)|qt_unicode_input|qt_unicode_render|qt_eight_session|qt_terminal_modes(_retained)?|qt_hidden_retention|qt_history_navigation|qt_selection_migration|qt_find|qt_scrollbar_size)$' --no-tests=error --verbose
- name: Run hosted-only Qt system clipboard copy
run: python src/qt/run_smoke.py build/qt-cpp/qt-clipboard-bin/Release/qt_clipboard_system_test.exe --hosted-copy
- name: Run hosted Windows QPA product-writer clipboard copy
Expand Down
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ if(WIN32)
add_executable(shell_unicode_echo_client experiments/shell/unicode_echo_client.cpp)
termforge_warnings(shell_unicode_echo_client)
target_compile_definitions(shell_unicode_echo_client PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE)
add_executable(shell_eight_session_client experiments/shell/eight_session_client.cpp)
termforge_warnings(shell_eight_session_client)
target_compile_definitions(shell_eight_session_client PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE)
add_executable(shell_text_client experiments/shell/text_client.cpp)
termforge_warnings(shell_text_client)
target_compile_definitions(shell_text_client PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE)
Expand Down Expand Up @@ -744,6 +747,23 @@ if(TERMFORGE_BUILD_QT_SHELL)
"${PROJECT_SOURCE_DIR}/src/qt/run_smoke.py" "$<TARGET_FILE:qt_unicode_render_test>")
set_tests_properties(qt_unicode_render PROPERTIES TIMEOUT 35
ENVIRONMENT "QT_QPA_PLATFORM=offscreen;TERMFORGE_TEST_ARTIFACTS=${PROJECT_BINARY_DIR}/test-artifacts")
add_executable(qt_eight_session_test src/qt/eight_session_test.cpp)
set_target_properties(qt_eight_session_test PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qt-eight-session-bin/$<CONFIG>")
termforge_qt_entry(qt_eight_session_test)
target_link_libraries(qt_eight_session_test PRIVATE Qt6::Test)
add_dependencies(qt_eight_session_test shell_eight_session_client)
add_custom_command(TARGET qt_eight_session_test POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"$<TARGET_FILE:Qt6::QOffscreenIntegrationPlugin>"
"$<TARGET_FILE_DIR:qt_eight_session_test>/platforms/"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"$<TARGET_FILE:shell_eight_session_client>" "$<TARGET_FILE_DIR:qt_eight_session_test>/"
VERBATIM)
add_test(NAME qt_eight_session COMMAND "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/src/qt/run_smoke.py" "$<TARGET_FILE:qt_eight_session_test>")
set_tests_properties(qt_eight_session PROPERTIES TIMEOUT 60
ENVIRONMENT "QT_QPA_PLATFORM=offscreen;TERMFORGE_TEST_ARTIFACTS=${PROJECT_BINARY_DIR}/test-artifacts")
add_executable(qt_cpp_resize_smoke src/qt/resize_smoke.cpp)
set_target_properties(qt_cpp_resize_smoke PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qt-resize-bin/$<CONFIG>")
Expand Down
1 change: 1 addition & 0 deletions docs/EVIDENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
| Qt 有界系统复制入口(#29/#30 切片) | [实现、fake 入口回归与 hosted 阻塞](../experiments/shell/results/2026-11-06-qt-system-copy/README.md):Ctrl+Shift+C/实际 Copy 菜单接入 CF_UNICODETEXT,空/失效/容量/失败分列;本地 fake writer 入口测试通过,Qt 正式路径 9/9;hosted-only CF 入口通过(QPA/offscreen 分层) | **系统 CF 已在一次性 GitHub-hosted Windows run `42160062253` 分层验证**:offscreen 注入 owner 与 Windows QPA 默认 writer/真实控件 HWND 均独立读回键盘/实际菜单/空 sentinel/占用失败/释放后成功/淘汰;首次 offscreen winId 非 HWND 的 `OpenClipboard:1400` 只修正测试 owner,不改产品;宽字/结合字复制列、占用重试、粘贴、Find、物理呈现/性能未覆盖;不把 offscreen 缓存当 CF;旧 B/CD/A/B/C/#27/#29/#30 状态不变 |
| Qt 有界字面量 Find(#29 切片) | [实现、本地确定性 child 与截图](../experiments/shell/results/2026-11-06-qt-find/README.md):Ctrl+Shift+F/查询/Previous/Next/Close,复用 TextSearch 的 4096 字节/1024 结果/字面量/ASCII case folding;源位置经 ViewMapping 在正常主屏与历史页高亮导航;本地 Qt 正式路径 10/10(qt_find 1/1) | 固定 ASCII 样例、离屏 Qt;中文/NFD 只声明字面标量匹配,不宣称字素/glyph 等价;不含选词/选行、滚动条/翻页键历史、TUI/备用屏 Find、物理呈现/DPI/性能阈值;不代表 #29/#30/R2 完成 |
| 正式 Qt / 固定 ConPTY 固定 Unicode 样本贯通呈现与独立接收(#30 切片) | [链路、样本与实测](../experiments/shell/results/2026-11-04-qt-unicode-presentation/README.md):新增 `qt_unicode_render`,5 条固定样本经公开 Qt 事件→真实 child `ReadConsoleW` 精确接收→同字节 CR→CRLF 回显→核心解析→`TerminalWidget` 离屏抓图;receiver/echo SHA-256 与源字节逐字节一致,CJK 实测 fallback `Alibaba PuHuiTi`、emoji `Segoe UI Emoji`(advance 21>span 18 但无裁剪参考墨迹 3..17 未越格),结合标 `marks=1`,第二条空会话 0 字节且无样本文字;Qt 正式路径 6/6 | U+200D/U+FE0F 仍被 recovery parser 替换为 U+FFFD(只记录,不批准新聚类/宽度策略);offscreen + 宿主 fallback 依赖、`presented_done=null`,不覆盖物理呈现/原生 IME/真实 DPI/完整字素或 #30/#155 验收 |
| 正式 Qt / 固定 ConPTY 八会话文本输入目标隔离与生命周期(#30 切片) | [入口、矩阵、时序与实测](../experiments/shell/results/2026-11-08-qt-eight-session-isolation/README.md):新增 `qt_eight_session`,通过公开 `+`/标签切换/关闭入口创建 8 个真实固定 ConPTY child(+1 替代页),每会话独立 PID/nonce/接收文件;硬编码字面预期核对 ASCII/CJK/补充平面/结合标与无修饰 Home 只进入活动目标,非创建顺序 `[4,0,7,2,5,1,6,3]` 切换,8×120 行受控后台输出全部排空(queued 0),关闭非活动/活动标签后存活目标继续精确接收,替代页首输入无待发单元泄漏,父窗关闭 6 会话 `cleanup_verified/active_processes_after=0`、status 0;Qt 正式路径 CTest 12/12,核心 42/42 | 仅 offscreen 合成 Qt 事件、固定 8 会话/80×24/1 替代页,`presented_done=null`;`SessionTabs` 当前无会话上限,未定义/未测试第 9 个会话行为;不覆盖真实键盘、原生 IME、系统剪贴板、真实 DPI、完整 Copy→Paste→IME、八会话以上或性能;#30/#155/#7 不关闭 |
| 隐藏主屏纯高度变化的正文保留(#27 工程合同) | [RED/GREEN、命令与边界](../experiments/core/results/2026-11-04-hidden-height-retention/README.md):修复前 `resize_hidden_height_test` 证明隐藏 live/历史被按未变宽度裁剪并丢失保留尾;`resize_preserving` 改为只在宽度实际变化时适配隐藏帧后,三场景通过并注册 `retained_resize_hidden_height_core`;组合回放 20/20、事务检查不变,正式 Qt CTest 5/5 | 工程不变量;原版对照见下一行。2026-11-04 用户确认保留完整正文、接受原版返回裁剪差异,工程身份不变;固定七阶段正式 Qt 路径已离屏核对(见下方正式路径行),物理呈现/DPI 未覆盖。未覆盖备用屏后续输出、保存光标交叉、Unicode、历史淘汰、Qt 物理呈现/DPI 或性能;#27/#29 不关闭 |
| 正式 Qt / 固定 ConPTY 隐藏帧七阶段完整正文(#27/#29 正式路径切片) | [场景、阶段与显示/命中](../experiments/shell/results/2026-11-04-qt-hidden-retention/README.md):真实 child 写入 91×20 固定 75 B 正文→公开 Qt 缩窄 61→`1049h`→仅高度 20→14→20→`1049l`→恢复宽度 91;58 检查 0 失败,2 次运行除 `child_pid` 外一致;阶段 1/2/6/7 逻辑正文 SHA `0e683ff0…` 相同,保留行 id `12`、91-Cell 源行与历史 5 行前缀保持,显示页/光标/命中均映射同一源身份;Qt 正式路径 7/7(8.99 s)、核心 41/41(23.05 s) | 仅 offscreen 固定样本;非物理呈现(`presented_done=null`)、DPI、IME 或性能验收;child 原生行单独记录,不作为保留文本 oracle;原严格失败、补充审计与 `semantic_acceptance=false` 不改写;#27/#29/#30/#7 不关闭 |
| 原版隐藏主屏高度的录制恢复与离线补充审计(#27/#29) | [补充审计、阶段观察与差异](../research/ui/results/2026-11-02-resize-hidden-height-reference/README.md):七阶段原版录制的严格审计失败保留;从仍可用的取证环境只读恢复完整输入后,离线补充审计通过(计划 `938992c4…`、参考 EXE `7b1053…`/4047 清单 `e459adf2…`、执行源清单 `51e80b93…`,0 次重跑),补充件 `4c0f28f2…` | 审计显示返回主屏后宽行按当前宽度裁剪为 61 空格 + `w`(62 字符)、DSR `19;7→14;7`,与 #311 的保留合同存在差异;2026-11-04 用户已确认保留完整正文、接受该原版观察为产品有意差异([决定评论](https://github.com/JavaZeroo/termforge/issues/29#issuecomment-6627911863));本记录不修改实现、不重跑、不关闭 #27/#29;语义验收 false,备用屏阶段 API 文本不等于活动备用屏网格 |
Expand Down
Loading