From 1b34e626c43d0474ea0cace6632c8ae223490162 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 6 Sep 2019 22:19:28 +0200 Subject: [PATCH] Add newline support on linux. Fix #6 --- src/engine.rs | 21 ++++++++++++------- src/keyboard/linux.rs | 47 ++++++++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 40d93fe..dff35b8 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -17,15 +17,22 @@ impl MatchReceiver for Engine where S: KeyboardSender{ fn on_match(&self, m: &Match) { self.sender.delete_string(m.trigger.len() as i32); - // To handle newlines, substitute each "\n" char with an Enter key press. - let splits = m.replace.lines(); + // Send the expected string. On linux, newlines are managed automatically + // while on windows and macos, we need to emulate a Enter key press. - for (i, split) in splits.enumerate() { - if i > 0 { - self.sender.send_enter(); + if cfg!(target_os = "linux") { + self.sender.send_string(m.replace.as_str()); + }else{ + // To handle newlines, substitute each "\n" char with an Enter key press. + let splits = m.replace.lines(); + + for (i, split) in splits.enumerate() { + if i > 0 { + self.sender.send_enter(); + } + + self.sender.send_string(split); } - - self.sender.send_string(split); } } } \ No newline at end of file diff --git a/src/keyboard/linux.rs b/src/keyboard/linux.rs index 087e7b2..b131c97 100644 --- a/src/keyboard/linux.rs +++ b/src/keyboard/linux.rs @@ -2,7 +2,8 @@ use std::thread; use std::sync::mpsc; use std::os::raw::c_char; use std::ffi::CString; -use crate::keyboard::KeyEvent; +use crate::keyboard::{KeyEvent, KeyModifier}; +use crate::keyboard::KeyModifier::*; #[repr(C)] pub struct LinuxKeyboardInterceptor { @@ -13,16 +14,14 @@ impl super::KeyboardInterceptor for LinuxKeyboardInterceptor { fn initialize(&self) { unsafe { register_keypress_callback(self,keypress_callback); + initialize(); // TODO: check initialization return codes } } fn start(&self) { - thread::spawn(|| { - unsafe { - initialize(); // TODO: check initialization return codes - eventloop(); - } - }); + unsafe { + eventloop(); + } } } @@ -44,6 +43,10 @@ impl super::KeyboardSender for LinuxKeyboardSender { } } + fn send_enter(&self) { + // On linux this is not needed, so NOOP + } + fn delete_string(&self, count: i32) { unsafe {delete_string(count)} } @@ -53,14 +56,30 @@ impl super::KeyboardSender for LinuxKeyboardSender { extern fn keypress_callback(_self: *mut LinuxKeyboardInterceptor, raw_buffer: *const u8, len: i32) { unsafe { - // Convert the received buffer to a character - let buffer = std::slice::from_raw_parts(raw_buffer, len as usize); - let r = String::from_utf8_lossy(buffer).chars().nth(0); + //if is_modifier == 0 { // Char event + if true { // Char event + // Convert the received buffer to a character + let buffer = std::slice::from_raw_parts(raw_buffer, len as usize); + let r = String::from_utf8_lossy(buffer).chars().nth(0); - // Send the char through the channel - if let Some(c) = r { - //println!("'{}'",c); - (*_self).sender.send(c).unwrap(); + // Send the char through the channel + if let Some(c) = r { + (*_self).sender.send(KeyEvent::Char(c)).unwrap(); + } + }else{ // Modifier event + let key_code = 3; + let modifier: Option = match key_code { + 0x37 => Some(META), + 0x38 => Some(SHIFT), + 0x3A => Some(ALT), + 0x3B => Some(CTRL), + 0x33 => Some(BACKSPACE), + _ => None, + }; + + if let Some(modifier) = modifier { + (*_self).sender.send(KeyEvent::Modifier(modifier)).unwrap(); + } } } }