|
1 | 1 | use crate::config::Value; |
2 | 2 | use clap::Parser; |
| 3 | +use config::Hotkey; |
3 | 4 | use evdev::{AttributeSet, Device, InputEventKind, Key}; |
4 | 5 | use nix::{ |
5 | 6 | sys::stat::{umask, Mode}, |
@@ -109,52 +110,6 @@ async fn main() -> Result<(), Box<dyn Error>> { |
109 | 110 |
|
110 | 111 | let mut modes = load_config(); |
111 | 112 | let mut mode_stack: Vec<usize> = vec![0]; |
112 | | - |
113 | | - macro_rules! send_command { |
114 | | - ($hotkey: expr, $socket_path: expr) => { |
115 | | - log::info!("Hotkey pressed: {:#?}", $hotkey); |
116 | | - let command = $hotkey.command; |
117 | | - let mut commands_to_send = String::new(); |
118 | | - if modes[mode_stack[mode_stack.len() - 1]].options.oneoff { |
119 | | - mode_stack.pop(); |
120 | | - } |
121 | | - if command.contains('@') { |
122 | | - let commands = command.split("&&").map(|s| s.trim()).collect::<Vec<_>>(); |
123 | | - for cmd in commands { |
124 | | - match cmd.split(' ').next().unwrap() { |
125 | | - config::MODE_ENTER_STATEMENT => { |
126 | | - let enter_mode = cmd.split(' ').nth(1).unwrap(); |
127 | | - for (i, mode) in modes.iter().enumerate() { |
128 | | - if mode.name == enter_mode { |
129 | | - mode_stack.push(i); |
130 | | - break; |
131 | | - } |
132 | | - } |
133 | | - log::info!( |
134 | | - "Entering mode: {}", |
135 | | - modes[mode_stack[mode_stack.len() - 1]].name |
136 | | - ); |
137 | | - } |
138 | | - config::MODE_ESCAPE_STATEMENT => { |
139 | | - mode_stack.pop(); |
140 | | - } |
141 | | - _ => commands_to_send.push_str(format!("{cmd} &&").as_str()), |
142 | | - } |
143 | | - } |
144 | | - } else { |
145 | | - commands_to_send = command; |
146 | | - } |
147 | | - if commands_to_send.ends_with(" &&") { |
148 | | - commands_to_send = commands_to_send.strip_suffix(" &&").unwrap().to_string(); |
149 | | - } |
150 | | - if let Err(e) = socket_write(&commands_to_send, $socket_path.to_path_buf()) { |
151 | | - log::error!("Failed to send command to swhks through IPC."); |
152 | | - log::error!("Please make sure that swhks is running."); |
153 | | - log::error!("Err: {:#?}", e) |
154 | | - } |
155 | | - }; |
156 | | - } |
157 | | - |
158 | 113 | let arg_devices: Vec<String> = args.device; |
159 | 114 |
|
160 | 115 | let keyboard_devices: Vec<_> = { |
@@ -247,7 +202,7 @@ async fn main() -> Result<(), Box<dyn Error>> { |
247 | 202 | if hotkey.keybinding.on_release { |
248 | 203 | continue; |
249 | 204 | } |
250 | | - send_command!(hotkey.clone(), &socket_file_path); |
| 205 | + send_command(hotkey.clone(), &socket_file_path, &modes, &mut mode_stack); |
251 | 206 | hotkey_repeat_timer.as_mut().reset(Instant::now() + Duration::from_millis(repeat_cooldown_duration)); |
252 | 207 | } |
253 | 208 |
|
@@ -367,7 +322,7 @@ async fn main() -> Result<(), Box<dyn Error>> { |
367 | 322 | 0 => { |
368 | 323 | if last_hotkey.is_some() && pending_release { |
369 | 324 | pending_release = false; |
370 | | - send_command!(last_hotkey.clone().unwrap(), &socket_file_path); |
| 325 | + send_command(last_hotkey.clone().unwrap(), &socket_file_path, &modes, &mut mode_stack); |
371 | 326 | last_hotkey = None; |
372 | 327 | } |
373 | 328 | if let Some(modifier) = modifiers_map.get(&key) { |
@@ -430,7 +385,7 @@ async fn main() -> Result<(), Box<dyn Error>> { |
430 | 385 | pending_release = true; |
431 | 386 | break; |
432 | 387 | } |
433 | | - send_command!(hotkey.clone(), &socket_file_path); |
| 388 | + send_command(hotkey.clone(), &socket_file_path, &modes, &mut mode_stack); |
434 | 389 | hotkey_repeat_timer.as_mut().reset(Instant::now() + Duration::from_millis(repeat_cooldown_duration)); |
435 | 390 | continue; |
436 | 391 | } |
@@ -538,3 +493,49 @@ pub fn setup_swhkd(invoking_uid: u32, runtime_path: String) { |
538 | 493 | exit(1); |
539 | 494 | } |
540 | 495 | } |
| 496 | + |
| 497 | +pub fn send_command( |
| 498 | + hotkey: Hotkey, |
| 499 | + socket_path: &Path, |
| 500 | + modes: &[config::Mode], |
| 501 | + mode_stack: &mut Vec<usize>, |
| 502 | +) { |
| 503 | + log::info!("Hotkey pressed: {:#?}", hotkey); |
| 504 | + let command = hotkey.command; |
| 505 | + let mut commands_to_send = String::new(); |
| 506 | + if modes[mode_stack[mode_stack.len() - 1]].options.oneoff { |
| 507 | + mode_stack.pop(); |
| 508 | + } |
| 509 | + if command.contains('@') { |
| 510 | + let commands = command.split("&&").map(|s| s.trim()).collect::<Vec<_>>(); |
| 511 | + for cmd in commands { |
| 512 | + let mut words = cmd.split_whitespace(); |
| 513 | + match words.next().unwrap() { |
| 514 | + config::MODE_ENTER_STATEMENT => { |
| 515 | + let enter_mode = cmd.split(' ').nth(1).unwrap(); |
| 516 | + for (i, mode) in modes.iter().enumerate() { |
| 517 | + if mode.name == enter_mode { |
| 518 | + mode_stack.push(i); |
| 519 | + break; |
| 520 | + } |
| 521 | + } |
| 522 | + log::info!("Entering mode: {}", modes[mode_stack[mode_stack.len() - 1]].name); |
| 523 | + } |
| 524 | + config::MODE_ESCAPE_STATEMENT => { |
| 525 | + mode_stack.pop(); |
| 526 | + } |
| 527 | + _ => commands_to_send.push_str(format!("{cmd} &&").as_str()), |
| 528 | + } |
| 529 | + } |
| 530 | + } else { |
| 531 | + commands_to_send = command; |
| 532 | + } |
| 533 | + if commands_to_send.ends_with(" &&") { |
| 534 | + commands_to_send = commands_to_send.strip_suffix(" &&").unwrap().to_string(); |
| 535 | + } |
| 536 | + if let Err(e) = socket_write(&commands_to_send, socket_path.to_path_buf()) { |
| 537 | + log::error!("Failed to send command to swhks through IPC."); |
| 538 | + log::error!("Please make sure that swhks is running."); |
| 539 | + log::error!("Err: {:#?}", e) |
| 540 | + }; |
| 541 | +} |
0 commit comments