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.
This commit is contained in:
Richard Acayan 2024-07-19 17:07:04 -04:00
parent 4a6b261be0
commit c1c92c4d5e
3 changed files with 33 additions and 13 deletions

View file

@ -206,6 +206,10 @@ impl<D: Display, K: Keyboard> Button<D, K> {
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<D: Display, K: Keyboard> Button<D, K> {
}
}
if old == ModState::Released {
self.kbd.press(Layout::modifier_keysym(modifier));
}
true
} else {
false

View file

@ -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,
}
}

View file

@ -27,6 +27,7 @@ pub struct VirtualKeyboard {
keymap_id: u8,
keycodes: HashMap<Keysym, u8>,
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);
}
}
}
}