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