From 328bf920bdfd8a58009714000fe50a8db6f56f72 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 20 Jun 2026 09:50:51 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=A1=8C=E9=9D=A2=E5=A3=B3?= =?UTF-8?q?=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F=E7=8A=B6=E6=80=81=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 桌面生命周期窗口状态读取失败时记录具体字段并使用保守默认值 桌面壳配置检查拒绝窗口状态读取静默兜底 共享决策日志补充生命周期读取失败边界 --- apps/desktop-shell/scripts/check-config.mjs | 11 +++-- .../src-tauri/src/shell/lifecycle.rs | 40 +++++++++++++++++-- .../shared-memory/decision-log.md | 7 ++++ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/apps/desktop-shell/scripts/check-config.mjs b/apps/desktop-shell/scripts/check-config.mjs index 3e88cd082..78478214f 100644 --- a/apps/desktop-shell/scripts/check-config.mjs +++ b/apps/desktop-shell/scripts/check-config.mjs @@ -2253,7 +2253,9 @@ const requiredRustHostSnippets = [ 'WindowEvent::Focused', 'WindowEvent::Resized', 'resolve_desktop_lifecycle_payload', + 'resolve_desktop_lifecycle_window_flag', 'emit_current_desktop_lifecycle_event', + 'desktop_lifecycle_window_flag_logs_failure_and_uses_default', '"background"', '"hidden"', '"minimized"', @@ -2273,9 +2275,9 @@ const requiredRustHostSnippets = [ 'PageLoadEvent::Finished', 'replay_desktop_webview_state', 'log_desktop_host_event_result', - 'window.is_focused()', - 'window.is_visible()', - 'window.is_minimized()', + 'resolve_desktop_lifecycle_window_flag("visible",', + 'resolve_desktop_lifecycle_window_flag("minimized",', + 'resolve_desktop_lifecycle_window_flag(\n "focused",', 'resolve_desktop_network_status', 'network.statusChanged', 'register_desktop_navigation_events', @@ -2786,6 +2788,9 @@ for (const blockedLifecycleSnippet of [ 'let _ = emit_current_desktop_lifecycle_event(window)', 'let _ = emit_current_desktop_lifecycle_event(&lifecycle_window)', 'let _ = emit_desktop_image_drop_event(&drop_window', + 'window.is_visible().unwrap_or(', + 'window.is_minimized().unwrap_or(', + 'window.is_focused().unwrap_or(', 'let _ = app.deep_link().register_all()', 'let _ = window.navigate(target_url)', 'let _ = show_main_window(window.app_handle())', diff --git a/apps/desktop-shell/src-tauri/src/shell/lifecycle.rs b/apps/desktop-shell/src-tauri/src/shell/lifecycle.rs index 3beb216df..4ad884ade 100644 --- a/apps/desktop-shell/src-tauri/src/shell/lifecycle.rs +++ b/apps/desktop-shell/src-tauri/src/shell/lifecycle.rs @@ -74,10 +74,30 @@ pub(crate) fn emit_desktop_lifecycle_payload( emit_desktop_lifecycle_event(window, payload.state, payload.focused, payload.native_state) } +fn resolve_desktop_lifecycle_window_flag( + label: &'static str, + result: tauri::Result, + default_value: bool, +) -> bool { + match result { + Ok(value) => value, + Err(error) => { + eprintln!("desktop host event failed for app.lifecycle.{label}: {error}"); + default_value + } + } +} + pub(crate) fn emit_current_desktop_lifecycle_event(window: &WebviewWindow) -> tauri::Result<()> { - let visible = window.is_visible().unwrap_or(true); - let minimized = window.is_minimized().unwrap_or(false); - let focused = window.is_focused().unwrap_or(visible && !minimized); + let visible = + resolve_desktop_lifecycle_window_flag("visible", window.is_visible(), true); + let minimized = + resolve_desktop_lifecycle_window_flag("minimized", window.is_minimized(), false); + let focused = resolve_desktop_lifecycle_window_flag( + "focused", + window.is_focused(), + visible && !minimized, + ); emit_desktop_lifecycle_payload( window, resolve_desktop_lifecycle_payload(focused, visible, minimized), @@ -151,6 +171,20 @@ mod tests { )); } + #[test] + fn desktop_lifecycle_window_flag_logs_failure_and_uses_default() { + assert!(resolve_desktop_lifecycle_window_flag( + "visible", + Ok(true), + false + )); + assert!(!resolve_desktop_lifecycle_window_flag( + "focused", + Err(tauri::Error::WindowNotFound), + false + )); + } + #[test] fn desktop_lifecycle_payload_maps_hidden_and_minimized_to_background() { assert_eq!( diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 863ae094f..0f783d372 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -2902,6 +2902,13 @@ - 影响范围:`apps/desktop-shell/src-tauri/src/shell/deep_link.rs`、`apps/desktop-shell/scripts/check-config.mjs`。 - 验证方式:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml shell::deep_link`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。 +## 2026-06-20 桌面壳生命周期窗口状态读取失败不可静默 + +- 背景:Tauri 桌面壳 `app.lifecycle` 事件会驱动 H5 游戏循环、背景音乐和固定玩法音频暂停 / 恢复;如果 `is_visible()`、`is_minimized()` 或 `is_focused()` 读取失败后静默使用默认值,生命周期状态可能错误且难以排查。 +- 决策:`emit_current_desktop_lifecycle_event(...)` 必须通过 `resolve_desktop_lifecycle_window_flag(...)` 读取窗口可见、最小化和焦点状态;读取失败时记录 `desktop host event failed for app.lifecycle.`,再使用保守默认值。桌面壳配置检查拒绝重新出现 `window.is_visible().unwrap_or(...)`、`window.is_minimized().unwrap_or(...)` 或 `window.is_focused().unwrap_or(...)`。 +- 影响范围:`apps/desktop-shell/src-tauri/src/shell/lifecycle.rs`、`apps/desktop-shell/scripts/check-config.mjs`。 +- 验证方式:`cargo test --manifest-path apps/desktop-shell/src-tauri/Cargo.toml shell::lifecycle`、`npm run desktop-shell:typecheck`、`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。 + ## 2026-06-20 移动壳 EAS 原生包构建 profile - 背景:移动壳已能通过 Expo managed config 和 Metro production bundle smoke,但缺少原生安装包构建 profile;如果只保留 `expo export`,无法证明 Android / iOS 壳有进入原生分发链路的配置。