From 44e06bc0dc4c3d1af42e02de6ad2363e5b876660 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Mon, 28 Sep 2020 17:52:00 +0000 Subject: [PATCH] keymap: Generate from symbol map, not layout --- src/data.rs | 17 ++++++------ src/keyboard.rs | 69 ++++++++++++------------------------------------- 2 files changed, 24 insertions(+), 62 deletions(-) diff --git a/src/data.rs b/src/data.rs index 4ff7cc2d..7cd06c4c 100644 --- a/src/data.rs +++ b/src/data.rs @@ -382,7 +382,7 @@ impl Layout { ) )}).collect(); - let keymap: HashMap = generate_keycodes( + let symbolmap: HashMap = generate_keycodes( button_actions.iter() .filter_map(|(_name, action)| { match action { @@ -399,20 +399,20 @@ impl Layout { let button_states = button_actions.into_iter().map(|(name, action)| { let keycodes = match &action { ::action::Action::Submit { text: _, keys } => { - keys.iter().map(|named_keycode| { - *keymap.get(named_keycode.0.as_str()) + keys.iter().map(|named_keysym| { + *symbolmap.get(named_keysym.0.as_str()) .expect( format!( - "keycode {} in key {} missing from keymap", - named_keycode.0, + "keysym {} in key {} missing from symbol map", + named_keysym.0, name ).as_str() ) }).collect() }, action::Action::Erase => vec![ - *keymap.get("BackSpace") - .expect(&format!("BackSpace missing from keymap")), + *symbolmap.get("BackSpace") + .expect(&format!("BackSpace missing from symbol map")), ], _ => Vec::new(), }; @@ -430,8 +430,7 @@ impl Layout { button_states ); - // TODO: generate from symbols - let keymap_str = match generate_keymap(&button_states) { + let keymap_str = match generate_keymap(symbolmap) { Err(e) => { return (Err(e), warning_handler) }, Ok(v) => v, }; diff --git a/src/keyboard.rs b/src/keyboard.rs index ddc4d1e4..b53c9eda 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -9,7 +9,6 @@ use std::rc::Rc; use std::string::FromUtf8Error; use ::action::Action; -use ::logging; // Traits use std::io::Write; @@ -125,11 +124,9 @@ impl From for FormattingError { } /// 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. +/// Key codes must not repeat and must remain between 9 and 255. pub fn generate_keymap( - keystates: &HashMap:: + symbolmap: HashMap::, ) -> Result { let mut buf: Vec = Vec::new(); writeln!( @@ -138,15 +135,14 @@ pub fn generate_keymap( xkb_keycodes \"squeekboard\" {{ minimum = 8; - maximum = 999;" + maximum = 255;" )?; - // Not all layouts fit in 255 characters... so bump the limit to 999. - // Xorg can only consume up to 255, so this may not work in Xwayland. + // Xorg can only consume up to 255 keys, so this may not work in Xwayland. // Two possible solutions: // - use levels to cram multiple characters into one key // - swap layouts on key presses - for keycode in 9..999 { + for keycode in symbolmap.values() { write!( buf, " @@ -165,39 +161,14 @@ pub fn generate_keymap( " )?; - for (_name, state) in keystates.iter() { - match &state.action{ - Action::Submit { text: _, keys } => { - for (named_keysym, keycode) in keys.iter().zip(&state.keycodes) { - write!( - buf, - " - key {{ [ {} ] }};", - keycode, - named_keysym.0, - )?; - } - }, - Action::Erase => { - let mut keycodes = state.keycodes.iter(); - write!( - buf, - " - key {{ [ BackSpace ] }};", - keycodes.next().expect("Erase key has no keycode"), - )?; - if let Some(_) = keycodes.next() { - log_print!( - logging::Level::Bug, - "Erase key has multiple keycodes", - ); - } - }, - Action::SetView(_) => {}, - Action::LockView{ .. } => {}, - Action::ApplyModifier(_) => {}, - Action::ShowPreferences => {}, - } + for (name, keycode) in symbolmap.iter() { + write!( + buf, + " +key {{ [ {} ] }};", + keycode, + name, + )?; } writeln!( @@ -247,21 +218,13 @@ mod tests { use xkbcommon::xkb; - use ::action::KeySym; - #[test] fn test_keymap_multi() { let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS); - let keymap_str = generate_keymap(&hashmap!{ - "ac".into() => KeyState { - action: Action::Submit { - text: None, - keys: vec!(KeySym("a".into()), KeySym("c".into())), - }, - keycodes: vec!(9, 10), - pressed: PressType::Released, - }, + let keymap_str = generate_keymap(hashmap!{ + "a".into() => 9, + "c".into() => 10, }).unwrap(); let keymap = xkb::Keymap::new_from_string(