From c1c92c4d5ecf4b933c5f46aad5a3a7d9be68c3fc Mon Sep 17 00:00:00 2001 From: Richard Acayan Date: Fri, 19 Jul 2024 17:07:04 -0400 Subject: [PATCH] wayland: keyboard: release keys while the keymap is changing Keeping the keys pressed can confuse some compositors, and the key codes may change. Release any keys that are pressed while the keymap is changing, and press them again afterwards. --- src/core/button.rs | 8 ++++---- src/core/layout.rs | 2 -- src/wayland/keyboard.rs | 36 +++++++++++++++++++++++++++++------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/core/button.rs b/src/core/button.rs index fdeb661..0e0c4cb 100644 --- a/src/core/button.rs +++ b/src/core/button.rs @@ -206,6 +206,10 @@ impl Button { self.kbd.release(Layout::modifier_keysym(modifier)); } + if old == ModState::Released { + self.kbd.press(Layout::modifier_keysym(modifier)); + } + if old == ModState::Released || new == ModState::Released { self.layout.update_modifiers(&self.modifiers); if Layout::is_keysym_modifier(modifier) { @@ -213,10 +217,6 @@ impl Button { } } - if old == ModState::Released { - self.kbd.press(Layout::modifier_keysym(modifier)); - } - true } else { false diff --git a/src/core/layout.rs b/src/core/layout.rs index 9c5f2a1..b22e5f6 100644 --- a/src/core/layout.rs +++ b/src/core/layout.rs @@ -165,10 +165,8 @@ impl Part { fn modify_no_fn(orig_sym: Keysym) -> Keysym { match orig_sym { - /* Keysym::F11 => Keysym::NoSymbol, Keysym::F12 => Keysym::NoSymbol, - */ _ => orig_sym, } } diff --git a/src/wayland/keyboard.rs b/src/wayland/keyboard.rs index 279ecac..52321b7 100644 --- a/src/wayland/keyboard.rs +++ b/src/wayland/keyboard.rs @@ -27,6 +27,7 @@ pub struct VirtualKeyboard { keymap_id: u8, keycodes: HashMap, + pressed: [Keysym; 248], mod_state: u32, } @@ -47,7 +48,8 @@ impl VirtualKeyboard { keymap, keymap_id: 1, - keycodes: HashMap::new(), + keycodes: HashMap::with_capacity(248), + pressed: [Keysym::NoSymbol; 248], mod_state: 0, } } @@ -101,6 +103,7 @@ impl Keyboard for VirtualKeyboard { } let keycode = *self.keycodes.get(&sym).unwrap(); + self.pressed[keycode as usize] = sym; self.vk.key(0, keycode as u32, 1); } @@ -127,6 +130,7 @@ impl Keyboard for VirtualKeyboard { } let keycode = *self.keycodes.get(&sym).unwrap(); + self.pressed[keycode as usize] = Keysym::NoSymbol; self.vk.key(0, keycode as u32, 0); } @@ -143,12 +147,9 @@ impl Keyboard for VirtualKeyboard { let path = format!("/tmp/ufkbd-keymap-pid{}-{}", process::id(), self.keymap_id); self.keymap = OpenOptions::new() - .read(true) - .write(true) - .create(true) - .truncate(true) - .open(path) - .unwrap(); + .read(true).write(true) + .create(true).truncate(true) + .open(path).unwrap(); self.keymap.write(b"xkb_keymap {\n").unwrap(); self.keymap.write(b" xkb_symbols \"ufkbd\" {\n").unwrap(); @@ -193,7 +194,28 @@ impl Keyboard for VirtualKeyboard { self.keymap.write(b" };\n").unwrap(); self.keymap.write(b"};\n").unwrap(); + if self.mod_state != 0 { + self.vk.modifiers(0, 0, 0, 0); + } + + for (code, sym) in self.pressed.iter().enumerate() { + if *sym != Keysym::NoSymbol { + self.vk.key(0, code as u32, 0); + } + } + let len = self.keymap.stream_position().unwrap() as u32; self.vk.keymap(KeymapFormat::XkbV1 as u32, self.keymap.as_fd(), len); + + if self.mod_state != 0 { + self.vk.modifiers(self.mod_state, 0, 0, 0); + } + + for sym in &self.pressed { + if *sym != Keysym::NoSymbol { + let code = *self.keycodes.get(&sym).unwrap(); + self.vk.key(0, code as u32, 1); + } + } } }