submission: Handle submitting strings

This commit is contained in:
Dorota Czaplejewicz
2020-01-14 13:13:42 +00:00
parent d1bc23e9d8
commit 42cb73cd8c
6 changed files with 126 additions and 23 deletions

View File

@ -16,8 +16,11 @@
* The text-input interface may be enabled and disabled at arbitrary times,
* and those events SHOULD NOT cause any lost events.
* */
use ::action::Action;
use ::imservice;
use ::imservice::IMService;
use ::keyboard::{ KeyCode, KeyState, KeyStateId, PressType };
use ::vkeyboard::VirtualKeyboard;
/// Gathers stuff defined in C or called by C
@ -57,6 +60,7 @@ pub mod c {
Submission {
imservice,
virtual_keyboard: VirtualKeyboard(vk),
pressed: Vec::new(),
}
))
}
@ -92,9 +96,78 @@ pub mod c {
#[derive(Clone, Copy)]
pub struct Timestamp(pub u32);
pub struct Submission {
// used by C callbacks internally, TODO: make use with virtual keyboard
#[allow(dead_code)]
imservice: Option<Box<IMService>>,
pub virtual_keyboard: VirtualKeyboard,
enum SubmittedAction {
/// A collection of keycodes that were pressed
VirtualKeyboard(Vec<KeyCode>),
IMService,
}
pub struct Submission {
imservice: Option<Box<IMService>>,
virtual_keyboard: VirtualKeyboard,
pressed: Vec<(KeyStateId, SubmittedAction)>,
}
impl Submission {
/// Sends a submit text event if possible;
/// otherwise sends key press and makes a note of it
pub fn handle_press(
&mut self,
key: &KeyState, key_id: KeyStateId,
time: Timestamp,
) {
let key_string = match &key.action {
Action::Submit { text, keys: _ } => text,
_ => {
eprintln!("BUG: Submitted key with action other than Submit");
return;
},
};
let text_was_committed = match (&mut self.imservice, key_string) {
(Some(imservice), Some(text)) => {
let submit_result = imservice.commit_string(text)
.and_then(|_| imservice.commit());
match submit_result {
Ok(()) => true,
Err(imservice::SubmitError::NotActive) => false,
}
},
(_, _) => false,
};
let submit_action = match text_was_committed {
true => SubmittedAction::IMService,
false => {
self.virtual_keyboard.switch(
&key.keycodes,
PressType::Pressed,
time,
);
SubmittedAction::VirtualKeyboard(key.keycodes.clone())
},
};
self.pressed.push((key_id, submit_action));
}
pub fn handle_release(&mut self, key_id: KeyStateId, time: Timestamp) {
let index = self.pressed.iter().position(|(id, _)| *id == key_id);
if let Some(index) = index {
let (_id, action) = self.pressed.remove(index);
match action {
// string already sent, nothing to do
SubmittedAction::IMService => {},
// no matter if the imservice got activated,
// keys must be released
SubmittedAction::VirtualKeyboard(keycodes) => {
self.virtual_keyboard.switch(
&keycodes,
PressType::Released,
time,
)
},
}
};
}
}