fix(app-iced): M100 r1 返工 —— 一次一采样 + OS 层密闭指标 + 文档口径订正

三条复审意见 + 六条 p3,全部落在原有文件里(另加两个拆分文件)。

P2-1 截图落盘「最后写入者说了算」(真竞态)
  `Message::Frame` 以前在 `frames >= CAPTURE_AT_FRAME` 之后每帧都发一次 `window::screenshot`,
  `Captured` 每次都覆盖同一文件才 `exit()`;已派发的采样不会因 exit 撤回 ⇒ 落盘内容是调度结果
  (复审实测 12 次里 7 次写了两次;把窗口在两次采样之间改成 900×600,落盘就是 900×600)。
  现在闸门 = `should_request_capture(frames, dispatched, capture_mode)`,派发即置位、只开一次;
  `Captured` 计数落盘次数并打进日志。实测 12/12 次「[shot] -> 文件」行恒为 1、`落盘次数=1`。

P2-2 密闭证据换成 OS 层
  `platform/win32/transparency.rs` 加安全 getter `click_through`(unsafe 仍只在既有唯一落点);
  该文件因超 400 行又拆出 `transparency/exstyle.rs`(子模块继承父模块的 `#![allow(unsafe_code)]`,
  `unsafe-scope` 门禁判据不受影响)。日志三态 `[caps] passthrough_ext=on|off|unknown`:
  `None` 记 `unknown`,绝不记 `off`。实测默认 on 12/12、`--passthrough=off` 为 off 3/3。

P2-3 头注释「下放」→「新增」,并订正「接真控件改 3 个文件」
  (section 文件里的 body 绊线 + 该 section 的 `GROUP` 文件 + `tests/mod.rs` 跨 section 绊线)。

p3 六条:shell 断言说明改准(默认值那条归 cli 的测试)、harness 文档给「指针事件=0」加对照限定、
数字订正(纯搬移 234 / 新增 134)、三文件口径、ai+about 对本文件的两处必改、`Rest` 与真 Disabled
撞语义写进「抓不住」。

文档口径:「8 连跑全稳」不再当密闭证据——同 argv 开/关穿透 hash 相同(实测 0d7b4f5b 两边一样),
它只说明「帧静止 + 落盘确定」。密闭主证据是 `[caps] passthrough_ext=`。

顺带:`run()` 从 `harness.rs` 拆到 `harness/app.rs`(272 / 190 行)。搬移中丢过一条既有断言
`ensure_layered_refuses_a_missing_or_invalid_window`,被编译器 unused-import 警告抓出并复原。
This commit is contained in:
AskaEth committed 2026-11-03 15:22:55 +08:00
1 parent 2061296615
commit 380fac0324
13 files changed
+545 -201

No files matched your search

@@ -1,7 +1,9 @@
//! 「Appearance」分组自己的断言(M100 从 `settings/tests.rs` 下放)。
//! 「Appearance」分组自己的断言(M100 **新增**:`settings/tests.rs` 那 7 条全是跨 section 的,
//! 一条 section 断言都没有;这 3 条是新增,不是搬移)。
//!
//! **归 language+appearance 线**:这是设置页唯一接了真控件的一组,真控件实现全在
//! `pages/appearance/section.rs`;本文件只守「注册表这一侧的接线」。
//! 本组已经把 `body` 接上了,所以 `tests/mod.rs` 那条「只有一组有真控件」的绊线不用再动。
use super::super::appearance;
use unlucky_design::icons::IconKind;
@@ -1,6 +1,8 @@
//! 「Downloads」分组自己的断言(M100 从 `settings/tests.rs` 下放)。
//! 「Downloads」分组自己的断言(M100 **新增**:`settings/tests.rs` 那 7 条全是跨 section 的,
//! 一条 section 断言都没有;这 3 条是新增,不是搬移)。
//!
//! **归 download 线**:接真控件时改本文件,不必动 `tests/mod.rs`,也不碰别的分组。
//! **归 download 线**。接真控件那天要改**三个**文件:本文件 `the_downloads_group_is_still_demo_rows`
//! (`body.is_none()` 绊线)+ `settings/download.rs` + `tests/mod.rs` 的跨 section 绊线。
//!
//! 别把它和下载页(`pages/download*`)搞混:那是「装哪个版本」,这一组是「怎么下」的默认值。
@@ -1,7 +1,9 @@
//! 「General」分组自己的断言(M100 从 `settings/tests.rs` 下放)。
//! 「General」分组自己的断言(M100 **新增**:`settings/tests.rs` 那 7 条全是跨 section 的,
//! 一条 section 断言都没有;这 3 条是新增,不是搬移)。
//!
//! **归 language+appearance 线**:接真控件时改本文件(`GROUP.body` 那条绊线要跟着翻),
//! 不必动 `tests/mod.rs`,也不碰别的分组。
//! **归 language+appearance 线**。接真控件那天要改**三个**文件:本文件
//! `the_general_group_is_still_demo_rows`(`body.is_none()` 绊线)+ `settings/general.rs` +
//! `tests/mod.rs` 的跨 section 绊线。
use super::super::general;
use unlucky_design::icons::IconKind;
@@ -1,7 +1,14 @@
//! 「Java」分组自己的断言(M100 从 `settings/tests.rs` 下放)。
//! 「Java」分组自己的断言(M100 **新增**:`settings/tests.rs` 里一条 section 断言都没有,
//! 那 7 条全是跨 section 的;所以这 3 条是新增,不是搬移)。
//!
//! **归 java 线**:接真控件时改本文件,不必动 `tests/mod.rs`,也不碰别的分组。
//! 判据(M100 交付里正面回答的那条):给 java 加一条新断言 = **只改本文件**。
//! **归 java 线**。接真控件那天要改**三个**文件:
//! 1. 本文件 `the_java_group_is_still_demo_rows`(它断言 `body.is_none()`,接上就红);
//! 2. `settings/java.rs`(写 `body = Some(..)`);
//! 3. `tests/mod.rs` 的 `only_the_appearance_group_carries_a_real_control_body`(跨 section 绊线)。
//!
//! download / general 同型。
//!
//! 判据(M100 交付里正面回答的那条):给 java 加一条**新断言** = **只改本文件**。
use super::super::java;
use unlucky_design::icons::IconKind;
@@ -1,15 +1,31 @@
//! 设置页的**跨 section** 守门测试(M100 按 section 下放之后,留在 mod 层的那一份)。
//! 设置页的**跨 section** 守门测试(M100:跨 section 的留在这里,section 自己的断言**新增**在
//! `tests/<section>_section.rs`)。
//!
//! ## 为什么这里只剩「跨 section」的断言
//!
//! 设置页正文接下来由四条线并行接(java / download / language+appearance / ai+about)。每条线要能
//! **只改自己的测试**就跑通,所以「某一组自己的行文案 / 图标 / body 现状」一律下放到
//! `tests/<section>_section.rs`;本文件只留**必须四组一起看**的断言——下放到任何单组文件里,
//! 都会变成「某组替其它三组说话」,四条线并行时必然互相踩。
//! **只改自己的测试**就跑通,所以「某一组自己的行文案 / 图标 / body 现状」一律放在
//! `tests/<section>_section.rs`(M100 **新增**的 12 条,不是从本文件搬过去的——本文件在 `main`
//! 上就只有下面这 7 条跨 section 断言,一条 section 断言都没有);本文件只留**必须四组一起看**的
//! 断言——下放到任何单组文件里,都会变成「某组替其它三组说话」,四条线并行时必然互相踩。
//!
//! 判据(M100 报告里正面回答的那条):**给 java 加一条新断言,改几个文件?** —— 1 个
//! (`tests/java_section.rs`)。本文件不动。
//!
//! 但「java 线**接真控件**那天改几个文件」是另一回事,答案是 **3 个**(M100 r1 复审 p3-3 订正,
//! 我最初只写成 2 个):`settings/java.rs`(写 body)+ `tests/java_section.rs` 的
//! `the_java_group_is_still_demo_rows`(它断言 `body.is_none()`,接上就红)+ 本文件末尾那条
//! `only_the_appearance_group_carries_a_real_control_body`。download / general 同型。
//!
//! ## ai+about 线要额外改本文件的两处(M100 r1 复审 p3-4)
//!
//! 它加第 5 组时,除了 `settings/mod.rs` 的 `GROUPS`,**本文件还有两处必改**:
//! 1. 顶部 `mod ai_section;`(新测试文件要挂进来,否则永远不编译、永远不跑);
//! 2. [`the_split_kept_the_left_column_order`] 断言的是**字面量** `["General","Appearance",
//! "Java","Downloads"]`,加第 5 组必红——这是刻意的:左列顺序变了就是观感变了,要人确认。
//! 另外 `the_appearance_group_is_where_the_module_says_it_is` 依赖 `APPEARANCE_GROUP == 1`,
//! **把新组插在 Appearance 前面会连带红**(所以新组应该排最后)。
//!
//! ## 站位
//!
//! 本文件是 `pages::settings::tests`:`super` = `pages::settings`,`super::super` = `pages`。