fix(launcher+fw): M39 r1 评审 P2 — 固件清单钉值同步 + APPS.md 守卫文档改到 150ms

- scripts/build/fw_content.conf:launcherd 钉值 bb2d5f12→e342d24f(本分支重链产物 891,164B),
  desc 补 M39 输入门与「链 meow_ui.a 8525aa6b」;同文件顺带修一处 pre-existing 打包阻塞:
  nyai 仍钉 M2.97 的 a7d24553,而仓库内二进制自 M35(cf5703b 评审 r1) 起已是 ef7940ec →
  从 main 打包固件会在该行 exit 1(与本单无关,但同一文件同一类错)。
- APPS.md §4.7:冷却 2500ms → MENU_TOUCH_GUARD_MS(150ms);写清「drain 才是防重放机制、
  时长只是面板重配尾巴守卫」;副作用段改为真实敞口(drain 之后硬件新产生的幽灵 1.2s 与
  150ms 都盖不住,只能靠真机日志收口),并指向 test_meow_ui_home_gesture T4。
- 校验:复刻 build_fw_apps.sh 第 4 步逐条 md5 强校验(真实 conf、临时 DST)→ 30 条全过、
  无 exit 1,装入的 launcherd = e342d24f、nyai = ef7940ec。
This commit is contained in:
AskaEth committed 2026-11-10 22:16:59 +08:00
1 parent 837cd47e7c
commit 6c6da79ad9
2 files changed
+5 -4

No files matched your search

+3 -2
View File
@@ -302,12 +302,13 @@ meow_launcherd --sim-exit N # 菜单打开 N 毫秒后模拟退出
**修复(`run_menu` + `menu_after_app_exit()`)**:
1. **drain**:应用退出后立即读完并丢弃 `touch_fd` 的全部残留事件。
2. **冷却**:应用**真正跑过**(`launch_app` 返回 0)时置 `menu_touch_cooldown_until = now + 2500ms`,冷却窗内忽略一切触摸按下边沿(与 watchdog 的同值 COOLDOWN_MS 对齐,覆盖实测幽灵窗 1.2-2.25s);启动失败(返回 -1)不置冷却,避免无谓锁菜单。
2. **短守卫**:应用**真正跑过**(`launch_app` 返回 0)时置 `menu_touch_cooldown_until = now + MENU_TOUCH_GUARD_MS`(**150ms**,M39 定值;M2.6 曾 2500ms、M2.22 缩到 1200ms),守卫窗内忽略触摸按下边沿;启动失败(返回 -1)不置守卫,避免无谓锁菜单。
**真正的防重放机制是第 1 条的 drain**:evdev 每个 fd 各收一份事件副本,App 运行期(launcher 不轮询 `touch_fd`)的全部事件都堆在本进程的 fd 里,drain 一次读空后已无历史事件可重放;**150ms 只兜面板重配后驱动补发的幽灵尾巴**。M39 起 drain 同时复位 `t_down/原点/坐标`——只清队列不清 pressed 边沿,会把「按下已被 drain、抬手稍后到」误判成一次 tap。旧注释写的「覆盖实测幽灵窗 1.2-2.25s」与实现自相矛盾(1200/2500ms 与 1.2–2.25s 的关系在 M2.22 注释里自己都写「实测略短」),故 M39 按「drain 是机制、时长只是尾巴守卫」定稿。
3. **菜单重绘**:v6.8 曾把 `last_redraw` 从绝对时间戳 `t` 改为相对量 `el`(使 500ms 安全重绘生效)以覆盖应用退出后的残帧(如 BYE)。**v6.9 起摒弃周期整屏重绘**(它在 500ms 定时把整个菜单重写进正在显示的 buffer0,造成列表 ~3fps 频闪):改为**仅 dirty 时整屏重绘**,应用退出/进入路径显式置 `dirty=1` 主动覆盖应用帧;时钟每秒用轻量 `draw_clock()` 只刷数字。
**Bug 3 根因与修复**:旧代码在所有 `launch_app` 调用点**无条件**置「CANNOT START: <name>」toast,即使应用**正常跑完**。修复:仅当 `launch_app` 返回 **-1(真启动失败)** 才置 toast;应用干净退出(返回 0)不显示。`launch_app` 用 **CLOEXEC 管道**检测 execve 失败(子进程写 errno → 父进程读 >0 判失败并返回 -1),不再把子进程 `_exit(127)` 误当「应用跑完」。
**副作用(已知取舍)**:应用退出后 2.5s 内菜单触摸不响应(返回键误触/退出后紧急再操作需等待;与 watchdog 相同值,实测幽灵窗 1.2-2.25s)。物理触摸的幽灵无法注入复现(§18.2 注入不投递),以上防抖逻辑在注入/sim 链路已验证,物理最终确认需用户。
**副作用(已知取舍)**:应用退出后 **150ms** 内菜单触摸不响应(M39 定值;M2.6 时是 2.5s,用户可见症状是「点一下没反应、要点两次」,M2.22 缩到 1.2s 仍会吞)。真正的不可控敞口是「面板在 drain 之后、队列之外新产生的硬件幽灵触摸」——这类幽灵 1.2s 与 150ms 都盖不住,只能靠真机日志收口:App 退出后观察 3–5s 内是否**自己重进 App / 闪回播放器**(Bug 2/4 原症状),并 `grep -c "menu touch dropped by cooldown"` 应为 0。物理触摸的幽灵无法注入复现(§18.2 注入不投递),宿主侧已由 `test_meow_ui_home_gesture` T4 覆盖「启动后立即点击生效 / 系统手势守卫内不触发、守卫后正好一次」。
---