This commit is contained in:
Junkui Zhang
2025-05-21 16:30:10 +08:00
parent 061ba9b6d2
commit be79ccde07
2 changed files with 68 additions and 14 deletions

View File

@@ -1,3 +1,4 @@
#[cfg(any(feature = "wayland", feature = "x11"))]
use collections::HashMap;
#[cfg(any(feature = "wayland", feature = "x11"))]
use xkbcommon::xkb::Keycode;
@@ -58,15 +59,53 @@ impl LinuxKeyboardMapper {
}
}
pub(crate) fn get_key(&self, keycode: Keycode, shift: bool) -> Option<String> {
if shift {
self.code_to_shifted_key.get(&keycode).cloned()
} else {
pub(crate) fn get_key(
&self,
keycode: Keycode,
modifiers: &mut crate::Modifiers,
) -> Option<String> {
if is_alphabetic_key(keycode) || !modifiers.shift {
self.code_to_key.get(&keycode).cloned()
} else {
modifiers.shift = false;
self.code_to_shifted_key.get(&keycode).cloned()
}
}
}
#[cfg(any(feature = "wayland", feature = "x11"))]
fn is_alphabetic_key(keycode: Keycode) -> bool {
matches!(
keycode.raw(),
0x0026 // a
| 0x0038 // b
| 0x0036 // c
| 0x0028 // d
| 0x001a // e
| 0x0029 // f
| 0x002a // g
| 0x002b // h
| 0x001f // i
| 0x002c // j
| 0x002d // k
| 0x002e // l
| 0x003a // m
| 0x0039 // n
| 0x0020 // o
| 0x0021 // p
| 0x0018 // q
| 0x001b // r
| 0x0027 // s
| 0x001c // t
| 0x001e // u
| 0x0037 // v
| 0x0019 // w
| 0x0035 // x
| 0x001d // y
| 0x0034 // z
)
}
// All typeable scan codes for the standard US keyboard layout, ANSI104
#[cfg(any(feature = "wayland", feature = "x11"))]
const TYPEABLE_CODES: &[u32] = &[

View File

@@ -759,9 +759,33 @@ impl crate::Keystroke {
Keysym::XF86_New => "new".to_owned(),
Keysym::XF86_Open => "open".to_owned(),
Keysym::XF86_Save => "save".to_owned(),
Keysym::F1 => "f1".to_owned(),
Keysym::F2 => "f2".to_owned(),
Keysym::F3 => "f3".to_owned(),
Keysym::F4 => "f4".to_owned(),
Keysym::F5 => "f5".to_owned(),
Keysym::F6 => "f6".to_owned(),
Keysym::F7 => "f7".to_owned(),
Keysym::F8 => "f8".to_owned(),
Keysym::F9 => "f9".to_owned(),
Keysym::F10 => "f10".to_owned(),
Keysym::F11 => "f11".to_owned(),
Keysym::F12 => "f12".to_owned(),
Keysym::F13 => "f13".to_owned(),
Keysym::F14 => "f14".to_owned(),
Keysym::F15 => "f15".to_owned(),
Keysym::F16 => "f16".to_owned(),
Keysym::F17 => "f17".to_owned(),
Keysym::F18 => "f18".to_owned(),
Keysym::F19 => "f19".to_owned(),
Keysym::F20 => "f20".to_owned(),
Keysym::F21 => "f21".to_owned(),
Keysym::F22 => "f22".to_owned(),
Keysym::F23 => "f23".to_owned(),
Keysym::F24 => "f24".to_owned(),
_ => keyboard_state
.mapper
.get_key(keycode, modifiers.shift)
.get_key(keycode, &mut modifiers)
.unwrap_or_else(|| {
let name = xkb::keysym_get_name(key_sym).to_lowercase();
if key_sym.is_keypad_key() {
@@ -772,15 +796,6 @@ impl crate::Keystroke {
}),
};
if modifiers.shift {
// we only include the shift for upper-case letters by convention,
// so don't include for numbers and symbols, but do include for
// tab/enter, etc.
if key.chars().count() == 1 && key.to_lowercase() == key.to_uppercase() {
modifiers.shift = false;
}
}
// Ignore control characters (and DEL) for the purposes of key_char
let key_char = (!key_utf8.is_empty() && !key_utf8.chars().next().unwrap().is_control())
.then_some(key_utf8);