diff --git a/native/liblinuxbridge/bridge.cpp b/native/liblinuxbridge/bridge.cpp index 7aff24f..654a95f 100644 --- a/native/liblinuxbridge/bridge.cpp +++ b/native/liblinuxbridge/bridge.cpp @@ -137,7 +137,7 @@ int32_t initialize(void * _context_instance) { return -4; } record_range->device_events.first = KeyPress; - record_range->device_events.last = KeyRelease; + record_range->device_events.last = ButtonPress; // We want to get the keys from all clients XRecordClientSpec client_spec; @@ -261,6 +261,9 @@ void event_callback(XPointer p, XRecordInterceptData *hook) keypress_callback(context_instance, NULL, 0, 1, key_code); } break; + case ButtonPress: // Send also mouse button presses as "other events" + //printf ("Press button %d\n", key_code); + keypress_callback(context_instance, NULL, 0, 2, key_code); default: break; } diff --git a/native/liblinuxbridge/bridge.h b/native/liblinuxbridge/bridge.h index e976c71..876a4b3 100644 --- a/native/liblinuxbridge/bridge.h +++ b/native/liblinuxbridge/bridge.h @@ -48,7 +48,7 @@ extern "C" void cleanup(); * Called when a new keypress is made, the first argument is an char array, * while the second is the size of the array. */ -typedef void (*KeypressCallback)(void * self, const char *buffer, int32_t len, int32_t is_modifier, int32_t key_code); +typedef void (*KeypressCallback)(void * self, const char *buffer, int32_t len, int32_t event_type, int32_t key_code); extern KeypressCallback keypress_callback; diff --git a/src/context/linux.rs b/src/context/linux.rs index 67185f3..95186b2 100644 --- a/src/context/linux.rs +++ b/src/context/linux.rs @@ -86,7 +86,7 @@ impl Drop for LinuxContext { // Native bridge code extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32, - is_modifier: i32, key_code: i32) { + event_type: i32, key_code: i32) { unsafe { let _self = _self as *mut LinuxContext; @@ -98,7 +98,7 @@ extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32, return; } - if is_modifier == 0 { // Char event + if event_type == 0 { // Char event // Convert the received buffer to a string let c_str = CStr::from_ptr(raw_buffer as (*const c_char)); let char_str = c_str.to_str(); @@ -113,7 +113,7 @@ extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32, debug!("Unable to receive char: {}",e); }, } - }else{ // Modifier event + }else if event_type == 1 { // Modifier event let modifier: Option = match key_code { 133 => Some(META), 50 => Some(SHIFT), @@ -126,7 +126,13 @@ extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32, if let Some(modifier) = modifier { let event = Event::Key(KeyEvent::Modifier(modifier)); (*_self).send_channel.send(event).unwrap(); + }else{ // Not one of the default modifiers, send an "other" event + let event = Event::Key(KeyEvent::Other); + (*_self).send_channel.send(event).unwrap(); } + }else{ // Other type of event + let event = Event::Key(KeyEvent::Other); + (*_self).send_channel.send(event).unwrap(); } } } \ No newline at end of file diff --git a/src/event/mod.rs b/src/event/mod.rs index dc47691..8e81324 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -53,7 +53,8 @@ impl From for ActionType { #[derive(Debug, Clone)] pub enum KeyEvent { Char(String), - Modifier(KeyModifier) + Modifier(KeyModifier), + Other } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/src/matcher/mod.rs b/src/matcher/mod.rs index e322355..4356c34 100644 --- a/src/matcher/mod.rs +++ b/src/matcher/mod.rs @@ -239,6 +239,7 @@ pub trait MatchReceiver { pub trait Matcher : KeyEventReceiver { fn handle_char(&self, c: &str); fn handle_modifier(&self, m: KeyModifier); + fn handle_other(&self); } impl KeyEventReceiver for M { @@ -250,6 +251,9 @@ impl KeyEventReceiver for M { KeyEvent::Modifier(m) => { self.handle_modifier(m); }, + KeyEvent::Other => { + self.handle_other(); + }, } } } diff --git a/src/matcher/scrolling.rs b/src/matcher/scrolling.rs index 9b72b07..17b3da1 100644 --- a/src/matcher/scrolling.rs +++ b/src/matcher/scrolling.rs @@ -236,6 +236,13 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa current_set_queue.pop_back(); } } + + fn handle_other(&self) { + // When receiving "other" type of events, we mark them as valid separators. + // This dramatically improves the reliability of word matches + let mut was_previous_char_word_separator = self.was_previous_char_word_separator.borrow_mut(); + *was_previous_char_word_separator = true; + } } impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ActionEventReceiver for ScrollingMatcher<'a, R, M> {