The menu bar supports rich operations

This commit is contained in:
Tw93
2025-12-08 14:13:48 +08:00
parent 194d82a1c5
commit 2767fc1b94
6 changed files with 301 additions and 47 deletions

View File

@@ -9,6 +9,9 @@ use tauri_plugin_window_state::StateFlags;
#[cfg(target_os = "macos")]
use std::time::Duration;
use tauri::menu::{AboutMetadata, Menu, MenuItem, PredefinedMenuItem, Submenu};
use tauri_plugin_opener::OpenerExt; // Add this
use app::{
invoke::{download_file, download_file_by_binary, send_notification, update_theme_mode},
setup::{set_global_shortcut, set_system_tray},
@@ -42,7 +45,8 @@ pub fn run_app() {
.plugin(tauri_plugin_oauth::init())
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_notification::init());
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_opener::init()); // Add this
// Only add single instance plugin if multiple instances are not allowed
if !multi_instance {
@@ -63,6 +67,227 @@ pub fn run_app() {
update_theme_mode,
])
.setup(move |app| {
// --- Menu Construction Start ---
let pake_version = env!("CARGO_PKG_VERSION");
let pake_menu_item_title = format!("Built with Pake V{}", pake_version);
// App Menu (macOS specific, e.g., "Pake")
let app_menu = Submenu::new(app, "Pake", true)?;
let about_metadata = AboutMetadata::default();
app_menu.append(&PredefinedMenuItem::about(
app,
Some("Pake"),
Some(about_metadata),
)?)?;
app_menu.append(&PredefinedMenuItem::separator(app)?)?;
app_menu.append(&PredefinedMenuItem::services(app, None)?)?;
app_menu.append(&PredefinedMenuItem::separator(app)?)?;
app_menu.append(&PredefinedMenuItem::hide(app, None)?)?;
app_menu.append(&PredefinedMenuItem::hide_others(app, None)?)?;
app_menu.append(&PredefinedMenuItem::show_all(app, None)?)?;
app_menu.append(&PredefinedMenuItem::separator(app)?)?;
app_menu.append(&PredefinedMenuItem::quit(app, None)?)?;
// File Menu
let file_menu = Submenu::new(app, "File", true)?;
file_menu.append(&PredefinedMenuItem::close_window(app, None)?)?;
// Edit Menu
let edit_menu = Submenu::new(app, "Edit", true)?;
edit_menu.append(&PredefinedMenuItem::undo(app, None)?)?;
edit_menu.append(&PredefinedMenuItem::redo(app, None)?)?;
edit_menu.append(&PredefinedMenuItem::separator(app)?)?;
edit_menu.append(&PredefinedMenuItem::cut(app, None)?)?;
edit_menu.append(&PredefinedMenuItem::copy(app, None)?)?;
edit_menu.append(&PredefinedMenuItem::paste(app, None)?)?;
edit_menu.append(&PredefinedMenuItem::select_all(app, None)?)?;
edit_menu.append(&PredefinedMenuItem::separator(app)?)?;
edit_menu.append(&MenuItem::with_id(
app,
"copy_url",
"Copy URL",
true,
Some("CmdOrCtrl+L"),
)?)?;
// View Menu
let view_menu = Submenu::new(app, "View", true)?;
view_menu.append(&MenuItem::with_id(
app,
"reload",
"Reload",
true,
Some("CmdOrCtrl+R"),
)?)?;
view_menu.append(&PredefinedMenuItem::separator(app)?)?;
view_menu.append(&MenuItem::with_id(
app,
"zoom_in",
"Zoom In",
true,
Some("CmdOrCtrl+="),
)?)?;
view_menu.append(&MenuItem::with_id(
app,
"zoom_out",
"Zoom Out",
true,
Some("CmdOrCtrl+-"),
)?)?;
view_menu.append(&MenuItem::with_id(
app,
"zoom_reset",
"Actual Size",
true,
Some("CmdOrCtrl+0"),
)?)?;
view_menu.append(&PredefinedMenuItem::separator(app)?)?;
view_menu.append(&PredefinedMenuItem::fullscreen(app, None)?)?;
view_menu.append(&PredefinedMenuItem::separator(app)?)?;
view_menu.append(&MenuItem::with_id(
app,
"toggle_devtools",
"Toggle Developer Tools",
cfg!(debug_assertions),
Some("CmdOrCtrl+Option+I"),
)?)?;
// Navigation Menu
let navigation_menu = Submenu::new(app, "Navigation", true)?;
navigation_menu.append(&MenuItem::with_id(
app,
"go_back",
"Back",
true,
Some("CmdOrCtrl+["),
)?)?;
navigation_menu.append(&MenuItem::with_id(
app,
"go_forward",
"Forward",
true,
Some("CmdOrCtrl+]"),
)?)?;
navigation_menu.append(&MenuItem::with_id(
app,
"go_home",
"Go Home",
true,
Some("CmdOrCtrl+Shift+H"),
)?)?;
// Window Menu
let window_menu = Submenu::new(app, "Window", true)?;
window_menu.append(&PredefinedMenuItem::minimize(app, None)?)?;
window_menu.append(&PredefinedMenuItem::maximize(app, None)?)?;
window_menu.append(&PredefinedMenuItem::separator(app)?)?;
window_menu.append(&MenuItem::with_id(
app,
"always_on_top",
"Toggle Always on Top",
true,
None::<&str>,
)?)?;
window_menu.append(&PredefinedMenuItem::separator(app)?)?;
window_menu.append(&PredefinedMenuItem::close_window(app, None)?)?;
// Help Menu (Custom)
let help_menu = Submenu::new(app, "Help", true)?;
let github_item = MenuItem::with_id(
app,
"pake_github_link",
&pake_menu_item_title,
true,
None::<&str>,
)?;
help_menu.append(&github_item)?;
// Construct the Menu Bar
let menu = Menu::with_items(
app,
&[
&app_menu,
&file_menu,
&edit_menu,
&view_menu,
&navigation_menu,
&window_menu,
&help_menu,
],
)?;
app.set_menu(menu)?;
// Event Handling for Custom Menu Item
app.on_menu_event(move |app_handle, event| {
match event.id().as_ref() {
"pake_github_link" => {
let _ = app_handle
.opener()
.open_url("https://github.com/tw93/Pake", None::<&str>);
}
"reload" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("window.location.reload()");
}
}
"toggle_devtools" => {
#[cfg(debug_assertions)] // Only allow in debug builds
if let Some(window) = app_handle.get_webview_window("pake") {
if window.is_devtools_open() {
window.close_devtools();
} else {
window.open_devtools();
}
}
}
"zoom_in" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("zoomIn()");
}
}
"zoom_out" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("zoomOut()");
}
}
"zoom_reset" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("setZoom('100%')");
}
}
"go_back" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("window.history.back()");
}
}
"go_forward" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("window.history.forward()");
}
}
"go_home" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ = window.eval("window.location.href = window.pakeConfig.url");
}
}
"copy_url" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let _ =
window.eval("navigator.clipboard.writeText(window.location.href)");
}
}
"always_on_top" => {
if let Some(window) = app_handle.get_webview_window("pake") {
let is_on_top = window.is_always_on_top().unwrap_or(false);
let _ = window.set_always_on_top(!is_on_top);
}
}
_ => {}
}
});
// --- Menu Construction End ---
let window = set_window(app, &pake_config, &tauri_config);
set_system_tray(
app.app_handle(),