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)); 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 { if old == ModState::Released || new == ModState::Released {
self.layout.update_modifiers(&self.modifiers); self.layout.update_modifiers(&self.modifiers);
if Layout::is_keysym_modifier(modifier) { 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 true
} else { } else {
false false

View file

@ -165,10 +165,8 @@ impl Part {
fn modify_no_fn(orig_sym: Keysym) -> Keysym fn modify_no_fn(orig_sym: Keysym) -> Keysym
{ {
match orig_sym { match orig_sym {
/*
Keysym::F11 => Keysym::NoSymbol, Keysym::F11 => Keysym::NoSymbol,
Keysym::F12 => Keysym::NoSymbol, Keysym::F12 => Keysym::NoSymbol,
*/
_ => orig_sym, _ => orig_sym,
} }
} }

View file

@ -27,6 +27,7 @@ pub struct VirtualKeyboard {
keymap_id: u8, keymap_id: u8,
keycodes: HashMap<Keysym, u8>, keycodes: HashMap<Keysym, u8>,
pressed: [Keysym; 248],
mod_state: u32, mod_state: u32,
} }
@ -47,7 +48,8 @@ impl VirtualKeyboard {
keymap, keymap,
keymap_id: 1, keymap_id: 1,
keycodes: HashMap::new(), keycodes: HashMap::with_capacity(248),
pressed: [Keysym::NoSymbol; 248],
mod_state: 0, mod_state: 0,
} }
} }
@ -101,6 +103,7 @@ impl Keyboard for VirtualKeyboard {
} }
let keycode = *self.keycodes.get(&sym).unwrap(); let keycode = *self.keycodes.get(&sym).unwrap();
self.pressed[keycode as usize] = sym;
self.vk.key(0, keycode as u32, 1); self.vk.key(0, keycode as u32, 1);
} }
@ -127,6 +130,7 @@ impl Keyboard for VirtualKeyboard {
} }
let keycode = *self.keycodes.get(&sym).unwrap(); let keycode = *self.keycodes.get(&sym).unwrap();
self.pressed[keycode as usize] = Keysym::NoSymbol;
self.vk.key(0, keycode as u32, 0); self.vk.key(0, keycode as u32, 0);
} }
@ -143,12 +147,9 @@ impl Keyboard for VirtualKeyboard {
let path = format!("/tmp/ufkbd-keymap-pid{}-{}", let path = format!("/tmp/ufkbd-keymap-pid{}-{}",
process::id(), self.keymap_id); process::id(), self.keymap_id);
self.keymap = OpenOptions::new() self.keymap = OpenOptions::new()
.read(true) .read(true).write(true)
.write(true) .create(true).truncate(true)
.create(true) .open(path).unwrap();
.truncate(true)
.open(path)
.unwrap();
self.keymap.write(b"xkb_keymap {\n").unwrap(); self.keymap.write(b"xkb_keymap {\n").unwrap();
self.keymap.write(b" xkb_symbols \"ufkbd\" {\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();
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; let len = self.keymap.stream_position().unwrap() as u32;
self.vk.keymap(KeymapFormat::XkbV1 as u32, self.keymap.as_fd(), len); 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);
}
}
} }
} }