锁定桌面窗口状态持久化边界
桌面壳窗口状态 flags 抽成可测试函数并覆盖排除可见性全屏和装饰状态 桌面壳配置门禁反查窗口状态 flags 单测边界 宿主壳方案协议和共享决策同步窗口状态验收口径
This commit is contained in:
@@ -2122,7 +2122,12 @@ const requiredRustHostSnippets = [
|
||||
'tauri_plugin_single_instance::init',
|
||||
'desktop_window_state_plugin()',
|
||||
'tauri_plugin_window_state::Builder::default()',
|
||||
'desktop_window_state_flags()',
|
||||
'StateFlags::SIZE | StateFlags::POSITION | StateFlags::MAXIMIZED',
|
||||
'fn desktop_window_state_flags_keep_visible_state_out_of_persistence()',
|
||||
'assert!(!flags.contains(StateFlags::VISIBLE));',
|
||||
'assert!(!flags.contains(StateFlags::FULLSCREEN));',
|
||||
'assert!(!flags.contains(StateFlags::DECORATIONS));',
|
||||
'tauri_plugin_deep_link::init()',
|
||||
'register_desktop_deep_link_events(app)',
|
||||
'register_desktop_deep_link_schemes(app)',
|
||||
|
||||
@@ -2,8 +2,29 @@ use tauri::plugin::TauriPlugin;
|
||||
use tauri::Runtime;
|
||||
use tauri_plugin_window_state::StateFlags;
|
||||
|
||||
fn desktop_window_state_flags() -> StateFlags {
|
||||
StateFlags::SIZE | StateFlags::POSITION | StateFlags::MAXIMIZED
|
||||
}
|
||||
|
||||
pub(crate) fn desktop_window_state_plugin<R: Runtime>() -> TauriPlugin<R> {
|
||||
tauri_plugin_window_state::Builder::default()
|
||||
.with_state_flags(StateFlags::SIZE | StateFlags::POSITION | StateFlags::MAXIMIZED)
|
||||
.with_state_flags(desktop_window_state_flags())
|
||||
.build()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn desktop_window_state_flags_keep_visible_state_out_of_persistence() {
|
||||
let flags = desktop_window_state_flags();
|
||||
|
||||
assert!(flags.contains(StateFlags::SIZE));
|
||||
assert!(flags.contains(StateFlags::POSITION));
|
||||
assert!(flags.contains(StateFlags::MAXIMIZED));
|
||||
assert!(!flags.contains(StateFlags::VISIBLE));
|
||||
assert!(!flags.contains(StateFlags::FULLSCREEN));
|
||||
assert!(!flags.contains(StateFlags::DECORATIONS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2673,7 +2673,7 @@
|
||||
## 2026-06-18 桌面壳窗口状态持久化
|
||||
|
||||
- 背景:Tauri 桌面壳已经具备系统托盘、单实例、深链和受控 HostBridge 能力,但用户调整主窗口尺寸、位置或最大化状态后,重启桌面 App 仍回到固定初始窗口配置;如果直接保存完整窗口状态,又可能把托盘隐藏后的可见性状态带到下次启动。
|
||||
- 决策:桌面壳接入 `tauri-plugin-window-state`,并把插件配置收口到 `apps/desktop-shell/src-tauri/src/shell/window_state.rs`。只保存 `SIZE`、`POSITION` 和 `MAXIMIZED`,不保存 `VISIBLE`、`FULLSCREEN` 或 `DECORATIONS`;该能力属于宿主壳自身体验,不进入 HostBridge capability,不暴露窗口状态插件 command 给 H5。插件注册顺序固定为 single-instance 优先,其后才是 window-state、deep-link 和其它系统插件。
|
||||
- 决策:桌面壳接入 `tauri-plugin-window-state`,并把插件配置收口到 `apps/desktop-shell/src-tauri/src/shell/window_state.rs`。只保存 `SIZE`、`POSITION` 和 `MAXIMIZED`,不保存 `VISIBLE`、`FULLSCREEN` 或 `DECORATIONS`;该能力属于宿主壳自身体验,不进入 HostBridge capability,不暴露窗口状态插件 command 给 H5。插件注册顺序固定为 single-instance 优先,其后才是 window-state、deep-link 和其它系统插件。`window_state.rs` 必须保留直接 Rust 单测证明这组 flags 边界,桌面壳配置门禁会反查该测试。
|
||||
- 影响范围:`apps/desktop-shell/src-tauri/Cargo.toml`、`apps/desktop-shell/src-tauri/Cargo.lock`、`apps/desktop-shell/src-tauri/src/main.rs`、`apps/desktop-shell/src-tauri/src/shell/window_state.rs`、`apps/desktop-shell/scripts/check-config.mjs`、Expo / Tauri HostBridge 方案文档。
|
||||
- 验证方式:`npm run desktop-shell:typecheck`、`npm run desktop-shell:test`、`npm run desktop-shell:build -- --no-bundle`、`npm run check:native-shells`、`npm run typecheck -- --pretty false`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ Tauri 壳同样只负责桌面宿主能力,不承接玩法业务。
|
||||
- 崩溃上报、前端 analytics、桌面遥测日志、自动更新和渠道分发 SDK 都必须等真实端点、采集字段、用户同意、隐私策略、签名和发布流程确定后逐项接入;当前桌面壳不安装 Sentry、Datadog、PostHog、Segment、Amplitude、Bugsnag、OpenTelemetry、Tauri log / updater 等相关依赖。
|
||||
- 桌面壳和根 H5 包不安装 `@tauri-apps/api` 或 `@tauri-apps/plugin-*` JS guest 包;生产 H5 只通过 Tauri 注入的 `window.__TAURI__.core.invoke('host_bridge_request', request)` 进入 HostBridge。opener、clipboard、dialog、notification 等能力只保留 Rust Cargo 插件,由 Rust 内部分发并受 capability 白名单约束。
|
||||
- 桌面深链只作为宿主启动 / 唤醒入口处理,不进入 HostBridge capability,也不把 deep-link 插件 command 授权给 H5。Tauri 只注册 `genarrative` scheme,并接受同源 `https://app.genarrative.world` URL;壳层会把目标路径归一为带 `native_app`、`tauri_desktop` 和真实 capability 清单的同源 H5 URL,外域、明文协议和危险协议直接丢弃。`navigation.openNativePage` 的同源主动跳转也必须复用同一宿主上下文补写逻辑,避免新页面按普通浏览器运行态启动。
|
||||
- 桌面窗口状态持久化属于宿主壳自有体验,不进入 HostBridge capability,也不开放窗口状态插件 command 给 H5。Tauri 壳只保存主窗口大小、位置和最大化状态,不保存可见性、全屏或装饰状态,避免托盘隐藏窗口后下次启动被恢复成隐藏状态。
|
||||
- 桌面窗口状态持久化属于宿主壳自有体验,不进入 HostBridge capability,也不开放窗口状态插件 command 给 H5。Tauri 壳只保存主窗口大小、位置和最大化状态,不保存可见性、全屏或装饰状态,避免托盘隐藏窗口后下次启动被恢复成隐藏状态;`shell/window_state.rs` 必须保留 Rust 单测证明这组 flags 边界。
|
||||
- 桌面壳外链打开、WebView 新窗口外链接管、托盘关闭前生命周期注入和窗口隐藏都属于用户可见宿主动作;这些动作失败必须走统一桌面宿主事件日志,配置检查拒绝 `let _ = ...` 静默吞错。
|
||||
|
||||
桌面 release 和 dev 模式:
|
||||
@@ -427,7 +427,7 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 单实例。用户重复启动桌面 App 时,新实例会退出并唤醒已有主窗口;该回调只执行显示、取消最小化和聚焦主窗口,不把第二实例的命令行参数或工作目录作为事件透传给 H5。Windows / Linux 上由单实例插件的 `deep-link` feature 把二次实例 URL 交给 deep-link 插件,仍由 `shell/deep_link.rs` 做受控归一;单实例唤醒主窗口失败必须记录桌面宿主事件日志,不能静默吞错。
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 窗口状态持久化。`shell/window_state.rs` 只配置 `tauri-plugin-window-state` 保存主窗口大小、位置和最大化状态,并排除可见性、全屏和装饰状态;插件注册顺序固定为 single-instance 优先,其后才是窗口状态、deep-link 和其它系统能力插件。该能力不进入 HostBridge 清单,不向 H5 暴露任意窗口状态读写,也不改变托盘关闭隐藏、单实例唤醒和托盘恢复主窗口的既有语义。
|
||||
2026-06-18 追加:桌面壳启用 Tauri 窗口状态持久化。`shell/window_state.rs` 只配置 `tauri-plugin-window-state` 保存主窗口大小、位置和最大化状态,并排除可见性、全屏和装饰状态;插件注册顺序固定为 single-instance 优先,其后才是窗口状态、deep-link 和其它系统能力插件。该能力不进入 HostBridge 清单,不向 H5 暴露任意窗口状态读写,也不改变托盘关闭隐藏、单实例唤醒和托盘恢复主窗口的既有语义。`apps/desktop-shell/scripts/check-config.mjs` 会反查 `desktop_window_state_flags_keep_visible_state_out_of_persistence` 单测,避免后续把可见性、全屏或装饰状态误纳入持久化。
|
||||
|
||||
2026-06-18 追加:桌面壳接入 Tauri deep-link 插件,但不开放插件 JS guest API,也不把 deep-link 命令加入 capability。桌面配置只注册 `genarrative` scheme;Rust 层只接受 `genarrative://open/...`、`genarrative://app/...`、`genarrative://<path>` 和 `https://app.genarrative.world/...`,统一跳到同源 H5 路径并补写 `clientRuntime=native_app`、`hostShell=tauri_desktop`、当前平台、版本与真实 `hostCapabilities`。外域、`http:`、`mailto:`、`javascript:`、`file:` 等来源不进入主 WebView;归一成功后的 `window.navigate(...)` 与主窗口恢复 / 聚焦失败必须记录桌面宿主事件日志,不能静默吞错。
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user