From 81aae23fe7d86c7cf2b79e4589e092f946965141 Mon Sep 17 00:00:00 2001 From: Richard Acayan Date: Wed, 25 Sep 2024 19:53:13 -0400 Subject: [PATCH] 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. --- src/wayland/keyboard.rs | 107 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/wayland/keyboard.rs b/src/wayland/keyboard.rs index a81eadc..f6c7e2e 100644 --- a/src/wayland/keyboard.rs +++ b/src/wayland/keyboard.rs @@ -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, 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, i).unwrap(); } + for i in keycode..255 { + if used_codes[i as usize - 8] { + writeln!(self.keymap, " = {};", 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();