桌面壳补齐历史导航菜单
为桌面应用菜单增加后退和前进历史动作 补充桌面菜单测试与配置门禁 更新桌面壳菜单导航文档
This commit is contained in:
@@ -1107,8 +1107,16 @@ const requiredRustHostSnippets = [
|
||||
'tauri_plugin_clipboard_manager::init()',
|
||||
'register_desktop_app_menu(app)?',
|
||||
'DESKTOP_APP_MENU_SHOW',
|
||||
'DESKTOP_APP_MENU_BACK',
|
||||
'DESKTOP_APP_MENU_FORWARD',
|
||||
'DESKTOP_APP_MENU_RELOAD',
|
||||
'DESKTOP_APP_MENU_QUIT',
|
||||
'DesktopAppMenuAction::GoBack',
|
||||
'DesktopAppMenuAction::GoForward',
|
||||
'DESKTOP_HISTORY_BACK_SCRIPT',
|
||||
'DESKTOP_HISTORY_FORWARD_SCRIPT',
|
||||
'window.history.back(); true;',
|
||||
'window.history.forward(); true;',
|
||||
'resolve_desktop_app_menu_action',
|
||||
'app.set_menu',
|
||||
'app.on_menu_event',
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
use crate::shell::tray::{reload_main_window, show_main_window};
|
||||
use tauri::menu::{Menu, MenuItem, PredefinedMenuItem, Submenu};
|
||||
use tauri::Manager;
|
||||
|
||||
pub(crate) const DESKTOP_APP_MENU_SHOW: &str = "app-menu-show-main-window";
|
||||
pub(crate) const DESKTOP_APP_MENU_BACK: &str = "app-menu-history-back";
|
||||
pub(crate) const DESKTOP_APP_MENU_FORWARD: &str = "app-menu-history-forward";
|
||||
pub(crate) const DESKTOP_APP_MENU_RELOAD: &str = "app-menu-reload-main-window";
|
||||
pub(crate) const DESKTOP_APP_MENU_QUIT: &str = "app-menu-quit-desktop-shell";
|
||||
pub(crate) const DESKTOP_HISTORY_BACK_SCRIPT: &str = "window.history.back(); true;";
|
||||
pub(crate) const DESKTOP_HISTORY_FORWARD_SCRIPT: &str = "window.history.forward(); true;";
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub(crate) enum DesktopAppMenuAction {
|
||||
ShowMainWindow,
|
||||
GoBack,
|
||||
GoForward,
|
||||
ReloadMainWindow,
|
||||
QuitApp,
|
||||
Ignore,
|
||||
@@ -16,17 +23,41 @@ pub(crate) enum DesktopAppMenuAction {
|
||||
pub(crate) fn resolve_desktop_app_menu_action(menu_id: &str) -> DesktopAppMenuAction {
|
||||
match menu_id {
|
||||
DESKTOP_APP_MENU_SHOW => DesktopAppMenuAction::ShowMainWindow,
|
||||
DESKTOP_APP_MENU_BACK => DesktopAppMenuAction::GoBack,
|
||||
DESKTOP_APP_MENU_FORWARD => DesktopAppMenuAction::GoForward,
|
||||
DESKTOP_APP_MENU_RELOAD => DesktopAppMenuAction::ReloadMainWindow,
|
||||
DESKTOP_APP_MENU_QUIT => DesktopAppMenuAction::QuitApp,
|
||||
_ => DesktopAppMenuAction::Ignore,
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_main_window_history_back(app: &tauri::AppHandle) -> tauri::Result<()> {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
window.eval(DESKTOP_HISTORY_BACK_SCRIPT)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn eval_main_window_history_forward(app: &tauri::AppHandle) -> tauri::Result<()> {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
window.eval(DESKTOP_HISTORY_FORWARD_SCRIPT)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_desktop_app_menu_action(app: &tauri::AppHandle, action: DesktopAppMenuAction) {
|
||||
match action {
|
||||
DesktopAppMenuAction::ShowMainWindow => {
|
||||
let _ = show_main_window(app);
|
||||
}
|
||||
DesktopAppMenuAction::GoBack => {
|
||||
let _ = eval_main_window_history_back(app);
|
||||
}
|
||||
DesktopAppMenuAction::GoForward => {
|
||||
let _ = eval_main_window_history_forward(app);
|
||||
}
|
||||
DesktopAppMenuAction::ReloadMainWindow => {
|
||||
let _ = reload_main_window(app);
|
||||
}
|
||||
@@ -38,6 +69,14 @@ fn handle_desktop_app_menu_action(app: &tauri::AppHandle, action: DesktopAppMenu
|
||||
pub(crate) fn register_desktop_app_menu(app: &tauri::App) -> tauri::Result<()> {
|
||||
let show_item =
|
||||
MenuItem::with_id(app, DESKTOP_APP_MENU_SHOW, "显示主窗口", true, None::<&str>)?;
|
||||
let back_item = MenuItem::with_id(app, DESKTOP_APP_MENU_BACK, "后退", true, Some("Alt+Left"))?;
|
||||
let forward_item = MenuItem::with_id(
|
||||
app,
|
||||
DESKTOP_APP_MENU_FORWARD,
|
||||
"前进",
|
||||
true,
|
||||
Some("Alt+Right"),
|
||||
)?;
|
||||
let reload_item = MenuItem::with_id(
|
||||
app,
|
||||
DESKTOP_APP_MENU_RELOAD,
|
||||
@@ -57,7 +96,14 @@ pub(crate) fn register_desktop_app_menu(app: &tauri::App) -> tauri::Result<()> {
|
||||
app,
|
||||
"Genarrative",
|
||||
true,
|
||||
&[&show_item, &reload_item, &app_separator, &quit_item],
|
||||
&[
|
||||
&show_item,
|
||||
&back_item,
|
||||
&forward_item,
|
||||
&reload_item,
|
||||
&app_separator,
|
||||
&quit_item,
|
||||
],
|
||||
)?;
|
||||
|
||||
let undo_item = PredefinedMenuItem::undo(app, Some("撤销"))?;
|
||||
@@ -120,6 +166,14 @@ mod tests {
|
||||
resolve_desktop_app_menu_action(DESKTOP_APP_MENU_SHOW),
|
||||
DesktopAppMenuAction::ShowMainWindow
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_desktop_app_menu_action(DESKTOP_APP_MENU_BACK),
|
||||
DesktopAppMenuAction::GoBack
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_desktop_app_menu_action(DESKTOP_APP_MENU_FORWARD),
|
||||
DesktopAppMenuAction::GoForward
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_desktop_app_menu_action(DESKTOP_APP_MENU_RELOAD),
|
||||
DesktopAppMenuAction::ReloadMainWindow
|
||||
@@ -133,4 +187,13 @@ mod tests {
|
||||
DesktopAppMenuAction::Ignore
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desktop_app_menu_history_scripts_are_fixed_browser_history_calls() {
|
||||
assert_eq!(DESKTOP_HISTORY_BACK_SCRIPT, "window.history.back(); true;");
|
||||
assert_eq!(
|
||||
DESKTOP_HISTORY_FORWARD_SCRIPT,
|
||||
"window.history.forward(); true;"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2506,7 +2506,7 @@
|
||||
## 2026-06-18 桌面壳应用菜单
|
||||
|
||||
- 背景:桌面壳方案要求 Tauri 承接系统菜单,但当前桌面壳只有系统托盘菜单和 HostBridge 受控能力;可分发桌面包缺少常规应用菜单会让刷新、退出、系统编辑和窗口操作只能依赖 WebView 或托盘。
|
||||
- 决策:新增 `apps/desktop-shell/src-tauri/src/shell/menu.rs` 注册 Tauri 应用菜单。应用菜单只复用宿主壳级显示主窗口、刷新主窗口和退出应用动作;编辑菜单和窗口菜单使用 Tauri 原生预定义项承接剪切、复制、粘贴、全选、最小化、最大化和关闭窗口。该能力不进入 HostBridge capability,不开放菜单 API、shell API 或任意窗口控制给 H5;菜单注册失败直接阻断启动,避免生产桌面壳缺少系统菜单仍静默运行。
|
||||
- 决策:新增 `apps/desktop-shell/src-tauri/src/shell/menu.rs` 注册 Tauri 应用菜单。应用菜单只复用宿主壳级显示主窗口、后退、前进、刷新主窗口和退出应用动作;后退 / 前进只执行固定 `window.history.back(); true;` 与 `window.history.forward(); true;`,无历史记录时按浏览器 no-op 处理,不新增 HostBridge method,也不接收 H5 payload 或任意脚本;编辑菜单和窗口菜单使用 Tauri 原生预定义项承接剪切、复制、粘贴、全选、最小化、最大化和关闭窗口。该能力不进入 HostBridge capability,不开放菜单 API、shell API 或任意窗口控制给 H5;菜单注册失败直接阻断启动,避免生产桌面壳缺少系统菜单仍静默运行。
|
||||
- 影响范围:`apps/desktop-shell/src-tauri/src/main.rs`、`apps/desktop-shell/src-tauri/src/shell/menu.rs`、`apps/desktop-shell/src-tauri/src/shell/tray.rs`、`apps/desktop-shell/scripts/check-config.mjs`、`scripts/check-native-shells.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`。
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 真实系统托盘,并复用品牌图标。托盘菜单只提供宿主壳级动作:显示主窗口、刷新主窗口和退出应用;左键点击托盘图标恢复并聚焦主窗口。该能力不进入 HostBridge capability 清单,不向 H5 暴露托盘 API、菜单 API、shell API 或任意窗口控制;如果当前桌面环境无法注册托盘,壳会继续启动主窗口。托盘注册成功时,用户点击主窗口关闭按钮会隐藏到托盘,必须通过托盘“退出”动作结束应用;托盘注册失败时不拦截关闭,避免窗口消失后没有恢复入口。
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 应用菜单。`shell/menu.rs` 注册应用菜单、编辑菜单和窗口菜单,其中应用菜单只复用宿主壳级动作:显示主窗口、刷新主窗口和退出应用;编辑 / 窗口项使用 Tauri 原生预定义菜单项承接系统剪切、复制、粘贴、全选、最小化、最大化和关闭窗口。该能力不进入 HostBridge capability,不向 H5 暴露菜单 API、shell API 或任意窗口控制;应用菜单注册失败视为桌面壳启动失败,避免可分发桌面包缺少系统菜单仍静默运行。
|
||||
2026-06-18 追加:桌面壳启用 Tauri 应用菜单。`shell/menu.rs` 注册应用菜单、编辑菜单和窗口菜单,其中应用菜单只复用宿主壳级动作:显示主窗口、后退、前进、刷新主窗口和退出应用;后退 / 前进只执行固定 `window.history.back(); true;` 与 `window.history.forward(); true;`,无历史记录时按浏览器 no-op 处理,不新增 HostBridge method,也不接收 H5 payload 或任意脚本;编辑 / 窗口项使用 Tauri 原生预定义菜单项承接系统剪切、复制、粘贴、全选、最小化、最大化和关闭窗口。该能力不进入 HostBridge capability,不向 H5 暴露菜单 API、shell API 或任意窗口控制;应用菜单注册失败视为桌面壳启动失败,避免可分发桌面包缺少系统菜单仍静默运行。
|
||||
|
||||
2026-06-18 追加:桌面壳启用 Tauri 单实例。用户重复启动桌面 App 时,新实例会退出并唤醒已有主窗口;该回调只执行显示、取消最小化和聚焦主窗口,不把第二实例的命令行参数或工作目录作为事件透传给 H5。Windows / Linux 上由单实例插件的 `deep-link` feature 把二次实例 URL 交给 deep-link 插件,仍由 `shell/deep_link.rs` 做受控归一。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user