submission: Handle submitting strings
This commit is contained in:
@ -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,
|
||||
)
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user