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) {
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.
let splits = m.replace.lines();
@ -29,3 +35,4 @@ impl <S> MatchReceiver for Engine<S> where S: KeyboardSender{
}
}
}
}

View File

@ -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();
}
});
}
}
@ -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 {
//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();
(*_self).sender.send(KeyEvent::Char(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();
}
}
}
}