tray.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. use crate::{config::Config, feat, utils::resolve};
  2. use anyhow::Result;
  3. use tauri::{
  4. api, AppHandle, CustomMenuItem, Manager, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
  5. SystemTraySubmenu,
  6. };
  7. pub struct Tray {}
  8. impl Tray {
  9. pub fn tray_menu(app_handle: &AppHandle) -> SystemTrayMenu {
  10. let zh = { Config::verge().latest().language == Some("zh".into()) };
  11. let version = app_handle.package_info().version.to_string();
  12. if zh {
  13. SystemTrayMenu::new()
  14. .add_item(CustomMenuItem::new("open_window", "打开面板"))
  15. .add_native_item(SystemTrayMenuItem::Separator)
  16. .add_item(CustomMenuItem::new("rule_mode", "规则模式"))
  17. .add_item(CustomMenuItem::new("global_mode", "全局模式"))
  18. .add_item(CustomMenuItem::new("direct_mode", "直连模式"))
  19. .add_item(CustomMenuItem::new("script_mode", "脚本模式"))
  20. .add_native_item(SystemTrayMenuItem::Separator)
  21. .add_item(CustomMenuItem::new("system_proxy", "系统代理"))
  22. .add_item(CustomMenuItem::new("tun_mode", "TUN 模式"))
  23. .add_submenu(SystemTraySubmenu::new(
  24. "更多",
  25. SystemTrayMenu::new()
  26. .add_item(CustomMenuItem::new("restart_clash", "重启 Clash"))
  27. .add_item(CustomMenuItem::new("restart_app", "重启应用"))
  28. .add_item(
  29. CustomMenuItem::new("app_version", format!("Version {version}"))
  30. .disabled(),
  31. ),
  32. ))
  33. .add_native_item(SystemTrayMenuItem::Separator)
  34. .add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q"))
  35. } else {
  36. SystemTrayMenu::new()
  37. .add_item(CustomMenuItem::new("open_window", "Dashboard"))
  38. .add_native_item(SystemTrayMenuItem::Separator)
  39. .add_item(CustomMenuItem::new("rule_mode", "Rule Mode"))
  40. .add_item(CustomMenuItem::new("global_mode", "Global Mode"))
  41. .add_item(CustomMenuItem::new("direct_mode", "Direct Mode"))
  42. .add_item(CustomMenuItem::new("script_mode", "Script Mode"))
  43. .add_native_item(SystemTrayMenuItem::Separator)
  44. .add_item(CustomMenuItem::new("system_proxy", "System Proxy"))
  45. .add_item(CustomMenuItem::new("tun_mode", "Tun Mode"))
  46. .add_submenu(SystemTraySubmenu::new(
  47. "More",
  48. SystemTrayMenu::new()
  49. .add_item(CustomMenuItem::new("restart_clash", "Restart Clash"))
  50. .add_item(CustomMenuItem::new("restart_app", "Restart App"))
  51. .add_item(
  52. CustomMenuItem::new("app_version", format!("Version {version}"))
  53. .disabled(),
  54. ),
  55. ))
  56. .add_native_item(SystemTrayMenuItem::Separator)
  57. .add_item(CustomMenuItem::new("quit", "Quit").accelerator("CmdOrControl+Q"))
  58. }
  59. }
  60. pub fn update_systray(app_handle: &AppHandle) -> Result<()> {
  61. app_handle
  62. .tray_handle()
  63. .set_menu(Tray::tray_menu(app_handle))?;
  64. Tray::update_part(app_handle)?;
  65. Ok(())
  66. }
  67. pub fn update_part(app_handle: &AppHandle) -> Result<()> {
  68. let mode = {
  69. Config::clash()
  70. .latest()
  71. .0
  72. .get("mode")
  73. .map(|val| val.as_str().unwrap_or("rule"))
  74. .unwrap_or("rule")
  75. .to_owned()
  76. };
  77. let tray = app_handle.tray_handle();
  78. let _ = tray.get_item("rule_mode").set_selected(mode == "rule");
  79. let _ = tray.get_item("global_mode").set_selected(mode == "global");
  80. let _ = tray.get_item("direct_mode").set_selected(mode == "direct");
  81. let _ = tray.get_item("script_mode").set_selected(mode == "script");
  82. let verge = Config::verge();
  83. let verge = verge.latest();
  84. let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
  85. let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
  86. let _ = tray.get_item("system_proxy").set_selected(*system_proxy);
  87. let _ = tray.get_item("tun_mode").set_selected(*tun_mode);
  88. Ok(())
  89. }
  90. pub fn on_system_tray_event(app_handle: &AppHandle, event: SystemTrayEvent) {
  91. match event {
  92. SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
  93. mode @ ("rule_mode" | "global_mode" | "direct_mode" | "script_mode") => {
  94. let mode = &mode[0..mode.len() - 5];
  95. feat::change_clash_mode(mode.into());
  96. }
  97. "open_window" => resolve::create_window(app_handle),
  98. "system_proxy" => feat::toggle_system_proxy(),
  99. "tun_mode" => feat::toggle_tun_mode(),
  100. "restart_clash" => feat::restart_clash_core(),
  101. "restart_app" => api::process::restart(&app_handle.env()),
  102. "quit" => {
  103. resolve::resolve_reset();
  104. api::process::kill_children();
  105. app_handle.exit(0);
  106. std::process::exit(0);
  107. }
  108. _ => {}
  109. },
  110. #[cfg(target_os = "windows")]
  111. SystemTrayEvent::LeftClick { .. } => {
  112. resolve::create_window(app_handle);
  113. }
  114. _ => {}
  115. }
  116. }
  117. }