fix(app-iced): M90 r3 —— 空闲 1Hz 心跳恢复配置热切 + 导航轨口径订正 + 文档收口

复审 P2-2(空闲态掐时钟 ⇒ config_poll_due 再也不跑):
- 空闲态改用 1 Hz 自续心跳(Task::perform(sleep(1s)) → Message::Heartbeat),忙碌态仍用
  window::frames() + 33ms 闸门;两条时钟不并行(心跳在 needs_frames() 为真时只续排不推进)。
- ticks 改成「33 ms 一拍」记账(1 s 心跳记 30 拍),config 轮询判据从「整除」改成「跨越」——
  实测整除版在 ticks=137 之后每拍 +30 永远不命中,配置轮询静默死掉。
- 顺手修一个真 bug:Message::SystemTheme 原来无条件 set_flavor,会把配置文件里的显式主题盖掉
  (优先级现在是 --theme > 配置文件 > 系统),否则「改 launcher.json 主题 1 秒内生效」验收根本看不到。
- 实测:14 s 交互跑,空闲段 [tick] clock=idle-1hz 每秒一行、frames 冻结在 2947、refreshes 冻结在 6;
  t≈7s / t≈11s 两次改 launcher.json,各自 ≤1 s 内打出 [settings] 配置文件变了 + [theme] 翻转。

复审 P2-1(导航轨口径):
- pages/mod.rs 交付表改成事实(产品路径的 rail 由 shell/nav.rs 画,组件版只给 harness/单测,
  像素等价是复审判的),补偏离表第 10 条(两套 rail 各测各的,漂移没人拦);
- pages/tests.rs 的 the_real_rail_agrees_with_the_layout_system 注释同步订正。

P3 文档五条:shell 的「8px 拖动热区」改成事实(拖动面=整条 48px 标题栏到第一个 caption;
缩放热区 4px)、state/update 的「每拍重建视图模型」改成 view_dirty 门控、message 的 Frame 注释
改成「只在忙碌时订阅」、pages/model 的 From<&AppState> 改成自由函数 model(..)、pages/tests 的守门
目录补 src/app。

r3 浅/深产品图与 r2 逐字节相同(视觉零变化)。
This commit is contained in:
AskaEth committed 2026-11-02 15:56:59 +08:00
1 parent 022778a5a7
commit 6b66adff44
9 files changed
+254 -42

No files matched your search

+9 -4
View File
@@ -84,7 +84,8 @@ fn the_width_comparison_really_changes_the_layout() {
///
/// **抓得住**:`frame_metrics` 的 `column`(页面唯一的列宽来源)不会越界;
/// **抓不住**:页面自己绕过 metrics 写死宽度(那条由 `tests/no_hardcoded_tokens.rs` 的
/// 「`.width(` 后面不许跟数字字面量」守门——注意它扫的是 `src/shell` + `src/pages`)。
/// 「`.width(` 后面不许跟数字字面量」守门——它扫的是 `src/shell` + `src/pages` + `src/app`
/// (M90 r2/P3-3 把 `app` 加进去了)。
#[test]
fn every_page_any_width_stays_under_the_measure_cap() {
let cap = measure_cap_px();
@@ -119,10 +120,14 @@ fn the_three_frozen_numbers_are_unchanged() {
assert_eq!(WidthClass::of(840.0), WidthClass::Expanded);
}
/// 导航轨用的**真组件**(M78 的 `NavigationRail`)声明的宽度必须与布局系统同值。
/// **组件版**导航轨(M78 的 `NavigationRail`)声明的宽度必须与布局系统同值。
///
/// **抓得住**:`NavPaneGeometry::rail().width` == `layout::rail_width()` == 88(组件与布局系统没分叉);
/// **抓不住**:容器圆角/药丸摆放的像素级正确性(组件自己的 probe 管)。
/// 注意这不是产品路径的实现(M90 r3 订正):产品页的 rail 由 `shell/nav.rs` 画,组件版只服务
/// `pages::app`(harness 出口图)与单测。这条守的是「组件与布局系统没分叉」,**不是**「产品 rail
/// 没问题」——两套实现的漂移风险见 `pages/mod.rs` 偏离表 #10。
///
/// **抓得住**:`NavPaneGeometry::rail().width` == `layout::rail_width()` == 88;
/// **抓不住**:容器圆角/药丸摆放的像素级正确性(组件自己的 probe 管),也抓不住 `shell/nav.rs`。
#[test]
fn the_real_rail_agrees_with_the_layout_system() {
let ui = ui();