Files
Unlucky-Launcher/crates/app-iced/src/pages/harness/caps.rs
T
AskaEth 380fac0324 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 警告抓出并复原。
2026-11-03 15:22:55 +08:00

54 lines
2.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 取证窗口的**OS 侧密闭指标**(M100 r1 P2-2):`WS_EX_TRANSPARENT` 在不在。
//!
//! 为什么单独一个文件:① `harness.rs` 正卡在 400 行硬线上;② 「三态映射」这件事本身值得有断言
//! (把 `unknown` 掉成 `off` 是这类日志最典型的假绿)。
//!
//! 判据来自 winit 0.30 的 Windows 实现:`set_cursor_hittest(false)` ⇒
//! `WS_EX_TRANSPARENT | WS_EX_LAYERED`。读位的手在
//! [`crate::platform::win32::transparency::click_through`](全仓唯一 unsafe 落点)。
use crate::platform::win32::transparency;
/// 窗口是不是点击穿透 → 日志里的三态字面量。
///
/// - `on` = 读到了,且有 `WS_EX_TRANSPARENT`(winit 已把命中测试关掉);
/// - `off` = 读到了,没有这一位;
/// - `unknown` = **没读到**(非 Windows / 句柄无效 / 还没拿到句柄)。
///
/// `unknown` 绝不许写成 `off`:「拿不到」和「没有」是两件事(U1 同族)。
#[must_use]
pub fn passthrough_label(hwnd: Option<isize>) -> &'static str {
match hwnd.and_then(transparency::click_through) {
Some(true) => "on",
Some(false) => "off",
None => "unknown",
}
}
#[cfg(test)]
mod tests {
use super::passthrough_label;
/// **抓得住**:谁把「没读到」掉成 `off`(那样一次失败的读数就变成了「密闭没开」的假证据,
/// 或者反过来——在一台读不到扩展样式的机器上永远看不出密闭是否生效)。
/// **抓不住**:真实窗口上的位到底置没置(那要出图日志里看 `on`)。
#[test]
fn a_missing_handle_is_unknown_not_off() {
assert_eq!(
passthrough_label(None),
"unknown",
"没句柄 = 没读到 ⇒ unknown"
);
assert_eq!(
passthrough_label(Some(0)),
"unknown",
"句柄 0 = 拿不到 ⇒ unknown(不是 off)"
);
assert_eq!(
passthrough_label(Some(1)),
"unknown",
"无效句柄 ⇒ unknown(不是 off)"
);
}
}