desktop.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. use std::sync::atomic::{AtomicBool, Ordering};
  2. use tauri::{
  3. api::{
  4. dialog::{ask, MessageDialogBuilder, MessageDialogButtons},
  5. shell,
  6. },
  7. CustomMenuItem, GlobalShortcutManager, Manager, RunEvent, SystemTray, SystemTrayEvent,
  8. SystemTrayMenu, WindowBuilder, WindowEvent, WindowUrl,
  9. };
  10. pub fn main() {
  11. api::AppBuilder::new()
  12. .setup(|app| {
  13. create_tray(app)?;
  14. Ok(())
  15. })
  16. .on_event(|app_handle, e| match e {
  17. // Application is ready (triggered only once)
  18. RunEvent::Ready => {
  19. let app_handle = app_handle.clone();
  20. app_handle
  21. .global_shortcut_manager()
  22. .register("CmdOrCtrl+1", move || {
  23. let app_handle = app_handle.clone();
  24. let window = app_handle.get_window("main").unwrap();
  25. window.set_title("New title!").unwrap();
  26. })
  27. .unwrap();
  28. }
  29. // Triggered when a window is trying to close
  30. RunEvent::WindowEvent {
  31. label,
  32. event: WindowEvent::CloseRequested { api, .. },
  33. ..
  34. } => {
  35. // for other windows, we handle it in JS
  36. if label == "main" {
  37. let app_handle = app_handle.clone();
  38. let window = app_handle.get_window(&label).unwrap();
  39. // use the exposed close api, and prevent the event loop to close
  40. api.prevent_close();
  41. // ask the user if he wants to quit
  42. ask(
  43. Some(&window),
  44. "Tauri API",
  45. "Are you sure that you want to close this window?",
  46. move |answer| {
  47. if answer {
  48. // .close() cannot be called on the main thread
  49. std::thread::spawn(move || {
  50. app_handle.get_window(&label).unwrap().close().unwrap();
  51. });
  52. }
  53. },
  54. );
  55. }
  56. }
  57. _ => (),
  58. })
  59. .run()
  60. }
  61. fn create_tray(app: &tauri::App) -> tauri::Result<()> {
  62. let mut tray_menu1 = SystemTrayMenu::new()
  63. .add_item(CustomMenuItem::new("toggle", "Toggle"))
  64. .add_item(CustomMenuItem::new("new", "New window"))
  65. .add_item(CustomMenuItem::new("icon_1", "Tray Icon 1"))
  66. .add_item(CustomMenuItem::new("icon_2", "Tray Icon 2"));
  67. #[cfg(target_os = "macos")]
  68. {
  69. tray_menu1 = tray_menu1.add_item(CustomMenuItem::new("set_title", "Set Title"));
  70. }
  71. tray_menu1 = tray_menu1
  72. .add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
  73. .add_item(CustomMenuItem::new("about", "About"))
  74. .add_item(CustomMenuItem::new("exit_app", "Quit"))
  75. .add_item(CustomMenuItem::new("destroy", "Destroy"));
  76. let tray_menu2 = SystemTrayMenu::new()
  77. .add_item(CustomMenuItem::new("toggle", "Toggle"))
  78. .add_item(CustomMenuItem::new("new", "New window"))
  79. .add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
  80. .add_item(CustomMenuItem::new("about", "About"))
  81. .add_item(CustomMenuItem::new("exit_app", "Quit"))
  82. .add_item(CustomMenuItem::new("destroy", "Destroy"));
  83. let is_menu1 = AtomicBool::new(true);
  84. let handle = app.handle();
  85. let tray_id = "my-tray".to_string();
  86. SystemTray::new()
  87. .with_id(&tray_id)
  88. .with_menu(tray_menu1.clone())
  89. .on_event(move |event| {
  90. let tray_handle = handle.tray_handle_by_id(&tray_id).unwrap();
  91. match event {
  92. SystemTrayEvent::LeftClick {
  93. position: _,
  94. size: _,
  95. ..
  96. } => {
  97. let window = handle.get_window("main").unwrap();
  98. window.show().unwrap();
  99. window.set_focus().unwrap();
  100. }
  101. SystemTrayEvent::MenuItemClick { id, .. } => {
  102. let item_handle = tray_handle.get_item(&id);
  103. match id.as_str() {
  104. "exit_app" => {
  105. // exit the app
  106. handle.exit(0);
  107. }
  108. "destroy" => {
  109. tray_handle.destroy().unwrap();
  110. }
  111. "toggle" => {
  112. let window = handle.get_window("main").unwrap();
  113. let new_title = if window.is_visible().unwrap() {
  114. window.hide().unwrap();
  115. "Show"
  116. } else {
  117. window.show().unwrap();
  118. "Hide"
  119. };
  120. item_handle.set_title(new_title).unwrap();
  121. }
  122. "new" => {
  123. WindowBuilder::new(&handle, "new", WindowUrl::App("index.html".into()))
  124. .title("Tauri")
  125. .build()
  126. .unwrap();
  127. }
  128. "set_title" => {
  129. #[cfg(target_os = "macos")]
  130. tray_handle.set_title("Tauri").unwrap();
  131. }
  132. "icon_1" => {
  133. #[cfg(target_os = "macos")]
  134. tray_handle.set_icon_as_template(true).unwrap();
  135. tray_handle
  136. .set_icon(tauri::Icon::Raw(
  137. include_bytes!("../../../.icons/tray_icon_with_transparency.png").to_vec(),
  138. ))
  139. .unwrap();
  140. }
  141. "icon_2" => {
  142. #[cfg(target_os = "macos")]
  143. tray_handle.set_icon_as_template(true).unwrap();
  144. tray_handle
  145. .set_icon(tauri::Icon::Raw(
  146. include_bytes!("../../../.icons/icon.ico").to_vec(),
  147. ))
  148. .unwrap();
  149. }
  150. "switch_menu" => {
  151. let flag = is_menu1.load(Ordering::Relaxed);
  152. tray_handle
  153. .set_menu(if flag {
  154. tray_menu2.clone()
  155. } else {
  156. tray_menu1.clone()
  157. })
  158. .unwrap();
  159. is_menu1.store(!flag, Ordering::Relaxed);
  160. }
  161. "about" => {
  162. let window = handle.get_window("main").unwrap();
  163. MessageDialogBuilder::new("About app", "Tauri demo app")
  164. .parent(&window)
  165. .buttons(MessageDialogButtons::OkCancelCustom(
  166. "Homepage".into(),
  167. "know it".into(),
  168. ))
  169. .show(move |ok| {
  170. if ok {
  171. shell::open(&window.shell_scope(), "https://tauri.app/", None).unwrap();
  172. }
  173. });
  174. }
  175. _ => {}
  176. }
  177. }
  178. _ => {}
  179. }
  180. })
  181. .build(app)
  182. .map(|_| ())
  183. }