improv(key_bind): allow fallback if not ascci graphic or space
check if the logical key is within the valid latin key range and use that if so
This commit is contained in:
parent
758c13723f
commit
f0f68933f1
1 changed files with 106 additions and 3 deletions
|
|
@ -51,9 +51,10 @@ impl KeyBind {
|
|||
physical_key: Option<&Physical>,
|
||||
) -> bool {
|
||||
let key_eq = self.key_eq(key)
|
||||
|| physical_key
|
||||
.and_then(physical_key_to_latin)
|
||||
.is_some_and(|latin| self.key_eq(&latin));
|
||||
|| (!is_latin_shortcut_key(key)
|
||||
&& physical_key
|
||||
.and_then(physical_key_to_latin)
|
||||
.is_some_and(|latin| self.key_eq(&latin)));
|
||||
key_eq
|
||||
&& modifiers.logo() == self.modifiers.contains(&Modifier::Super)
|
||||
&& modifiers.control() == self.modifiers.contains(&Modifier::Ctrl)
|
||||
|
|
@ -70,6 +71,19 @@ impl KeyBind {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_latin_shortcut_key(key: &Key) -> bool {
|
||||
let Key::Character(s) = key else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let mut chars = s.chars();
|
||||
let Some(ch) = chars.next() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
chars.next().is_none() && (ch.is_ascii_graphic() || ch == ' ')
|
||||
}
|
||||
|
||||
/// Converts a physical key code to the corresponding US-layout Latin `Key`.
|
||||
///
|
||||
/// This mapping is intentionally limited to keys that may produce different
|
||||
|
|
@ -138,3 +152,92 @@ impl fmt::Display for KeyBind {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
fn bind_ctrl_w() -> KeyBind {
|
||||
KeyBind {
|
||||
modifiers: vec![Modifier::Ctrl],
|
||||
key: Key::Character("w".into()),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_w() {
|
||||
assert!(bind_ctrl_w().matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character("w".into()),
|
||||
Some(&Physical::Code(Code::KeyW)),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_w_no_fallback_to_dvorak_comma() {
|
||||
assert!(!bind_ctrl_w().matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character(",".into()),
|
||||
Some(&Physical::Code(Code::KeyW)),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_latin_layout_fallback() {
|
||||
assert!(bind_ctrl_w().matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character("ц".into()),
|
||||
Some(&Physical::Code(Code::KeyW)),
|
||||
));
|
||||
|
||||
let bind = KeyBind {
|
||||
modifiers: vec![Modifier::Ctrl],
|
||||
key: Key::Character("s".into()),
|
||||
};
|
||||
|
||||
assert!(bind.matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character("ы".into()),
|
||||
Some(&Physical::Code(Code::KeyS)),
|
||||
));
|
||||
|
||||
assert!(!bind.matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character("ц".into()),
|
||||
Some(&Physical::Code(Code::KeyQ)),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_space() {
|
||||
let bind = KeyBind {
|
||||
modifiers: vec![Modifier::Ctrl],
|
||||
key: Key::Character(" ".into()),
|
||||
};
|
||||
|
||||
assert!(bind.matches(Modifiers::CTRL, &Key::Character(" ".into()), None,));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_space_no_fallback() {
|
||||
assert!(!bind_ctrl_w().matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character(" ".into()),
|
||||
Some(&Physical::Code(Code::KeyW)),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_a_no_fallback_to_french_azerty_q() {
|
||||
let bind = KeyBind {
|
||||
modifiers: vec![Modifier::Ctrl],
|
||||
key: Key::Character("a".into()),
|
||||
};
|
||||
|
||||
assert!(!bind.matches(
|
||||
Modifiers::CTRL,
|
||||
&Key::Character("q".into()),
|
||||
Some(&Physical::Code(Code::KeyA)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue