Add newline support on linux. Fix #6

This commit is contained in:
Federico Terzi 2019-09-06 22:19:28 +02:00
parent d02f90bd44
commit 1b34e626c4
2 changed files with 47 additions and 21 deletions

View File

@ -17,6 +17,12 @@ impl <S> MatchReceiver for Engine<S> where S: KeyboardSender{
fn on_match(&self, m: &Match) { fn on_match(&self, m: &Match) {
self.sender.delete_string(m.trigger.len() as i32); self.sender.delete_string(m.trigger.len() as i32);
// Send the expected string. On linux, newlines are managed automatically
// while on windows and macos, we need to emulate a Enter key press.
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. // To handle newlines, substitute each "\n" char with an Enter key press.
let splits = m.replace.lines(); let splits = m.replace.lines();
@ -28,4 +34,5 @@ impl <S> MatchReceiver for Engine<S> where S: KeyboardSender{
self.sender.send_string(split); self.sender.send_string(split);
} }
} }
}
} }

View File

@ -2,7 +2,8 @@ use std::thread;
use std::sync::mpsc; use std::sync::mpsc;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::ffi::CString; use std::ffi::CString;
use crate::keyboard::KeyEvent; use crate::keyboard::{KeyEvent, KeyModifier};
use crate::keyboard::KeyModifier::*;
#[repr(C)] #[repr(C)]
pub struct LinuxKeyboardInterceptor { pub struct LinuxKeyboardInterceptor {
@ -13,16 +14,14 @@ impl super::KeyboardInterceptor for LinuxKeyboardInterceptor {
fn initialize(&self) { fn initialize(&self) {
unsafe { unsafe {
register_keypress_callback(self,keypress_callback); register_keypress_callback(self,keypress_callback);
initialize(); // TODO: check initialization return codes
} }
} }
fn start(&self) { fn start(&self) {
thread::spawn(|| {
unsafe { unsafe {
initialize(); // TODO: check initialization return codes
eventloop(); 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) { fn delete_string(&self, count: i32) {
unsafe {delete_string(count)} 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) { extern fn keypress_callback(_self: *mut LinuxKeyboardInterceptor, raw_buffer: *const u8, len: i32) {
unsafe { unsafe {
//if is_modifier == 0 { // Char event
if true { // Char event
// Convert the received buffer to a character // Convert the received buffer to a character
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize); let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
let r = String::from_utf8_lossy(buffer).chars().nth(0); let r = String::from_utf8_lossy(buffer).chars().nth(0);
// Send the char through the channel // Send the char through the channel
if let Some(c) = r { if let Some(c) = r {
//println!("'{}'",c); (*_self).sender.send(KeyEvent::Char(c)).unwrap();
(*_self).sender.send(c).unwrap(); }
}else{ // Modifier event
let key_code = 3;
let modifier: Option<KeyModifier> = 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();
}
} }
} }
} }