wayland: keyboard: assign static key codes for some keys

Some applications like Waydroid and Klavaro (with the Enter key) ignore
the keyboard layout and expect a key code from the Linux input UAPI.
Assign static key codes for keys on the QWERTY layout so some keys can
still work with these applications.
This commit is contained in:
Richard Acayan 2024-09-25 19:53:13 -04:00
parent e8a3995710
commit 81aae23fe7

View file

@ -24,6 +24,85 @@ use wayland_client::protocol::wl_seat::WlSeat;
use wayland_client::protocol::wl_keyboard::KeymapFormat;
use xkeysym::Keysym;
const STATIC_KEYCODES: [(Keysym, u8); 76] = [
(Keysym::space, 65),
(Keysym::apostrophe, 48),
(Keysym::comma, 59),
(Keysym::minus, 20),
(Keysym::period, 60),
(Keysym::slash, 61),
(Keysym::_0, 19),
(Keysym::_1, 10),
(Keysym::_2, 11),
(Keysym::_3, 12),
(Keysym::_4, 13),
(Keysym::_5, 14),
(Keysym::_6, 15),
(Keysym::_7, 16),
(Keysym::_8, 17),
(Keysym::_9, 18),
(Keysym::semicolon, 47),
(Keysym::equal, 21),
(Keysym::bracketleft, 34),
(Keysym::backslash, 51),
(Keysym::bracketright, 35),
(Keysym::grave, 49),
(Keysym::a, 38),
(Keysym::b, 56),
(Keysym::c, 54),
(Keysym::d, 40),
(Keysym::e, 26),
(Keysym::f, 41),
(Keysym::g, 42),
(Keysym::h, 43),
(Keysym::i, 31),
(Keysym::j, 44),
(Keysym::k, 45),
(Keysym::l, 46),
(Keysym::m, 58),
(Keysym::n, 57),
(Keysym::o, 32),
(Keysym::p, 33),
(Keysym::q, 24),
(Keysym::r, 27),
(Keysym::s, 39),
(Keysym::t, 28),
(Keysym::u, 30),
(Keysym::v, 55),
(Keysym::w, 25),
(Keysym::x, 53),
(Keysym::y, 29),
(Keysym::z, 52),
(Keysym::BackSpace, 22),
(Keysym::Tab, 23),
(Keysym::Return, 36),
(Keysym::Escape, 9),
(Keysym::Home, 110),
(Keysym::Left, 113),
(Keysym::Up, 111),
(Keysym::Right, 114),
(Keysym::Down, 116),
(Keysym::Prior, 112),
(Keysym::Next, 117),
(Keysym::End, 115),
(Keysym::Insert, 118),
(Keysym::F1, 67),
(Keysym::F2, 68),
(Keysym::F3, 69),
(Keysym::F4, 70),
(Keysym::F5, 71),
(Keysym::F6, 72),
(Keysym::F7, 73),
(Keysym::F8, 74),
(Keysym::F9, 75),
(Keysym::F10, 76),
(Keysym::F11, 95),
(Keysym::F12, 96),
(Keysym::Shift_L, 50),
(Keysym::Control_L, 37),
(Keysym::Delete, 119),
];
pub struct VirtualKeyboard {
vk: Option<ZwpVirtualKeyboardV1>,
keymap: File,
@ -196,6 +275,7 @@ impl Keyboard for VirtualKeyboard {
fn change_layout(&mut self, layout: &Layout)
{
let mut keycode = 8;
let mut used_codes = [false; 248];
self.keymap_id = match self.keymap_id {
0 => 1,
@ -214,6 +294,23 @@ impl Keyboard for VirtualKeyboard {
self.keymap.write_all(b" xkb_symbols \"ufkbd\" {\n").unwrap();
self.keycodes.clear();
for row in layout.rows() {
for key in row {
for part in &key.parts {
if !part.key_available() {
continue;
}
if let Ok(idx) = STATIC_KEYCODES.binary_search_by_key(&part.sym(), |(s, _)| *s) {
let (sym, code) = STATIC_KEYCODES[idx];
self.keycodes.insert(sym, code - 8);
self.write_key(part, code);
used_codes[code as usize - 8] = true;
}
}
}
}
for row in layout.rows() {
for key in row {
for part in &key.parts {
@ -225,6 +322,10 @@ impl Keyboard for VirtualKeyboard {
continue;
}
while used_codes[keycode as usize - 8] {
keycode += 1;
}
self.keycodes.insert(part.sym(), keycode - 8);
self.write_key(part, keycode);
keycode += 1;
@ -242,6 +343,12 @@ impl Keyboard for VirtualKeyboard {
writeln!(self.keymap, " <I{:03}> = {};", i, i).unwrap();
}
for i in keycode..255 {
if used_codes[i as usize - 8] {
writeln!(self.keymap, " <I{:03}> = {};", i, i).unwrap();
}
}
self.keymap.write_all(b" indicator 1 = \"Caps Lock\";\n").unwrap();
self.keymap.write_all(b" };\n").unwrap();
self.keymap.write_all(b"\n").unwrap();