Add register special keys to improve word matches reliability

This commit is contained in:
Federico Terzi 2020-03-08 19:51:38 +01:00
parent 33cfb156db
commit 5273d8b805
6 changed files with 27 additions and 6 deletions

View File

@ -137,7 +137,7 @@ int32_t initialize(void * _context_instance) {
return -4; return -4;
} }
record_range->device_events.first = KeyPress; 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 // We want to get the keys from all clients
XRecordClientSpec client_spec; XRecordClientSpec client_spec;
@ -261,6 +261,9 @@ void event_callback(XPointer p, XRecordInterceptData *hook)
keypress_callback(context_instance, NULL, 0, 1, key_code); keypress_callback(context_instance, NULL, 0, 1, key_code);
} }
break; 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: default:
break; break;
} }

View File

@ -48,7 +48,7 @@ extern "C" void cleanup();
* Called when a new keypress is made, the first argument is an char array, * Called when a new keypress is made, the first argument is an char array,
* while the second is the size of the 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; extern KeypressCallback keypress_callback;

View File

@ -86,7 +86,7 @@ impl Drop for LinuxContext {
// Native bridge code // Native bridge code
extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32, 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 { unsafe {
let _self = _self as *mut LinuxContext; 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; return;
} }
if is_modifier == 0 { // Char event if event_type == 0 { // Char event
// Convert the received buffer to a string // Convert the received buffer to a string
let c_str = CStr::from_ptr(raw_buffer as (*const c_char)); let c_str = CStr::from_ptr(raw_buffer as (*const c_char));
let char_str = c_str.to_str(); 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); debug!("Unable to receive char: {}",e);
}, },
} }
}else{ // Modifier event }else if event_type == 1 { // Modifier event
let modifier: Option<KeyModifier> = match key_code { let modifier: Option<KeyModifier> = match key_code {
133 => Some(META), 133 => Some(META),
50 => Some(SHIFT), 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 { if let Some(modifier) = modifier {
let event = Event::Key(KeyEvent::Modifier(modifier)); let event = Event::Key(KeyEvent::Modifier(modifier));
(*_self).send_channel.send(event).unwrap(); (*_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();
} }
} }
} }

View File

@ -53,7 +53,8 @@ impl From<i32> for ActionType {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum KeyEvent { pub enum KeyEvent {
Char(String), Char(String),
Modifier(KeyModifier) Modifier(KeyModifier),
Other
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

View File

@ -239,6 +239,7 @@ pub trait MatchReceiver {
pub trait Matcher : KeyEventReceiver { pub trait Matcher : KeyEventReceiver {
fn handle_char(&self, c: &str); fn handle_char(&self, c: &str);
fn handle_modifier(&self, m: KeyModifier); fn handle_modifier(&self, m: KeyModifier);
fn handle_other(&self);
} }
impl <M: Matcher> KeyEventReceiver for M { impl <M: Matcher> KeyEventReceiver for M {
@ -250,6 +251,9 @@ impl <M: Matcher> KeyEventReceiver for M {
KeyEvent::Modifier(m) => { KeyEvent::Modifier(m) => {
self.handle_modifier(m); self.handle_modifier(m);
}, },
KeyEvent::Other => {
self.handle_other();
},
} }
} }
} }

View File

@ -236,6 +236,13 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa
current_set_queue.pop_back(); 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> { impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ActionEventReceiver for ScrollingMatcher<'a, R, M> {