@@ -10,6 +10,7 @@ mod usage;
1010
1111use crate :: { core:: AppCore , models:: * } ;
1212use std:: {
13+ ffi:: OsString ,
1314 path:: { Path , PathBuf } ,
1415 sync:: atomic:: { AtomicBool , AtomicU64 , Ordering } ,
1516 time:: { Duration , Instant } ,
@@ -21,6 +22,7 @@ use tauri::{
2122} ;
2223#[ cfg( target_os = "macos" ) ]
2324use tauri_plugin_autostart:: MacosLauncher ;
25+ use tauri_plugin_autostart:: ManagerExt ;
2426
2527#[ derive( Debug , serde:: Serialize ) ]
2628#[ serde( rename_all = "camelCase" ) ]
@@ -385,6 +387,8 @@ fn reveal_main<R: Runtime>(app: &tauri::AppHandle<R>) -> bool {
385387 let Some ( window) = app. get_webview_window ( "main" ) else {
386388 return false ;
387389 } ;
390+ #[ cfg( target_os = "macos" ) ]
391+ let _ = app. set_activation_policy ( tauri:: ActivationPolicy :: Regular ) ;
388392 let _ = window. show ( ) ;
389393 let _ = window. unminimize ( ) ;
390394 let _ = window. set_focus ( ) ;
@@ -552,15 +556,20 @@ fn health_check_due(minutes: u32, elapsed: Duration, needs_initial_discovery: bo
552556 && ( needs_initial_discovery || elapsed >= Duration :: from_secs ( u64:: from ( minutes) * 60 ) )
553557}
554558
559+ fn is_background_launch ( args : impl IntoIterator < Item = OsString > ) -> bool {
560+ args. into_iter ( ) . any ( |arg| arg == "--background" )
561+ }
562+
555563pub fn run ( ) {
556- let autostart = tauri_plugin_autostart:: Builder :: new ( ) ;
564+ let background_launch = is_background_launch ( std:: env:: args_os ( ) ) ;
565+ let autostart = tauri_plugin_autostart:: Builder :: new ( ) . arg ( "--background" ) ;
557566 #[ cfg( target_os = "macos" ) ]
558567 let autostart = autostart. macos_launcher ( MacosLauncher :: LaunchAgent ) ;
559568
560569 let app = tauri:: Builder :: default ( )
561570 . plugin ( tauri_plugin_dialog:: init ( ) )
562571 . plugin ( autostart. build ( ) )
563- . setup ( |app| {
572+ . setup ( move |app| {
564573 let data_dir: PathBuf = app
565574 . path ( )
566575 . app_data_dir ( )
@@ -579,12 +588,23 @@ pub fn run() {
579588 if app. state :: < AppCore > ( ) . snapshot ( ) ?. settings . mcp_enabled {
580589 mcp:: start_enabled_server ( app. handle ( ) . clone ( ) ) ;
581590 }
591+ // Existing login items need the new background argument as well.
592+ if app. autolaunch ( ) . is_enabled ( ) . unwrap_or ( false ) {
593+ let _ = app. autolaunch ( ) . enable ( ) ;
594+ }
595+ if !background_launch {
596+ reveal_main ( app. handle ( ) ) ;
597+ }
582598 Ok ( ( ) )
583599 } )
584600 . on_window_event ( |window, event| {
585601 if let tauri:: WindowEvent :: CloseRequested { api, .. } = event {
586602 api. prevent_close ( ) ;
587603 let _ = window. hide ( ) ;
604+ #[ cfg( target_os = "macos" ) ]
605+ let _ = window
606+ . app_handle ( )
607+ . set_activation_policy ( tauri:: ActivationPolicy :: Accessory ) ;
588608 }
589609 } )
590610 . invoke_handler ( tauri:: generate_handler![
@@ -618,6 +638,14 @@ pub fn run() {
618638 . build ( tauri:: generate_context!( ) )
619639 . expect ( "error while building GitBoost" ) ;
620640
641+ // macOS applies the initial policy before the event loop starts, earlier than setup.
642+ #[ cfg( target_os = "macos" ) ]
643+ let mut app = app;
644+ #[ cfg( target_os = "macos" ) ]
645+ if background_launch {
646+ app. set_activation_policy ( tauri:: ActivationPolicy :: Accessory ) ;
647+ }
648+
621649 app. run ( |app, event| {
622650 #[ cfg( target_os = "macos" ) ]
623651 if let tauri:: RunEvent :: Reopen { .. } = event {
@@ -632,13 +660,23 @@ pub fn run() {
632660#[ cfg( test) ]
633661mod tests {
634662 use super :: {
635- health_check_due, project_link, reveal_main, run_node_test, should_reveal_main ,
636- tray_labels, CommandError ,
663+ health_check_due, is_background_launch , project_link, reveal_main, run_node_test,
664+ should_reveal_main , tray_labels, CommandError ,
637665 } ;
638666 use crate :: models:: { HealthSummary , NodeDefinition , NodeEntry , Settings } ;
667+ use std:: ffi:: OsString ;
639668 use std:: time:: Duration ;
640669 use tauri:: tray:: { MouseButton , MouseButtonState } ;
641670
671+ #[ test]
672+ fn background_launch_requires_explicit_argument ( ) {
673+ assert ! ( is_background_launch( [
674+ OsString :: from( "GitBoost" ) ,
675+ OsString :: from( "--background" )
676+ ] ) ) ;
677+ assert ! ( !is_background_launch( [ OsString :: from( "GitBoost" ) ] ) ) ;
678+ }
679+
642680 #[ test]
643681 fn command_errors_serialize_with_a_stable_frontend_contract ( ) {
644682 assert_eq ! (
0 commit comments