diff --git a/src/ei/ei_ifs/ei_keyboard.rs b/src/ei/ei_ifs/ei_keyboard.rs index 69e342db..a510d87e 100644 --- a/src/ei/ei_ifs/ei_keyboard.rs +++ b/src/ei/ei_ifs/ei_keyboard.rs @@ -36,8 +36,8 @@ impl EiKeyboard { self.client.event(Keymap { self_id: self.id, keymap_type: KEYMAP_TYPE_XKB, - size: state.map_len as _, - keymap: state.map.clone(), + size: state.map.len as _, + keymap: state.map.map.clone(), }); } diff --git a/src/ifs/jay_input.rs b/src/ifs/jay_input.rs index 8c9f5513..14291c90 100644 --- a/src/ifs/jay_input.rs +++ b/src/ifs/jay_input.rs @@ -75,8 +75,8 @@ impl JayInput { fn send_keymap(&self, map: &KbvmMap) { self.client.event(Keymap { self_id: self.id, - keymap: map.map.clone(), - keymap_len: (map.map_len - 1) as _, + keymap: map.map.map.clone(), + keymap_len: (map.map.len - 1) as _, }); } diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index aa392568..459dcbf1 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -73,7 +73,7 @@ use { xdg_toplevel_drag_v1::XdgToplevelDragV1, }, kbvm::{KbvmMap, KbvmMapId, KbvmState, PhysicalKeyboardState}, - keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId}, + keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId, KeymapFd}, leaks::Tracker, object::{Object, Version}, rect::Rect, @@ -104,7 +104,6 @@ use { rc::{Rc, Weak}, }, thiserror::Error, - uapi::OwnedFd, }; pub use { event_handling::NodeSeatState, @@ -1179,11 +1178,15 @@ impl WlSeat { }) } - pub fn keymap_fd(&self, state: &KeyboardState) -> Result, WlKeyboardError> { + pub fn keymap_fd(&self, state: &KeyboardState) -> Result { + let fd = match self.client.is_xwayland { + true => &state.xwayland_map, + _ => &state.map, + }; if self.version >= READ_ONLY_KEYMAP_SINCE { - return Ok(state.map.clone()); + return Ok(fd.clone()); } - Ok(state.create_new_keymap_fd()?) + Ok(fd.create_unprotected_fd()?) } } diff --git a/src/ifs/wl_seat/text_input/zwp_input_method_keyboard_grab_v2.rs b/src/ifs/wl_seat/text_input/zwp_input_method_keyboard_grab_v2.rs index 21935562..927e9de7 100644 --- a/src/ifs/wl_seat/text_input/zwp_input_method_keyboard_grab_v2.rs +++ b/src/ifs/wl_seat/text_input/zwp_input_method_keyboard_grab_v2.rs @@ -27,7 +27,7 @@ impl ZwpInputMethodKeyboardGrabV2 { } fn send_keymap(&self, kb_state: &KeyboardState) { - let map = match kb_state.create_new_keymap_fd() { + let map = match kb_state.map.create_unprotected_fd() { Ok(m) => m, Err(e) => { log::error!("Could not create new keymap fd: {}", ErrorFmt(e)); @@ -37,8 +37,8 @@ impl ZwpInputMethodKeyboardGrabV2 { self.client.event(Keymap { self_id: self.id, format: wl_keyboard::XKB_V1, - fd: map, - size: kb_state.map_len as _, + fd: map.map, + size: map.len as _, }); } diff --git a/src/ifs/wl_seat/wl_keyboard.rs b/src/ifs/wl_seat/wl_keyboard.rs index 55c4b8de..aaea9c07 100644 --- a/src/ifs/wl_seat/wl_keyboard.rs +++ b/src/ifs/wl_seat/wl_keyboard.rs @@ -74,8 +74,8 @@ impl WlKeyboard { self.seat.client.event(Keymap { self_id: self.id, format: XKB_V1, - fd, - size: state.map_len as _, + fd: fd.map, + size: fd.len as _, }); } diff --git a/src/ifs/wl_seat/zwp_virtual_keyboard_manager_v1.rs b/src/ifs/wl_seat/zwp_virtual_keyboard_manager_v1.rs index 2ee99651..58e5f6fa 100644 --- a/src/ifs/wl_seat/zwp_virtual_keyboard_manager_v1.rs +++ b/src/ifs/wl_seat/zwp_virtual_keyboard_manager_v1.rs @@ -87,7 +87,7 @@ impl ZwpVirtualKeyboardManagerV1RequestHandler for ZwpVirtualKeyboardManagerV1 { kb_state: Rc::new(RefCell::new(KeyboardState { id: self.client.state.keyboard_state_ids.next(), map: seat_keymap.map.clone(), - map_len: seat_keymap.map_len, + xwayland_map: seat_keymap.xwayland_map.clone(), pressed_keys: Default::default(), mods: Default::default(), })), diff --git a/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs b/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs index 09c6f276..2f748dcf 100644 --- a/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs +++ b/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs @@ -80,7 +80,7 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 { *self.kb_state.borrow_mut() = KeyboardState { id: self.client.state.keyboard_state_ids.next(), map: map.map.clone(), - map_len: map.map_len, + xwayland_map: map.xwayland_map.clone(), pressed_keys: Default::default(), mods: Default::default(), }; diff --git a/src/it/tests/t0040_virtual_keyboard.rs b/src/it/tests/t0040_virtual_keyboard.rs index 78ccb5f0..b8d125cc 100644 --- a/src/it/tests/t0040_virtual_keyboard.rs +++ b/src/it/tests/t0040_virtual_keyboard.rs @@ -16,7 +16,7 @@ async fn test(run: Rc) -> TestResult { let virtual_keymap_str = { let xkb = KbvmContext::default(); let map = xkb.parse_keymap(VIRTUAL_KEYMAP.as_bytes()).unwrap(); - read_keymap(&map.map, map.map_len) + read_keymap(&map.map.map, map.map.len) }; let ds = run.create_default_setup().await?; diff --git a/src/kbvm.rs b/src/kbvm.rs index 9a8e5fd7..44236626 100644 --- a/src/kbvm.rs +++ b/src/kbvm.rs @@ -2,7 +2,7 @@ use { crate::{ backend::KeyState, ifs::wl_seat::WlSeatGlobal, - keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId}, + keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId, KeymapFd}, utils::{oserror::OsError, syncqueue::SyncQueue, vecset::VecSet}, }, kbvm::{ @@ -21,7 +21,7 @@ use { rc::Rc, }, thiserror::Error, - uapi::{c, OwnedFd}, + uapi::c, }; #[derive(Debug, Error)] @@ -54,8 +54,8 @@ pub struct KbvmMap { pub id: KbvmMapId, pub state_machine: StateMachine, pub lookup_table: LookupTable, - pub map: Rc, - pub map_len: usize, + pub map: KeymapFd, + pub xwayland_map: KeymapFd, } pub struct KbvmState { @@ -89,20 +89,23 @@ impl KbvmContext { .ctx .keymap_from_bytes(WriteToLog, None, keymap) .map_err(KbvmError::CouldNotParseKeymap)?; - let (memfd, len) = create_keymap_memfd(&map).map_err(KbvmError::KeymapMemfd)?; let builder = map.to_builder(); Ok(Rc::new(KbvmMap { id: self.ids.next(), state_machine: builder.build_state_machine(), - map: Rc::new(memfd), - map_len: len + 1, + map: create_keymap_memfd(&map, false).map_err(KbvmError::KeymapMemfd)?, + xwayland_map: create_keymap_memfd(&map, true).map_err(KbvmError::KeymapMemfd)?, lookup_table: builder.build_lookup_table(), })) } } -fn create_keymap_memfd(map: &Keymap) -> Result<(OwnedFd, usize), OsError> { - let str = format!("{}\n", map.format()); +fn create_keymap_memfd(map: &Keymap, xwayland: bool) -> Result { + let mut format = map.format(); + if xwayland { + format = format.lookup_only(true).rename_long_keys(true); + } + let str = format!("{}\n", format); let mut memfd = uapi::memfd_create("keymap", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING)?; memfd.write_all(str.as_bytes())?; memfd.write_all(&[0])?; @@ -111,7 +114,10 @@ fn create_keymap_memfd(map: &Keymap) -> Result<(OwnedFd, usize), OsError> { memfd.raw(), c::F_SEAL_SEAL | c::F_SEAL_GROW | c::F_SEAL_SHRINK | c::F_SEAL_WRITE, )?; - Ok((memfd, str.len())) + Ok(KeymapFd { + map: Rc::new(memfd), + len: str.len() + 1, + }) } impl KbvmMap { @@ -122,7 +128,7 @@ impl KbvmMap { kb_state: KeyboardState { id, map: self.map.clone(), - map_len: self.map_len, + xwayland_map: self.xwayland_map.clone(), pressed_keys: Default::default(), mods: Default::default(), }, diff --git a/src/keyboard.rs b/src/keyboard.rs index 1b8d113d..cbe74093 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -21,8 +21,8 @@ linear_ids!(KeyboardStateIds, KeyboardStateId, u64); pub struct KeyboardState { pub id: KeyboardStateId, - pub map: Rc, - pub map_len: usize, + pub map: KeymapFd, + pub xwayland_map: KeymapFd, pub pressed_keys: VecSet, pub mods: Components, } @@ -37,13 +37,19 @@ impl DynKeyboardState for RefCell { } } -impl KeyboardState { - pub fn create_new_keymap_fd(&self) -> Result, KeyboardError> { +#[derive(Clone)] +pub struct KeymapFd { + pub map: Rc, + pub len: usize, +} + +impl KeymapFd { + pub fn create_unprotected_fd(&self) -> Result { let fd = match uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC) { Ok(fd) => fd, Err(e) => return Err(KeyboardError::KeymapMemfd(e.into())), }; - let target = self.map_len as c::off_t; + let target = self.len as c::off_t; let mut pos = 0; while pos < target { let rem = target - pos; @@ -53,6 +59,9 @@ impl KeyboardState { Err(e) => return Err(KeyboardError::KeymapCopy(e.into())), } } - Ok(Rc::new(fd)) + Ok(Self { + map: Rc::new(fd), + len: self.len, + }) } }