main.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #![cfg_attr(
  2. all(not(debug_assertions), target_os = "windows"),
  3. windows_subsystem = "windows"
  4. )]
  5. extern crate tauri;
  6. mod cmds;
  7. mod config;
  8. mod events;
  9. mod utils;
  10. use crate::{events::state, utils::clash::put_clash_profile};
  11. use std::sync::{Arc, Mutex};
  12. use tauri::{
  13. api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
  14. SystemTraySubmenu,
  15. };
  16. fn main() -> std::io::Result<()> {
  17. let sub_menu = SystemTraySubmenu::new(
  18. "出站规则",
  19. SystemTrayMenu::new()
  20. .add_item(CustomMenuItem::new("rway_global", "全局连接"))
  21. .add_item(CustomMenuItem::new("rway_rule", "规则连接").selected())
  22. .add_item(CustomMenuItem::new("rway_direct", "直接连接")),
  23. );
  24. let menu = SystemTrayMenu::new()
  25. .add_submenu(sub_menu)
  26. .add_native_item(SystemTrayMenuItem::Separator)
  27. .add_item(CustomMenuItem::new("syste_proxy", "设置为系统代理"))
  28. .add_item(CustomMenuItem::new("self_startup", "开机启动").selected())
  29. .add_item(CustomMenuItem::new("open_window", "显示应用"))
  30. .add_native_item(SystemTrayMenuItem::Separator)
  31. .add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q"));
  32. let app = tauri::Builder::default()
  33. .system_tray(SystemTray::new().with_menu(menu))
  34. .on_system_tray_event(move |app, event| match event {
  35. SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
  36. "open_window" => {
  37. let window = app.get_window("main").unwrap();
  38. window.show().unwrap();
  39. window.set_focus().unwrap();
  40. }
  41. "quit" => {
  42. api::process::kill_children();
  43. app.exit(0);
  44. }
  45. _ => {}
  46. },
  47. SystemTrayEvent::LeftClick { .. } => {
  48. let window = app.get_window("main").unwrap();
  49. window.show().unwrap();
  50. window.set_focus().unwrap();
  51. }
  52. _ => {}
  53. })
  54. .invoke_handler(tauri::generate_handler![
  55. cmds::some::restart_sidecar,
  56. cmds::some::get_clash_info,
  57. cmds::some::set_sys_proxy,
  58. cmds::profile::import_profile,
  59. cmds::profile::update_profile,
  60. cmds::profile::get_profiles,
  61. cmds::profile::set_profiles,
  62. cmds::profile::put_profiles,
  63. ])
  64. .build(tauri::generate_context!())
  65. .expect("error while running tauri application");
  66. // init app config
  67. utils::init::init_app(app.package_info());
  68. // run clash sidecar
  69. let info = utils::clash::run_clash_bin(&app.handle());
  70. // update the profile
  71. let info_copy = info.clone();
  72. tauri::async_runtime::spawn(async move {
  73. match put_clash_profile(&info_copy).await {
  74. Ok(_) => {}
  75. Err(err) => log::error!("failed to put config for `{}`", err),
  76. };
  77. });
  78. app.manage(state::ClashInfoState(Arc::new(Mutex::new(info))));
  79. app.manage(state::ProfileLock::default());
  80. app.run(|app_handle, e| match e {
  81. tauri::Event::CloseRequested { label, api, .. } => {
  82. let app_handle = app_handle.clone();
  83. api.prevent_close();
  84. app_handle.get_window(&label).unwrap().hide().unwrap();
  85. }
  86. tauri::Event::ExitRequested { api, .. } => {
  87. api.prevent_exit();
  88. }
  89. tauri::Event::Exit => {
  90. api::process::kill_children();
  91. }
  92. _ => {}
  93. });
  94. Ok(())
  95. }