@@ -37,7 +37,7 @@ impl KeyboardState {
3737
3838#[ tokio:: main]
3939async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
40- let args = set_flags ( ) . get_matches ( ) ;
40+ let args = set_command_line_args ( ) . get_matches ( ) ;
4141 env:: set_var ( "RUST_LOG" , "swhkd=warn" ) ;
4242
4343 if args. is_present ( "debug" ) {
@@ -77,14 +77,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
7777 }
7878 }
7979
80- permission_check ( ) ;
80+ if let Err ( _) = check_user_permissions ( ) {
81+ exit ( 1 ) ;
82+ }
8183
8284 let load_config = || {
8385 let config_file_path: std:: path:: PathBuf = if args. is_present ( "config" ) {
8486 Path :: new ( args. value_of ( "config" ) . unwrap ( ) ) . to_path_buf ( )
8587 } else {
86- check_config_xdg ( )
88+ fetch_xdg_config_path ( )
8789 } ;
90+
8891 log:: debug!( "Using config file path: {:#?}" , config_file_path) ;
8992
9093 if !config_file_path. exists ( ) {
@@ -99,16 +102,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
99102 }
100103 Ok ( out) => out,
101104 } ;
105+
102106 for hotkey in & hotkeys {
103107 log:: debug!( "hotkey: {:#?}" , hotkey) ;
104108 }
109+
105110 hotkeys
106111 } ;
107112
108113 let mut hotkeys = load_config ( ) ;
109114
110115 log:: trace!( "Attempting to find all keyboard file descriptors." ) ;
111- let keyboard_devices: Vec < Device > = evdev:: enumerate ( ) . filter ( check_keyboard ) . collect ( ) ;
116+ let keyboard_devices: Vec < Device > = evdev:: enumerate ( ) . filter ( check_device_is_keyboard ) . collect ( ) ;
112117
113118 let mut uinput_device = match uinput:: create_uinput_device ( ) {
114119 Ok ( dev) => dev,
@@ -143,20 +148,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
143148 250
144149 } ;
145150
146- fn send_command ( hotkey : config:: Hotkey ) {
147- log:: info!( "Hotkey pressed: {:#?}" , hotkey) ;
148- if let Err ( e) = sock_send ( & hotkey. command ) {
149- log:: error!( "Failed to send command over IPC." ) ;
150- log:: error!( "Is swhks running?" ) ;
151- log:: error!( "{:#?}" , e)
152- }
153- }
154-
155151 let mut signals = Signals :: new ( & [
156152 SIGUSR1 , SIGUSR2 , SIGHUP , SIGABRT , SIGBUS , SIGCHLD , SIGCONT , SIGINT , SIGPIPE , SIGQUIT ,
157153 SIGSYS , SIGTERM , SIGTRAP , SIGTSTP , SIGVTALRM , SIGXCPU , SIGXFSZ ,
158154 ] ) ?;
159- let mut paused = false ;
155+
156+ let mut execution_is_paused = false ;
160157 let mut last_hotkey: Option < config:: Hotkey > = None ;
161158 let mut keyboard_states: Vec < KeyboardState > = Vec :: new ( ) ;
162159 let mut keyboard_stream_map = StreamMap :: new ( ) ;
@@ -167,7 +164,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
167164 keyboard_states. push ( KeyboardState :: new ( ) ) ;
168165 }
169166
170- // the initial sleep duration is never read because last_hotkey is initialized to None
167+ // The initial sleep duration is never read because last_hotkey is initialized to None
171168 let hotkey_repeat_timer = sleep ( Duration :: from_millis ( 0 ) ) ;
172169 tokio:: pin!( hotkey_repeat_timer) ;
173170
@@ -178,47 +175,66 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
178175 send_command( hotkey. clone( ) ) ;
179176 hotkey_repeat_timer. as_mut( ) . reset( Instant :: now( ) + Duration :: from_millis( repeat_cooldown_duration) ) ;
180177 }
178+
181179 Some ( signal) = signals. next( ) => {
182180 match signal {
183181 SIGUSR1 => {
184- paused = true ;
185- for mut device in evdev:: enumerate( ) . filter( check_keyboard ) {
182+ execution_is_paused = true ;
183+ for mut device in evdev:: enumerate( ) . filter( check_device_is_keyboard ) {
186184 let _ = device. ungrab( ) ;
187185 }
188186 }
187+
189188 SIGUSR2 => {
190- paused = false ;
191- for mut device in evdev:: enumerate( ) . filter( check_keyboard ) {
189+ execution_is_paused = false ;
190+ for mut device in evdev:: enumerate( ) . filter( check_device_is_keyboard ) {
192191 let _ = device. grab( ) ;
193192 }
194193 }
194+
195195 SIGHUP => {
196196 hotkeys = load_config( ) ;
197197 }
198+
198199 SIGINT => {
199- for mut device in evdev:: enumerate( ) . filter( check_keyboard ) {
200+ for mut device in evdev:: enumerate( ) . filter( check_device_is_keyboard ) {
200201 let _ = device. ungrab( ) ;
201202 }
202203 log:: warn!( "Received SIGINT signal, exiting..." ) ;
203204 exit( 1 ) ;
204205 }
206+
205207 _ => {
208+ for ( _, mut device) in evdev:: enumerate( ) {
209+ if check_device_is_keyboard( & device) {
210+ let _ = device. ungrab( ) ;
211+ } ;
212+ }
206213 log:: warn!( "Got signal: {:#?}" , signal) ;
207214 exit( 1 ) ;
208215 }
209216 }
210217 }
218+
211219 Some ( ( i, Ok ( event) ) ) = keyboard_stream_map. next( ) => {
212- let keyboard_state = & mut keyboard_states[ i] ;
213- if let InputEventKind :: Key ( key) = event. kind( ) {
220+ let keyboard_state = & mut keyboard_states[ i] ;
221+
222+ let key = match event. kind( ) {
223+ InputEventKind :: Key ( keycode) => keycode,
224+ _ => continue
225+ } ;
226+
214227 match event. value( ) {
228+ // Key press
215229 1 => {
216230 if let Some ( modifier) = modifiers_map. get( & key) {
217231 keyboard_state. state_modifiers. insert( * modifier) ;
218232 } else {
219233 keyboard_state. state_keysyms. insert( key) ;
220234 }
221235 }
236+
237+ // Key release
222238 0 => {
223239 if let Some ( modifier) = modifiers_map. get( & key) {
224240 if let Some ( hotkey) = & last_hotkey {
@@ -236,6 +252,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
236252 keyboard_state. state_keysyms. remove( key) ;
237253 }
238254 }
255+
239256 _ => { }
240257 }
241258
@@ -257,11 +274,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
257274 uinput_device. emit( & [ event] ) . unwrap( ) ;
258275 }
259276
260- if paused || last_hotkey. is_some( ) {
261- continue ;
262- }
263-
264- if possible_hotkeys. is_empty( ) {
277+ if execution_is_paused || possible_hotkeys. is_empty( ) || last_hotkey. is_some( ) {
265278 continue ;
266279 }
267280
@@ -270,7 +283,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
270283 log:: debug!( "hotkey: {:#?}" , possible_hotkeys) ;
271284
272285 for hotkey in possible_hotkeys {
273- // this should check if state_modifiers and hotkey.modifiers have the same elements
274286 if keyboard_state. state_modifiers. iter( ) . all( |x| hotkey. modifiers. contains( x) )
275287 && keyboard_state. state_modifiers. len( ) == hotkey. modifiers. len( )
276288 && keyboard_state. state_keysyms. contains( hotkey. keysym)
@@ -283,11 +295,25 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
283295 }
284296 }
285297 }
286- }
287298 }
288299}
289300
290- pub fn permission_check ( ) {
301+ fn sock_send ( command : & str ) -> std:: io:: Result < ( ) > {
302+ let mut stream = UnixStream :: connect ( "/tmp/swhkd.sock" ) ?;
303+ stream. write_all ( command. as_bytes ( ) ) ?;
304+ Ok ( ( ) )
305+ }
306+
307+ fn send_command ( hotkey : config:: Hotkey ) {
308+ log:: info!( "Hotkey pressed: {:#?}" , hotkey) ;
309+ if let Err ( e) = sock_send ( & hotkey. command ) {
310+ log:: error!( "Failed to send command over IPC." ) ;
311+ log:: error!( "Is swhks running?" ) ;
312+ log:: error!( "{:#?}" , e)
313+ }
314+ }
315+
316+ pub fn check_user_permissions ( ) -> Result < ( ) , ( ) > {
291317 if !Uid :: current ( ) . is_root ( ) {
292318 let groups = nix:: unistd:: getgroups ( ) ;
293319 for ( _, groups) in groups. iter ( ) . enumerate ( ) {
@@ -300,13 +326,14 @@ pub fn permission_check() {
300326 }
301327 }
302328 log:: error!( "Consider using `pkexec swhkd ...`" ) ;
303- exit ( 1 ) ;
329+ Err ( ( ) )
304330 } else {
305331 log:: warn!( "Running swhkd as root!" ) ;
332+ Ok ( ( ) )
306333 }
307334}
308335
309- pub fn check_keyboard ( device : & Device ) -> bool {
336+ pub fn check_device_is_keyboard ( device : & Device ) -> bool {
310337 if device. supported_keys ( ) . map_or ( false , |keys| keys. contains ( Key :: KEY_ENTER ) ) {
311338 if device. name ( ) == Some ( "swhkd virtual output" ) {
312339 return false ;
@@ -319,7 +346,7 @@ pub fn check_keyboard(device: &Device) -> bool {
319346 }
320347}
321348
322- pub fn set_flags ( ) -> Command < ' static > {
349+ pub fn set_command_line_args ( ) -> Command < ' static > {
323350 let app = Command :: new ( "swhkd" )
324351 . version ( env ! ( "CARGO_PKG_VERSION" ) )
325352 . author ( env ! ( "CARGO_PKG_AUTHORS" ) )
@@ -340,7 +367,7 @@ pub fn set_flags() -> Command<'static> {
340367 app
341368}
342369
343- pub fn check_config_xdg ( ) -> std:: path:: PathBuf {
370+ pub fn fetch_xdg_config_path ( ) -> std:: path:: PathBuf {
344371 let config_file_path: std:: path:: PathBuf = match env:: var ( "XDG_CONFIG_HOME" ) {
345372 Ok ( val) => {
346373 log:: debug!( "XDG_CONFIG_HOME exists: {:#?}" , val) ;
@@ -353,9 +380,3 @@ pub fn check_config_xdg() -> std::path::PathBuf {
353380 } ;
354381 config_file_path
355382}
356-
357- fn sock_send ( command : & str ) -> std:: io:: Result < ( ) > {
358- let mut stream = UnixStream :: connect ( "/tmp/swhkd.sock" ) ?;
359- stream. write_all ( command. as_bytes ( ) ) ?;
360- Ok ( ( ) )
361- }
0 commit comments