Files
MailUI4Agents/client/electron
dsh 477479a370 fix(harmony): ★★ 三页 AppHeader 顶栏避让硬编码 0 ⇒ 顶栏压进系统状态栏(真机实测)
设备:HUAWEI MatePad Pro(MRDI-W00),HarmonyOS NEXT,API 26,
      `hdc tconn 192.168.2.87:43679`(此前一直无真机,本条挂了 5 天)。

## 症状(用户报:「左上角全屏状态下不应该显示全屏,会与顶部系统顶栏冲突」)

截图像看是状态栏压住顶栏。**实测证伪了这个读法**:像素扫描 + `uitest dumpLayout`
显示顶栏文字在 y=134..166、系统状态栏止于 y=82,**两者不重叠**。
真正被切掉的是**列表第一封邮件的标题**(y=294..319,只剩一条细线)。

⇒ 两处独立问题,第二个(窗格头 y=222..320 与列表首行 y=294..319 重叠)
   **不是顶栏避让**造成的,本次未修,见下。

## 已修:AppHeader 那一半的避让确实是坏的

`EntryAbility` 早就把避让读到了(真机日志 `insets: statusBar=38.588235
navIndicator=27.764706 windowDecor=37`),`CommPage`/`MainPage` 内容层也用了
(`top: max(statusBar, windowDecor) + paneGap`)。**但 `AppHeader` 是另一个消费者,
三处都写死了 `topInsetPx: 0`**:

  · `SentTab`(发件箱)      MainPage.ets:1658
  · `SettingsPage`(我的)   SettingsPage.ets:687
  · `PermissionTab`(授权)  PermissionTab.ets:487

只有 `AdminUsersPage` 是对的(`topInset(this.windowInsets)`)—— 抄它。

## 为什么已有的判据没抓到(这才是关键)

`harmony-window.test.mjs` 接线⑤「每一个 @Entry 页都要消费避让」是**绿的**,
因为它的 `consumes()` 认两种形状,其中一种只要**文件里出现过**
`this.windowInsets.statusBar` 就算过 —— 而 `MainPage` 的**内容层**正好读了它。
⇒ 页面上有**两个**避让消费者,判据只问"页里有没有出现过那个字段",
  于是 `AppHeader` 里那个 0 被完全放过。

新判据(判据 10)改成**逐个消费者问**:任何传给 `AppHeader` 的 `topInsetPx`
不得是字面量 0。自检要求扫到 ≥4 处,防"遍历写错 ⇒ 永远绿"。

★ 这条判据自己先犯过一次同类错并当场被抓:第一版用 `prose()`(含注释),
  把**我自己写进注释里的**「原先 topInsetPx: 0」抓成了红 ——
  判据在判自己的注释。改用本文件已有的 `stripped()`(其注释原话:
  「判据的锚不能落在被守对象的自述上」)。红绿已验:把 SettingsPage 退回
  缺陷版 ⇒ 红;恢复 ⇒ 绿。

## 编译期抓到的一个坑

`MainPage.ets:1658` 的 AppHeader 在 **`SentTab`** 里,而 `windowInsets` 原本
只声明在 `CommPage` 上。ArkTS 报 `Property 'windowInsets' does not exist on
type 'SentTab'`。⇒ `@StorageLink` 是**每个组件各自**订阅 `AppStorage` 的,
父组件的不会自动传给子组件;直接各自订阅同一把键(比"父传子"少一层)。

## 真机验证

装机后重跑 dumpLayout:发件箱顶栏 `y=134..166`(状态栏底 y=82,间隙 52px),
截图确认「发件箱」完整显示、不再被压。

## 未修(诚实登记)

列表第一行标题被窗格头盖住(`List` 首项 y=294..319 落在窗格头 y=222..320 内),
与顶栏避让**无关**,本次未动。根因待查:`MailRow` 是 `.height(64)` 定高,
而 List 容器从 y=320 起算,首项被画到容器上方。
2026-10-01 18:49:06 +08:00
..