@@ -12,6 +12,7 @@ use anyhow::Result;
1212use clap:: Parser ;
1313use regex:: Regex ;
1414use tauri:: {
15+ AppHandle ,
1516 Builder ,
1617 CustomMenuItem ,
1718 SystemTray ,
@@ -27,6 +28,13 @@ use crate::config::{Config, Rule};
2728
2829mod config;
2930
31+ const MENU_ITEMS : [ ( & str , & str ) ; 4 ] = [
32+ ( "digital" , "Digital" ) ,
33+ ( "analog_1" , "Analog 1" ) ,
34+ ( "analog_2" , "Analog 2" ) ,
35+ ( "analog_3" , "Analog 3" ) ,
36+ ] ;
37+
3038#[ derive( Debug , Parser ) ]
3139#[ command( author, version, about) ]
3240struct Args {
@@ -58,20 +66,27 @@ async fn main() -> Result<()> {
5866 let config = Arc :: new ( Config :: load ( ) ?) ;
5967
6068 // Poll the active window in a background task
61- let args_clone = args. clone ( ) ;
62- let config_clone = config. clone ( ) ;
69+ let args_task = args. clone ( ) ;
70+ let config_task = config. clone ( ) ;
6371 tokio:: spawn ( async move {
64- poll_active_window ( args_clone , & config_clone ) . await . unwrap ( ) ;
72+ poll_active_window ( args_task , & config_task ) . unwrap ( ) ;
6573 } ) ;
6674
67- Builder :: default ( )
75+ // Create the system tray menu and add the MENU_ITEMS
76+ let args_clone = args. clone ( ) ;
77+ let config_clone = config. clone ( ) ;
78+ let mut system_tray_menu = SystemTrayMenu :: new ( ) ;
79+ for ( id, title) in MENU_ITEMS {
80+ let menu_item = CustomMenuItem :: new ( String :: from ( id) , title) . selected ( ) ;
81+ system_tray_menu = system_tray_menu. add_item ( menu_item) ;
82+ }
83+
84+ // Create the Tauri app and add the system tray menu
85+ #[ cfg_attr( not( target_os = "macos" ) , allow( unused_mut) ) ]
86+ let mut app = Builder :: default ( )
6887 . system_tray (
6988 SystemTray :: new ( ) . with_menu (
70- SystemTrayMenu :: new ( )
71- . add_item ( CustomMenuItem :: new ( String :: from ( "digital" ) , "Digital" ) )
72- . add_item ( CustomMenuItem :: new ( String :: from ( "analog_1" ) , "Analog 1" ) )
73- . add_item ( CustomMenuItem :: new ( String :: from ( "analog_2" ) , "Analog 2" ) )
74- . add_item ( CustomMenuItem :: new ( String :: from ( "analog_3" ) , "Analog 3" ) )
89+ system_tray_menu
7590 . add_native_item ( SystemTrayMenuItem :: Separator )
7691 . add_item ( CustomMenuItem :: new ( String :: from ( "pause" ) , "Pause" ) )
7792 . add_native_item ( SystemTrayMenuItem :: Separator )
@@ -86,34 +101,68 @@ async fn main() -> Result<()> {
86101 std:: process:: exit ( 0 ) ;
87102 }
88103 "pause" => {
89- let paused = args . read ( ) . unwrap ( ) . paused ;
104+ let paused = args_clone . read ( ) . unwrap ( ) . paused ;
90105 let title = if paused { "Pause" } else { "Resume" } ;
91- args . write ( ) . unwrap ( ) . paused = !paused;
106+ args_clone . write ( ) . unwrap ( ) . paused = !paused;
92107 item_handle. set_title ( title) . unwrap ( ) ;
93108 }
94109 "digital" => {
95- set_active_profile_index ( 0 , config. send_sleep_ms ) ;
110+ set_active_profile_index ( 0 , config_clone. send_sleep_ms ) ;
111+ args_clone. write ( ) . unwrap ( ) . profile_index = Some ( 0 ) ;
96112 }
97113 "analog_1" => {
98- set_active_profile_index ( 1 , config. send_sleep_ms ) ;
114+ set_active_profile_index ( 1 , config_clone. send_sleep_ms ) ;
115+ args_clone. write ( ) . unwrap ( ) . profile_index = Some ( 1 ) ;
99116 }
100117 "analog_2" => {
101- set_active_profile_index ( 2 , config. send_sleep_ms ) ;
118+ set_active_profile_index ( 2 , config_clone. send_sleep_ms ) ;
119+ args_clone. write ( ) . unwrap ( ) . profile_index = Some ( 2 ) ;
102120 }
103121 "analog_3" => {
104- set_active_profile_index ( 3 , config. send_sleep_ms ) ;
122+ set_active_profile_index ( 3 , config_clone. send_sleep_ms ) ;
123+ args_clone. write ( ) . unwrap ( ) . profile_index = Some ( 3 ) ;
105124 }
106125 _ => { }
107126 }
108127 }
109128 } )
110- . run ( tauri:: generate_context!( ) ) ?;
129+ . build ( tauri:: generate_context!( ) ) ?;
130+
131+ #[ cfg( target_os = "macos" ) ] // Hide the macOS dock icon
132+ app. set_activation_policy ( tauri:: ActivationPolicy :: Accessory ) ;
133+
134+ // Run the Tauri app
135+ app. run ( move |app, _event| {
136+ // Poll the args in a background task
137+ let app_clone = app. clone ( ) ;
138+ let args_clone = args. clone ( ) ;
139+ let config_clone = config. clone ( ) ;
140+ tokio:: spawn ( async move {
141+ poll_args_profile ( args_clone, & config_clone, & app_clone) ;
142+ } ) ;
143+ } ) ;
111144
112145 Ok ( ( ) )
113146}
114147
148+ /// Poll the args for profile index and update the system tray menu
149+ fn poll_args_profile ( args : Arc < RwLock < Args > > , config : & Config , app : & AppHandle ) {
150+ loop {
151+ std:: thread:: sleep ( Duration :: from_millis ( config. loop_sleep_ms ) ) ;
152+
153+ if let Some ( profile_index) = args. read ( ) . unwrap ( ) . profile_index {
154+ MENU_ITEMS . iter ( ) . enumerate ( ) . for_each ( |( i, ( id, _title) ) | {
155+ let item_handle = app. tray_handle ( ) . get_item ( id) ;
156+ item_handle
157+ . set_selected ( i == profile_index as usize )
158+ . unwrap ( ) ;
159+ } )
160+ }
161+ }
162+ }
163+
115164/// Poll the active window for matching rules and apply the profile
116- async fn poll_active_window ( args : Arc < RwLock < Args > > , config : & Config ) -> Result < ( ) > {
165+ fn poll_active_window ( args : Arc < RwLock < Args > > , config : & Config ) -> Result < ( ) > {
117166 let device_info = unsafe {
118167 if !wooting_rgb_kbd_connected ( ) {
119168 println ! ( "Keyboard not connected." ) ;
@@ -131,9 +180,11 @@ async fn poll_active_window(args: Arc<RwLock<Args>>, config: &Config) -> Result<
131180
132181 let mut last_active_window: ActiveWindow = Default :: default ( ) ;
133182 let mut last_profile_index = get_active_profile_index ( device_info) ;
183+ args. write ( ) . unwrap ( ) . profile_index = Some ( last_profile_index) ;
134184
135185 loop {
136186 std:: thread:: sleep ( Duration :: from_millis ( config. loop_sleep_ms ) ) ;
187+
137188 if args. read ( ) . unwrap ( ) . paused {
138189 continue ;
139190 }
@@ -184,6 +235,7 @@ async fn poll_active_window(args: Arc<RwLock<Args>>, config: &Config) -> Result<
184235
185236 println ! ( "Process Profile Index: {}" , profile_index) ;
186237 set_active_profile_index ( profile_index, config. send_sleep_ms ) ;
238+ args. write ( ) . unwrap ( ) . profile_index = Some ( profile_index) ;
187239 }
188240}
189241
0 commit comments