1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 15:04:36 +03:00

window: wayland: improve keyboard mapping

This commit is contained in:
Wez Furlong 2019-11-28 00:01:05 -08:00
parent c63766ffe2
commit eb953a511c
3 changed files with 54 additions and 35 deletions

View File

@ -1084,6 +1084,7 @@ impl WindowView {
.map(|kc| normalize_shifted_unmodified_key(kc, virtual_key));
match (&key, &raw) {
// Avoid eg: \x01 when we can use CTRL-A
(KeyCode::Char(c), Some(raw)) if c.is_ascii_control() => (raw.clone(), None),
_ => (key, raw),
}

View File

@ -298,35 +298,27 @@ impl Window {
map_keyboard_auto_with_repeat(
&seat,
KeyRepeatKind::System,
move |event: KbEvent, _| {
println!("key event");
match event {
KbEvent::Key {
rawkey,
keysym,
state,
utf8,
..
} => {
Connection::with_window_inner(window_id, move |inner| {
inner.handle_key(
state == KeyState::Pressed,
rawkey,
keysym,
utf8.clone(),
);
Ok(())
});
}
KbEvent::Modifiers { modifiers } => {
let mods = modifier_keys(modifiers);
Connection::with_window_inner(window_id, move |inner| {
inner.handle_modifiers(mods);
Ok(())
});
}
_ => {}
move |event: KbEvent, _| match event {
KbEvent::Key {
rawkey,
keysym,
state,
utf8,
..
} => {
Connection::with_window_inner(window_id, move |inner| {
inner.handle_key(state == KeyState::Pressed, rawkey, keysym, utf8.clone());
Ok(())
});
}
KbEvent::Modifiers { modifiers } => {
let mods = modifier_keys(modifiers);
Connection::with_window_inner(window_id, move |inner| {
inner.handle_modifiers(mods);
Ok(())
});
}
_ => {}
},
move |event: KeyRepeatEvent, _| {
Connection::with_window_inner(window_id, move |inner| {
@ -363,18 +355,31 @@ impl Window {
impl WindowInner {
fn handle_key(&mut self, key_is_down: bool, rawkey: u32, keysym: u32, utf8: Option<String>) {
let key = match utf8 {
Some(text) if text.chars().count() == 1 => KeyCode::Char(text.chars().nth(0).unwrap()),
Some(text) => KeyCode::Composed(text),
None => {
println!("no mapping for keysym {} and rawkey {}", keysym, rawkey);
return;
let raw_key = keysym_to_keycode(keysym);
let (key, raw_key) = match utf8 {
Some(text) if text.chars().count() == 1 => {
(KeyCode::Char(text.chars().nth(0).unwrap()), raw_key)
}
Some(text) => (KeyCode::Composed(text), raw_key),
None => match raw_key {
Some(key) => (key, None),
None => {
println!("no mapping for keysym {:x} and rawkey {:x}", keysym, rawkey);
return;
}
},
};
// Avoid redundant key == raw_key
let (key, raw_key) = match (key, raw_key) {
// Avoid eg: \x01 when we can use CTRL-A
(KeyCode::Char(c), Some(raw)) if c.is_ascii_control() => (raw.clone(), None),
(key, Some(raw)) if key == raw => (key, None),
pair => pair,
};
let key_event = KeyEvent {
key_is_down,
key,
raw_key: None,
raw_key,
modifiers: self.modifiers,
repeat_count: 1,
};

View File

@ -28,6 +28,16 @@ pub fn modifiers_from_state(state: u16) -> Modifiers {
/// for missing keys, look into `/usr/include/X11/keysymdef.h`
/// and/or define them in KeyCode.
pub fn keysym_to_keycode(keysym: u32) -> Option<KeyCode> {
let utf32 = xkbcommon::xkb::keysym_to_utf32(keysym);
if utf32 >= 0x20 {
// Unsafety: this is ok because we trust that keysym_to_utf32
// is only going to return valid utf32 codepoints.
// Note that keysym_to_utf32 returns 0 for no match.
unsafe {
return Some(KeyCode::Char(std::char::from_u32_unchecked(utf32)));
}
}
use xkbcommon::xkb::keysyms::*;
#[allow(non_upper_case_globals)]
Some(match keysym {
@ -42,6 +52,9 @@ pub fn keysym_to_keycode(keysym: u32) -> Option<KeyCode> {
KEY_Pause => KeyCode::Pause,
KEY_Print => KeyCode::Print,
// latin-1
i @ KEY_space..=KEY_ydiaeresis => KeyCode::Char(i as u8 as char),
// cursor movement
KEY_Home => KeyCode::Home,
KEY_End => KeyCode::End,