wayland: keyboard: add reis emulated input support

The Emulated Input (EI) protocol allows applications to send input
events through a distinct connection to the server, instead of through
Wayland. Add support for sending key presses through this protocol.
This commit is contained in:
Richard Acayan 2024-10-17 21:24:07 -04:00
parent ff24a39214
commit 89c96c511a
No known key found for this signature in database
GPG key ID: 0346F4894879DB73
2 changed files with 31 additions and 2 deletions

View file

@ -447,7 +447,7 @@ impl Dispatch<zwp_input_method_context_v1::ZwpInputMethodContextV1, ()> for Disp
zwp_input_method_context_v1::Event::Reset => (),
zwp_input_method_context_v1::Event::ContentType { .. } => (),
zwp_input_method_context_v1::Event::CommitState { serial } => {
ctx.seat.keyboard_mut().set_serial(serial);
ctx.seat.keyboard_mut().set_im_serial(serial);
},
zwp_input_method_context_v1::Event::PreferredLanguage { .. } => (),
_ => eprintln!("warn: unknown zwp_input_method_context_v1 event emitted"),

View file

@ -11,6 +11,7 @@ use crate::wayland::input_method_unstable_v2::zwp_input_method_manager_v2::ZwpIn
use crate::wayland::input_method_unstable_v2::zwp_input_method_v2::ZwpInputMethodV2;
use crate::wayland::virtual_keyboard_unstable_v1::zwp_virtual_keyboard_manager_v1::ZwpVirtualKeyboardManagerV1;
use crate::wayland::virtual_keyboard_unstable_v1::zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1;
use reis::ei;
use std::collections::HashMap;
use std::fs::File;
use std::fs::OpenOptions;
@ -110,7 +111,9 @@ pub struct VirtualKeyboard {
im: Option<ZwpInputMethodV2>,
im_ctx: Option<ZwpInputMethodContextV1>,
ei_kbd: Option<(ei::device::Device, ei::keyboard::Keyboard)>,
im_serial: u32,
ei_serial: u32,
keycodes: HashMap<Keysym, u8>,
pressed: [Keysym; 248],
@ -139,7 +142,9 @@ impl VirtualKeyboard {
im,
im_ctx: None,
ei_kbd: None,
im_serial: 0,
ei_serial: 0,
keycodes: HashMap::with_capacity(248),
pressed: [Keysym::NoSymbol; 248],
@ -176,15 +181,27 @@ impl VirtualKeyboard {
self.im_serial += 1;
}
pub fn set_serial(&mut self, serial: u32)
pub fn set_im_serial(&mut self, serial: u32)
{
self.im_serial = serial;
}
pub fn set_ei_serial(&mut self, serial: u32)
{
self.ei_serial = serial;
}
pub fn set_input_method_context(&mut self, imc: Option<ZwpInputMethodContextV1>)
{
self.im_ctx = imc;
}
pub fn set_ei_keyboard(&mut self,
dev: ei::device::Device,
kbd: ei::keyboard::Keyboard)
{
self.ei_kbd = Some((dev, kbd));
}
}
impl Keyboard for VirtualKeyboard {
@ -195,6 +212,8 @@ impl Keyboard for VirtualKeyboard {
Some(n) => n.starts_with("XK_"),
None => false,
}
} else if self.ei_kbd.is_some() {
STATIC_KEYCODES.binary_search_by_key(&sym, |(s, _)| *s).is_ok()
} else {
self.im_ctx.is_some()
}
@ -225,6 +244,11 @@ impl Keyboard for VirtualKeyboard {
let keycode = *self.keycodes.get(&sym).unwrap();
self.pressed[keycode as usize] = sym;
vk.key(0, keycode as u32, 1);
} else if let Some((d, k)) = &self.ei_kbd {
let i = STATIC_KEYCODES.binary_search_by_key(&sym, |(s, _)| *s).unwrap();
let keycode = STATIC_KEYCODES[i].1 - 8;
k.key(keycode as u32, ei::keyboard::KeyState::Press);
d.frame(self.ei_serial, 0);
} else if let Some(imc) = &self.im_ctx {
imc.keysym(self.im_serial, 0, sym.raw(), 0, self.mod_state);
}
@ -255,6 +279,11 @@ impl Keyboard for VirtualKeyboard {
let keycode = *self.keycodes.get(&sym).unwrap();
self.pressed[keycode as usize] = Keysym::NoSymbol;
vk.key(0, keycode as u32, 0);
} else if let Some((d, k)) = &self.ei_kbd {
let i = STATIC_KEYCODES.binary_search_by_key(&sym, |(s, _)| *s).unwrap();
let keycode = STATIC_KEYCODES[i].1 - 8;
k.key(keycode as u32, ei::keyboard::KeyState::Released);
d.frame(self.ei_serial, 0);
} else if let Some(imc) = &self.im_ctx {
imc.keysym(self.im_serial, 0, sym.raw(), 0, self.mod_state);
}