@@ -25,7 +25,11 @@ use crate::{
2525
2626use tauri_utils:: PackageInfo ;
2727
28- use std:: { collections:: HashMap , path:: PathBuf , sync:: Arc } ;
28+ use std:: {
29+ collections:: HashMap ,
30+ path:: PathBuf ,
31+ sync:: { mpsc:: Sender , Arc } ,
32+ } ;
2933
3034#[ cfg( feature = "menu" ) ]
3135use crate :: runtime:: menu:: Menu ;
@@ -45,6 +49,33 @@ pub(crate) type GlobalWindowEventListener<P> = Box<dyn Fn(GlobalWindowEvent<P>)
4549type SystemTrayEventListener < P > =
4650 Box < dyn Fn ( & AppHandle < P > , tray:: SystemTrayEvent < <P as Params >:: SystemTrayMenuId > ) + Send + Sync > ;
4751
52+ /// Api exposed on the `CloseRequested` event.
53+ pub struct CloseRequestApi ( Sender < bool > ) ;
54+
55+ impl CloseRequestApi {
56+ /// Prevents the window from being closed.
57+ pub fn prevent_close ( & self ) {
58+ self . 0 . send ( true ) . unwrap ( ) ;
59+ }
60+ }
61+
62+ /// An application event, triggered from the event loop.
63+ #[ non_exhaustive]
64+ pub enum Event < P : Params > {
65+ /// Event loop is exiting.
66+ Exit ,
67+ /// Window close was requested by the user.
68+ #[ non_exhaustive]
69+ CloseRequested {
70+ /// The window label.
71+ label : P :: Label ,
72+ /// Event API.
73+ api : CloseRequestApi ,
74+ } ,
75+ /// Window closed.
76+ WindowClosed ( P :: Label ) ,
77+ }
78+
4879crate :: manager:: default_args! {
4980 /// A menu event that was triggered on a window.
5081 #[ cfg( feature = "menu" ) ]
@@ -271,6 +302,42 @@ impl<P: Params> App<P> {
271302 self . handle . clone ( )
272303 }
273304
305+ /// Runs the application.
306+ pub fn run < F : Fn ( & AppHandle < P > , Event < P > ) + ' static > ( mut self , callback : F ) {
307+ let app_handle = self . handle ( ) ;
308+ let manager = self . manager . clone ( ) ;
309+ self . runtime . take ( ) . unwrap ( ) . run ( move |event| match event {
310+ RunEvent :: Exit => {
311+ #[ cfg( shell_execute) ]
312+ {
313+ crate :: api:: process:: kill_children ( ) ;
314+ }
315+ #[ cfg( all( windows, feature = "system-tray" ) ) ]
316+ {
317+ let _ = app_handle. remove_system_tray ( ) ;
318+ }
319+ callback ( & app_handle, Event :: Exit ) ;
320+ }
321+ _ => {
322+ on_event_loop_event ( & event, & manager) ;
323+ callback (
324+ & app_handle,
325+ match event {
326+ RunEvent :: Exit => Event :: Exit ,
327+ RunEvent :: CloseRequested { label, signal_tx } => Event :: CloseRequested {
328+ label : label. parse ( ) . unwrap_or_else ( |_| unreachable ! ( ) ) ,
329+ api : CloseRequestApi ( signal_tx) ,
330+ } ,
331+ RunEvent :: WindowClose ( label) => {
332+ Event :: WindowClosed ( label. parse ( ) . unwrap_or_else ( |_| unreachable ! ( ) ) )
333+ }
334+ _ => unimplemented ! ( ) ,
335+ } ,
336+ ) ;
337+ }
338+ } ) ;
339+ }
340+
274341 /// Runs a iteration of the runtime event loop and immediately return.
275342 ///
276343 /// Note that when using this API, app cleanup is not automatically done.
@@ -297,7 +364,7 @@ impl<P: Params> App<P> {
297364 . runtime
298365 . as_mut ( )
299366 . unwrap ( )
300- . run_iteration ( move |event| on_event_loop_event ( event, & manager) )
367+ . run_iteration ( move |event| on_event_loop_event ( & event, & manager) )
301368 }
302369}
303370
@@ -855,28 +922,12 @@ where
855922
856923 /// Runs the configured Tauri application.
857924 pub fn run ( self , context : Context < A > ) -> crate :: Result < ( ) > {
858- let mut app = self . build ( context) ?;
859- #[ cfg( all( windows, feature = "system-tray" ) ) ]
860- let app_handle = app. handle ( ) ;
861- let manager = app. manager . clone ( ) ;
862- app. runtime . take ( ) . unwrap ( ) . run ( move |event| match event {
863- RunEvent :: Exit => {
864- #[ cfg( shell_execute) ]
865- {
866- crate :: api:: process:: kill_children ( ) ;
867- }
868- #[ cfg( all( windows, feature = "system-tray" ) ) ]
869- {
870- let _ = app_handle. remove_system_tray ( ) ;
871- }
872- }
873- _ => on_event_loop_event ( event, & manager) ,
874- } ) ;
925+ self . build ( context) ?. run ( |_, _| { } ) ;
875926 Ok ( ( ) )
876927 }
877928}
878929
879- fn on_event_loop_event < P : Params > ( event : RunEvent , manager : & WindowManager < P > ) {
930+ fn on_event_loop_event < P : Params > ( event : & RunEvent , manager : & WindowManager < P > ) {
880931 if let RunEvent :: WindowClose ( label) = event {
881932 manager. on_window_close ( label) ;
882933 }
0 commit comments