input_method: Use for erasing
This commit is contained in:
		@ -45,7 +45,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "special"
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "special"
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "default"
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "default"
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    space:
 | 
			
		||||
        outline: spaceline
 | 
			
		||||
        text: " "
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "special"
 | 
			
		||||
 | 
			
		||||
@ -39,9 +39,9 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: erase
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        action: show_prefs
 | 
			
		||||
        outline: "special"
 | 
			
		||||
        icon: "keyboard-mode-symbolic"
 | 
			
		||||
    show_numbers:
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
        keysym: "BackSpace"
 | 
			
		||||
        action: "erase"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "special"
 | 
			
		||||
 | 
			
		||||
@ -37,5 +37,7 @@ pub enum Action {
 | 
			
		||||
        /// The key events this symbol submits when submitting text is not possible
 | 
			
		||||
        keys: Vec<KeySym>,
 | 
			
		||||
    },
 | 
			
		||||
    /// Erase a position behind the cursor
 | 
			
		||||
    Erase,
 | 
			
		||||
    ShowPreferences,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								src/data.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/data.rs
									
									
									
									
									
								
							@ -15,6 +15,7 @@ use std::vec::Vec;
 | 
			
		||||
 | 
			
		||||
use xkbcommon::xkb;
 | 
			
		||||
 | 
			
		||||
use ::action;
 | 
			
		||||
use ::keyboard::{
 | 
			
		||||
    KeyState, PressType,
 | 
			
		||||
    generate_keymap, generate_keycodes, FormattingError
 | 
			
		||||
@ -259,6 +260,9 @@ enum Action {
 | 
			
		||||
    SetView(String),
 | 
			
		||||
    #[serde(rename="show_prefs")]
 | 
			
		||||
    ShowPrefs,
 | 
			
		||||
    /// Remove last character
 | 
			
		||||
    #[serde(rename="erase")]
 | 
			
		||||
    Erase,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
 | 
			
		||||
@ -381,6 +385,10 @@ impl Layout {
 | 
			
		||||
                            )
 | 
			
		||||
                    }).collect()
 | 
			
		||||
                },
 | 
			
		||||
                action::Action::Erase => vec![
 | 
			
		||||
                    *keymap.get("BackSpace")
 | 
			
		||||
                        .expect(&format!("BackSpace missing from keymap")),
 | 
			
		||||
                ],
 | 
			
		||||
                _ => Vec::new(),
 | 
			
		||||
            };
 | 
			
		||||
            (
 | 
			
		||||
@ -547,6 +555,7 @@ fn create_action<H: WarningHandler>(
 | 
			
		||||
        SubmitData::Action(
 | 
			
		||||
            Action::ShowPrefs
 | 
			
		||||
        ) => ::action::Action::ShowPreferences,
 | 
			
		||||
        SubmitData::Action(Action::Erase) => action::Action::Erase,
 | 
			
		||||
        SubmitData::Keysym(keysym) => ::action::Action::Submit {
 | 
			
		||||
            text: None,
 | 
			
		||||
            keys: vec!(::action::KeySym(
 | 
			
		||||
@ -581,7 +590,7 @@ fn create_action<H: WarningHandler>(
 | 
			
		||||
                    false => format!("U{:04X}", codepoint as u32),
 | 
			
		||||
                })
 | 
			
		||||
            }).collect(),
 | 
			
		||||
        }
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,11 @@ eek_input_method_commit_string(struct zwp_input_method_v2 *zwp_input_method_v2,
 | 
			
		||||
    zwp_input_method_v2_commit_string(zwp_input_method_v2, text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_input_method_delete_surrounding_text(struct zwp_input_method_v2 *zwp_input_method_v2, uint32_t before_length, uint32_t after_length) {
 | 
			
		||||
    zwp_input_method_v2_delete_surrounding_text(zwp_input_method_v2, before_length, after_length);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_input_method_commit(struct zwp_input_method_v2 *zwp_input_method_v2, uint32_t serial)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ pub mod c {
 | 
			
		||||
        #[allow(improper_ctypes)] // IMService will never be dereferenced in C
 | 
			
		||||
        pub fn imservice_connect_listeners(im: *mut InputMethod, imservice: *const IMService);
 | 
			
		||||
        pub fn eek_input_method_commit_string(im: *mut InputMethod, text: *const c_char);
 | 
			
		||||
        pub fn eek_input_method_delete_surrounding_text(im: *mut InputMethod, before: u32, after: u32);
 | 
			
		||||
        pub fn eek_input_method_commit(im: *mut InputMethod, serial: u32);
 | 
			
		||||
        fn eekboard_context_service_set_hint_purpose(state: *const StateManager, hint: u32, purpose: u32);
 | 
			
		||||
        fn server_context_service_show_keyboard(imservice: *const UIManager);
 | 
			
		||||
@ -375,6 +376,24 @@ impl IMService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn delete_surrounding_text(
 | 
			
		||||
        &self,
 | 
			
		||||
        before: u32, after: u32,
 | 
			
		||||
    ) -> Result<(), SubmitError> {
 | 
			
		||||
        match self.current.active {
 | 
			
		||||
            true => {
 | 
			
		||||
                unsafe {
 | 
			
		||||
                    c::eek_input_method_delete_surrounding_text(
 | 
			
		||||
                        self.im,
 | 
			
		||||
                        before, after,
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                Ok(())
 | 
			
		||||
            },
 | 
			
		||||
            false => Err(SubmitError::NotActive),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn commit(&mut self) -> Result<(), SubmitError> {
 | 
			
		||||
        match self.current.active {
 | 
			
		||||
            true => {
 | 
			
		||||
 | 
			
		||||
@ -79,9 +79,10 @@ fn sorted<'a, I: Iterator<Item=&'a str>>(
 | 
			
		||||
pub fn generate_keycodes<'a, C: IntoIterator<Item=&'a str>>(
 | 
			
		||||
    key_names: C
 | 
			
		||||
) -> HashMap<String, u32> {
 | 
			
		||||
    let special_keysyms = ["BackSpace", "Return"].iter().map(|&s| s);
 | 
			
		||||
    HashMap::from_iter(
 | 
			
		||||
        // sort to remove a source of indeterminism in keycode assignment
 | 
			
		||||
        sorted(key_names.into_iter())
 | 
			
		||||
        sorted(key_names.into_iter().chain(special_keysyms))
 | 
			
		||||
            .map(|name| String::from(name))
 | 
			
		||||
            .zip(9..)
 | 
			
		||||
    )
 | 
			
		||||
@ -108,7 +109,10 @@ impl From<io::Error> for FormattingError {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Generates a de-facto single level keymap. TODO: actually drop second level
 | 
			
		||||
/// Generates a de-facto single level keymap.
 | 
			
		||||
// TODO: don't rely on keys and their order,
 | 
			
		||||
// but rather on what keysyms and keycodes are in use.
 | 
			
		||||
// Iterating actions makes it hard to deduplicate keysyms.
 | 
			
		||||
pub fn generate_keymap(
 | 
			
		||||
    keystates: &HashMap::<String, KeyState>
 | 
			
		||||
) -> Result<String, FormattingError> {
 | 
			
		||||
@ -123,17 +127,32 @@ pub fn generate_keymap(
 | 
			
		||||
    )?;
 | 
			
		||||
    
 | 
			
		||||
    for (name, state) in keystates.iter() {
 | 
			
		||||
        if let Action::Submit { text: _, keys } = &state.action {
 | 
			
		||||
            if let 0 = keys.len() { eprintln!("Key {} has no keysyms", name); };
 | 
			
		||||
            for (named_keysym, keycode) in keys.iter().zip(&state.keycodes) {
 | 
			
		||||
        match &state.action {
 | 
			
		||||
            Action::Submit { text: _, keys } => {
 | 
			
		||||
                if let 0 = keys.len() { eprintln!("Key {} has no keysyms", name); };
 | 
			
		||||
                for (named_keysym, keycode) in keys.iter().zip(&state.keycodes) {
 | 
			
		||||
                    write!(
 | 
			
		||||
                        buf,
 | 
			
		||||
                        "
 | 
			
		||||
        <{}> = {};",
 | 
			
		||||
                        named_keysym.0,
 | 
			
		||||
                        keycode,
 | 
			
		||||
                    )?;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            Action::Erase => {
 | 
			
		||||
                let mut keycodes = state.keycodes.iter();
 | 
			
		||||
                write!(
 | 
			
		||||
                    buf,
 | 
			
		||||
                    "
 | 
			
		||||
        <{}> = {};",
 | 
			
		||||
                    named_keysym.0,
 | 
			
		||||
                    keycode,
 | 
			
		||||
        <BackSpace> = {};",
 | 
			
		||||
                    keycodes.next().expect("Erase key has no keycode"),
 | 
			
		||||
                )?;
 | 
			
		||||
            }
 | 
			
		||||
                if let Some(_) = keycodes.next() {
 | 
			
		||||
                    eprintln!("BUG: Erase key has multiple keycodes");
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            _ => {},
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@ -145,7 +164,9 @@ pub fn generate_keymap(
 | 
			
		||||
    xkb_symbols \"squeekboard\" {{
 | 
			
		||||
 | 
			
		||||
        name[Group1] = \"Letters\";
 | 
			
		||||
        name[Group2] = \"Numbers/Symbols\";"
 | 
			
		||||
        name[Group2] = \"Numbers/Symbols\";
 | 
			
		||||
        
 | 
			
		||||
        key <BackSpace> {{ [ BackSpace ] }};"
 | 
			
		||||
    )?;
 | 
			
		||||
    
 | 
			
		||||
    for (name, state) in keystates.iter() {
 | 
			
		||||
 | 
			
		||||
@ -887,7 +887,9 @@ mod seat {
 | 
			
		||||
 | 
			
		||||
        // process changes
 | 
			
		||||
        match action {
 | 
			
		||||
            Action::Submit { text: _, keys: _ } => {
 | 
			
		||||
            Action::Submit { text: _, keys: _ }
 | 
			
		||||
                | Action::Erase
 | 
			
		||||
            => {
 | 
			
		||||
                unstick_locks(layout).apply();
 | 
			
		||||
                submission.handle_release(KeyState::get_id(rckey), time);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
@ -116,16 +116,18 @@ impl Submission {
 | 
			
		||||
        key: &KeyState, key_id: KeyStateId,
 | 
			
		||||
        time: Timestamp,
 | 
			
		||||
    ) {
 | 
			
		||||
        let key_string = match &key.action {
 | 
			
		||||
            Action::Submit { text, keys: _ } => text,
 | 
			
		||||
        match &key.action {
 | 
			
		||||
            Action::Submit { text: _, keys: _ }
 | 
			
		||||
                | Action::Erase
 | 
			
		||||
            => (),
 | 
			
		||||
            _ => {
 | 
			
		||||
                eprintln!("BUG: Submitted key with action other than Submit");
 | 
			
		||||
                eprintln!("BUG: Submitted key with action other than Submit or Erase");
 | 
			
		||||
                return;
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let text_was_committed = match (&mut self.imservice, key_string) {
 | 
			
		||||
            (Some(imservice), Some(text)) => {
 | 
			
		||||
        let was_committed_as_text = match (&mut self.imservice, &key.action) {
 | 
			
		||||
            (Some(imservice), Action::Submit { text: Some(text), keys: _ }) => {
 | 
			
		||||
                let submit_result = imservice.commit_string(text)
 | 
			
		||||
                    .and_then(|_| imservice.commit());
 | 
			
		||||
                match submit_result {
 | 
			
		||||
@ -133,10 +135,18 @@ impl Submission {
 | 
			
		||||
                    Err(imservice::SubmitError::NotActive) => false,
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            (Some(imservice), Action::Erase) => {
 | 
			
		||||
                let submit_result = imservice.delete_surrounding_text(1, 0)
 | 
			
		||||
                    .and_then(|_| imservice.commit());
 | 
			
		||||
                match submit_result {
 | 
			
		||||
                    Ok(()) => true,
 | 
			
		||||
                    Err(imservice::SubmitError::NotActive) => false,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            (_, _) => false,
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        let submit_action = match text_was_committed {
 | 
			
		||||
        let submit_action = match was_committed_as_text {
 | 
			
		||||
            true => SubmittedAction::IMService,
 | 
			
		||||
            false => {
 | 
			
		||||
                self.virtual_keyboard.switch(
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user