mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
window: x11/wayland: extract utf8 version of key from key state
Previously, we'd take a couple of guesses at how to map the key to a utf8 value, but! the keyboard state has a method that can tell us what to use. This is important in non-latin keymaps where, for example, the `c` key generates cyrillic small letter es and we'd end up sending CTRL + that through to the terminal when CTRL is held down. If we get the utf8 string from the keyboard layer then we get CTRL+c instead, and that is what we want. refs: https://github.com/wez/wezterm/issues/678
This commit is contained in:
parent
c05491f831
commit
43d9392c52
@ -17,6 +17,7 @@ As features stabilize some brief notes about them will accumulate here.
|
||||
#### Fixed
|
||||
|
||||
* Regression that broke fontconfig aliases such as `"monospace"` [#1250](https://github.com/wez/wezterm/pull/1250)
|
||||
* X11/Wayland: CTRL+C in non-latin keyboard layouts wouldn't send CTRL-C [#678](https://github.com/wez/wezterm/issues/678)
|
||||
|
||||
### 20220101-133340-7edc5b5a
|
||||
|
||||
|
@ -120,6 +120,19 @@ impl KeyCode {
|
||||
pub fn normalize_shift(&self, modifiers: Modifiers) -> (KeyCode, Modifiers) {
|
||||
normalize_shift(self.clone(), modifiers)
|
||||
}
|
||||
|
||||
pub fn composed(s: &str) -> Self {
|
||||
// Prefer to send along a single Char when the string
|
||||
// is just a single char, as the keymapping layer cannot
|
||||
// bind to composed key sequences
|
||||
let mut iter = s.chars();
|
||||
let first_char = iter.next();
|
||||
let next_char = iter.next();
|
||||
match (first_char, next_char) {
|
||||
(Some(c), None) => Self::Char(c),
|
||||
_ => Self::Composed(s.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for KeyCode {
|
||||
|
@ -1425,19 +1425,7 @@ impl WindowView {
|
||||
let mut inner = myself.inner.borrow_mut();
|
||||
let key_is_down = inner.key_is_down.take().unwrap_or(true);
|
||||
|
||||
// Prefer to send along a single Char when the string
|
||||
// is just a single char, as the keymapping layer cannot
|
||||
// bind to composed key sequences and we'll get those
|
||||
// for example when use_ime=true and the user presses
|
||||
// `CTRL-A p` - we'd get CTRL-A followed by Composed("p")
|
||||
// here if we didn't normalize it back to Char.
|
||||
let mut iter = s.chars();
|
||||
let first_char = iter.next();
|
||||
let next_char = iter.next();
|
||||
let key = match (first_char, next_char) {
|
||||
(Some(c), None) => KeyCode::Char(c),
|
||||
_ => KeyCode::Composed(s.to_string()),
|
||||
};
|
||||
let key = KeyCode::composed(s);
|
||||
|
||||
let event = KeyEvent {
|
||||
key,
|
||||
|
@ -160,6 +160,7 @@ impl Keyboard {
|
||||
fn process_key_event_impl(&self, xcode: xkb::Keycode, pressed: bool) -> Option<KeyEvent> {
|
||||
let xsym = self.state.borrow().key_get_one_sym(xcode);
|
||||
|
||||
let mut kc = None;
|
||||
let ksym = if pressed {
|
||||
self.compose_state.borrow_mut().feed(xsym);
|
||||
|
||||
@ -170,11 +171,21 @@ impl Keyboard {
|
||||
return None;
|
||||
}
|
||||
ComposeStatus::Composed => {
|
||||
let res = self.compose_state.borrow().keysym();
|
||||
self.compose_state.borrow_mut().reset();
|
||||
let mut compose_state = self.compose_state.borrow_mut();
|
||||
let res = compose_state.keysym();
|
||||
if let Some(utf8) = compose_state.utf8() {
|
||||
kc.replace(crate::KeyCode::composed(&utf8));
|
||||
}
|
||||
compose_state.reset();
|
||||
res.unwrap_or(xsym)
|
||||
}
|
||||
ComposeStatus::Nothing => xsym,
|
||||
ComposeStatus::Nothing => {
|
||||
let utf8 = self.state.borrow().key_get_utf8(xcode);
|
||||
if !utf8.is_empty() {
|
||||
kc.replace(crate::KeyCode::composed(&utf8));
|
||||
}
|
||||
xsym
|
||||
}
|
||||
ComposeStatus::Cancelled => {
|
||||
self.compose_state.borrow_mut().reset();
|
||||
return None;
|
||||
@ -184,7 +195,11 @@ impl Keyboard {
|
||||
xsym
|
||||
};
|
||||
|
||||
let kc = keysym_to_keycode(ksym).or_else(|| keysym_to_keycode(xsym))?;
|
||||
let kc = match kc {
|
||||
Some(kc) => kc,
|
||||
None => keysym_to_keycode(ksym).or_else(|| keysym_to_keycode(xsym))?,
|
||||
};
|
||||
|
||||
let raw_modifiers = self.get_key_modifiers();
|
||||
// X11 keysyms that map to KeyCode::Char already factor in the SHIFT
|
||||
// modifier state. eg: SHIFT-c in an US layout produces `Char('C')`.
|
||||
@ -201,16 +216,19 @@ impl Keyboard {
|
||||
(_, mods) => mods,
|
||||
};
|
||||
|
||||
Some(KeyEvent {
|
||||
key: kc,
|
||||
modifiers,
|
||||
raw_key: None,
|
||||
raw_modifiers,
|
||||
raw_code: Some(xcode),
|
||||
phys_code: self.phys_code_map.borrow().get(&xcode).copied(),
|
||||
repeat_count: 1,
|
||||
key_is_down: pressed,
|
||||
})
|
||||
Some(
|
||||
KeyEvent {
|
||||
key: kc,
|
||||
modifiers,
|
||||
raw_key: None,
|
||||
raw_modifiers,
|
||||
raw_code: Some(xcode),
|
||||
phys_code: self.phys_code_map.borrow().get(&xcode).copied(),
|
||||
repeat_count: 1,
|
||||
key_is_down: pressed,
|
||||
}
|
||||
.normalize_ctrl(),
|
||||
)
|
||||
}
|
||||
|
||||
fn mod_is_active(&self, modifier: &str) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user