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>,
|
physical_key: Option<&Physical>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let key_eq = self.key_eq(key)
|
let key_eq = self.key_eq(key)
|
||||||
|| physical_key
|
|| (!is_latin_shortcut_key(key)
|
||||||
.and_then(physical_key_to_latin)
|
&& physical_key
|
||||||
.is_some_and(|latin| self.key_eq(&latin));
|
.and_then(physical_key_to_latin)
|
||||||
|
.is_some_and(|latin| self.key_eq(&latin)));
|
||||||
key_eq
|
key_eq
|
||||||
&& modifiers.logo() == self.modifiers.contains(&Modifier::Super)
|
&& modifiers.logo() == self.modifiers.contains(&Modifier::Super)
|
||||||
&& modifiers.control() == self.modifiers.contains(&Modifier::Ctrl)
|
&& 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`.
|
/// Converts a physical key code to the corresponding US-layout Latin `Key`.
|
||||||
///
|
///
|
||||||
/// This mapping is intentionally limited to keys that may produce different
|
/// 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