diff --git a/.changes/tauri-ready-event.md b/.changes/tauri-ready-event.md new file mode 100644 index 000000000..1e6b78101 --- /dev/null +++ b/.changes/tauri-ready-event.md @@ -0,0 +1,7 @@ +--- +"tauri": minor +"tauri-runtime": minor +"tauri-runtime-wry": minor +--- + +Add `Event::Ready` on the `run()` callback. Triggered once when the event loop is ready. diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index 13480b741..70fc132f8 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -44,7 +44,7 @@ use wry::{ PhysicalPosition as WryPhysicalPosition, PhysicalSize as WryPhysicalSize, Position as WryPosition, Size as WrySize, }, - event::{Event, WindowEvent as WryWindowEvent}, + event::{Event, StartCause, WindowEvent as WryWindowEvent}, event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget}, global_shortcut::{GlobalShortcut, ShortcutManager as WryShortcutManager}, menu::{ @@ -1781,6 +1781,10 @@ fn handle_event_loop( *control_flow = ControlFlow::Wait; match event { + Event::NewEvents(StartCause::Init) => { + callback(RunEvent::Ready); + } + Event::GlobalShortcutEvent(accelerator_id) => { for (id, handler) in &*global_shortcut_manager_handle.listeners.lock().unwrap() { if accelerator_id == *id { diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index e44a8e72b..247d7bf09 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -184,6 +184,8 @@ pub enum RunEvent { }, /// Window closed. WindowClose(String), + /// Application ready. + Ready, } /// Action to take when the event loop is about to exit diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 291d3a515..92864818c 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -95,6 +95,8 @@ pub enum Event { }, /// Window closed. WindowClosed(String), + /// Application ready. + Ready, } /// A menu event that was triggered on a window. @@ -438,6 +440,7 @@ impl App { api: CloseRequestApi(signal_tx), }, RunEvent::WindowClose(label) => Event::WindowClosed(label), + RunEvent::Ready => Event::Ready, _ => unimplemented!(), }, ); diff --git a/examples/api/src-tauri/src/main.rs b/examples/api/src-tauri/src/main.rs index 7d597198b..51f6f3be5 100644 --- a/examples/api/src-tauri/src/main.rs +++ b/examples/api/src-tauri/src/main.rs @@ -15,8 +15,8 @@ use std::path::PathBuf; use serde::Serialize; use tauri::{ - api::dialog::ask, CustomMenuItem, Event, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, - WindowBuilder, WindowUrl, + api::dialog::ask, async_runtime, CustomMenuItem, Event, GlobalShortcutManager, Manager, + SystemTray, SystemTrayEvent, SystemTrayMenu, WindowBuilder, WindowUrl, }; #[derive(Serialize)] @@ -55,7 +55,8 @@ fn main() { .add_item(CustomMenuItem::new("toggle", "Toggle")) .add_item(CustomMenuItem::new("new", "New window")) .add_item(CustomMenuItem::new("icon_1", "Tray Icon 1")) - .add_item(CustomMenuItem::new("icon_2", "Tray Icon 2")), + .add_item(CustomMenuItem::new("icon_2", "Tray Icon 2")) + .add_item(CustomMenuItem::new("exit_app", "Quit")), ), ) .on_system_tray_event(|app, event| match event { @@ -71,6 +72,10 @@ fn main() { SystemTrayEvent::MenuItemClick { id, .. } => { let item_handle = app.tray_handle().get_item(&id); match id.as_str() { + "exit_app" => { + // exit the app + app.exit(0); + } "toggle" => { let window = app.get_window("main").unwrap(); let new_title = if window.is_visible().unwrap() { @@ -157,15 +162,42 @@ fn main() { #[cfg(target_os = "macos")] app.set_activation_policy(tauri::ActivationPolicy::Regular); - app.run(|app_handle, e| { - if let Event::CloseRequested { label, api, .. } = e { - api.prevent_close(); + app.run(|app_handle, e| match e { + // Application is ready (triggered only once) + Event::Ready => { let app_handle = app_handle.clone(); + // launch a new thread so it doesnt block any channel + async_runtime::spawn(async move { + let app_handle = app_handle.clone(); + app_handle + .global_shortcut_manager() + .register("CmdOrCtrl+1", move || { + let app_handle = app_handle.clone(); + let window = app_handle.get_window("main").unwrap(); + window.set_title("New title!").unwrap(); + }) + .unwrap(); + }); + } + + // Triggered when a window is trying to close + Event::CloseRequested { label, api, .. } => { + let app_handle = app_handle.clone(); + // use the exposed close api, and prevent the event loop to close + api.prevent_close(); + // ask the user if he wants to quit ask("Tauri API", "Are you sure?", move |answer| { if answer { app_handle.get_window(&label).unwrap().close().unwrap(); } }); } + + // Keep the event loop running even if all windows are closed + // This allow us to catch system tray events when there is no window + Event::ExitRequested { api, .. } => { + api.prevent_exit(); + } + _ => {} }) }