feat: tmux 动态 resize(iPadOS 拖拽窗口/旋转自适应)

- ContentView 观测 onChange(geo.size)/onAppear → controller.containerResized
- containerResized: 点尺寸 × displayScale ÷ cell 像素 = 目标 cols×rows,去重 + debounce(200ms)
  → refresh-client -C WxH → tmux 重排回 %layout-change → 更新 pane frame
- cell 像素来自 raw 终端/pane surface metrics(InMemoryTerminalViewport.cellWidthPixels);
  surface resize 回调只 noteCellPixels 不驱动 tmux(防反馈环,单向数据流)
- 验证:容器 1032x1280@2x cell16x35→129x73,tmux 根 rect 精确采纳,2 pane 复用不重建

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
kid
2026-07-24 17:42:45 +08:00
parent 9a27338222
commit 7abe61a71f
4 changed files with 85 additions and 32 deletions

View File

@@ -67,7 +67,7 @@
## 6. 已知问题 / TODO继续工作的入口
- **M4 安全**`SSHSession.connect()``TODO(M4)`:不校验 host key接受任意。需接 known_hosts 三元组 pin(egress,host,port) + Secure Enclave 私钥(`libssh2_userauth_publickey_frommemory`+`SecKeyCreateSignature`)。
- **tmux 多 pane 分屏**:✅ 已做pane-per-surface + layout rect 绝对定位渲染 + 按 pane %output 路由 + tap 切焦点/select-pane + attach `refresh-client -C` 设尺寸让 tmux 布局)。**剩余**:动态 resize旋转/改字号→重发 refresh-client -Cfable 方案第 5 步,未做,当前 attach 时定一次);完整 scrollback仍靠 capture-pane 抓当前屏pause 流控(`%pause/%continue`,防单 pane 刷屏tmux<3.1 降级路径未做
- **tmux 多 pane 分屏 + 动态 resize**:✅ 已做pane-per-surface + layout rect 绝对定位渲染 + 按 pane %output 路由 + tap 切焦点/select-pane + attach `refresh-client -C` 设尺寸 + **iPadOS 拖拽窗口/旋转 → `onChange(geo.size)`→`containerResized`(点×displayScale÷cell像素)→debounce→refresh-client -C→%layout-change→更新 frame**,验证:容器 1032x1280@2x cell16x35→129x73tmux 精确采纳)。**剩余**完整 scrollback仍靠 capture-pane 抓当前屏pause 流控(`%pause/%continue`,防单 pane 刷屏);split/kill pane 手势;tmux<3.1 降级路径未做
- **tsnet 首连**已加 dial 重试更优是等 peer online dial PeersJSON online 状态)。
- **签名/真机**`CODE_SIGNING_ALLOWED=NO`仅模拟器上真机/TestFlight 需配置签名 + entitlementstsnet 用户态**无需** NE entitlement利好审核)。
- **git** `git init`**尚无 commit**`artifacts/*.xcframework` gitignore `make`/脚本重建或从 Release )。
@@ -76,7 +76,7 @@
## 7. 下一步建议(按价值)
1. **M2 mosh 打磨**功能已通打磨项`activateMosh` 写死 80x24 初值靠首次 resize 纠正SSH 会话在 mosh 接管后保持 idle 未关占一条连接`MoshSession.close()` mosh 线程可能滞留阻塞主循环 TODOmoshiosbridge.cc 顶部 `fwrite("Hello from the Bridge!")` 调试行可清理`SSHTerminalModel` `NSLog("MOSHDBG …")` 诊断日志可按需保留/删除mosh-server 引导后远端会累积 detached 会话`mosh-server new` 每次新建可考虑复用或清理。**挂起恢复<3s M3待专门测**。
3. **M3 真机深挂起补测**模拟器不复现 socket defunct且看门狗会杀掉被 `kill -STOP` 冻结过久的 app>~30s 概率被杀),故 WG 密钥过期(>180s)/DERP 死链/socket defunct 路径需**真机锁屏数分钟**用例补测(`MoshRelay.Rebind`/`hop_port` 的正确性靠代码 + 真机)。
4. **tmux 多 pane 打磨**动态 resize旋转/改字号→debounce 重发 `refresh-client -C`,处理回来的 %layout-change防抖动/反馈环pause 流控split/kill pane 的 UI 手势;外接键盘 `Cmd+Opt+方向` 导航 pane
4. **tmux 多 pane 打磨**pause 流控(`%pause/%continue` 防单 pane 刷屏)split/kill pane 的 UI 手势;外接键盘 `Cmd+Opt+方向` 导航 pane;完整 scrollback。多 pane + 动态 resize 已做并验证。)
5. **M4 安全 + 冷启动 mosh 重连**known_hosts 固定 + SE 密钥mosh 进程死后重连原 detached 会话需持久化 MOSH_KEY+port 且改 mosh 序列化 SSP 序号/终端状态Blink 式,大活)。
5. **产品化**:主机列表持久化(Keychain)、多标签(非 tmux)、软键盘运维工具栏(GhosttyKit 内建,接线即可)。