keyboard: send keymap without actions/behaviors to xwayland
This commit is contained in:
parent
541a7b5ebc
commit
abaeed4c01
10 changed files with 52 additions and 34 deletions
|
|
@ -36,8 +36,8 @@ impl EiKeyboard {
|
||||||
self.client.event(Keymap {
|
self.client.event(Keymap {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
keymap_type: KEYMAP_TYPE_XKB,
|
keymap_type: KEYMAP_TYPE_XKB,
|
||||||
size: state.map_len as _,
|
size: state.map.len as _,
|
||||||
keymap: state.map.clone(),
|
keymap: state.map.map.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ impl JayInput {
|
||||||
fn send_keymap(&self, map: &KbvmMap) {
|
fn send_keymap(&self, map: &KbvmMap) {
|
||||||
self.client.event(Keymap {
|
self.client.event(Keymap {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
keymap: map.map.clone(),
|
keymap: map.map.map.clone(),
|
||||||
keymap_len: (map.map_len - 1) as _,
|
keymap_len: (map.map.len - 1) as _,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ use {
|
||||||
xdg_toplevel_drag_v1::XdgToplevelDragV1,
|
xdg_toplevel_drag_v1::XdgToplevelDragV1,
|
||||||
},
|
},
|
||||||
kbvm::{KbvmMap, KbvmMapId, KbvmState, PhysicalKeyboardState},
|
kbvm::{KbvmMap, KbvmMapId, KbvmState, PhysicalKeyboardState},
|
||||||
keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId},
|
keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId, KeymapFd},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
|
|
@ -104,7 +104,6 @@ use {
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
},
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
uapi::OwnedFd,
|
|
||||||
};
|
};
|
||||||
pub use {
|
pub use {
|
||||||
event_handling::NodeSeatState,
|
event_handling::NodeSeatState,
|
||||||
|
|
@ -1179,11 +1178,15 @@ impl WlSeat {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keymap_fd(&self, state: &KeyboardState) -> Result<Rc<OwnedFd>, WlKeyboardError> {
|
pub fn keymap_fd(&self, state: &KeyboardState) -> Result<KeymapFd, WlKeyboardError> {
|
||||||
|
let fd = match self.client.is_xwayland {
|
||||||
|
true => &state.xwayland_map,
|
||||||
|
_ => &state.map,
|
||||||
|
};
|
||||||
if self.version >= READ_ONLY_KEYMAP_SINCE {
|
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()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl ZwpInputMethodKeyboardGrabV2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_keymap(&self, kb_state: &KeyboardState) {
|
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,
|
Ok(m) => m,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Could not create new keymap fd: {}", ErrorFmt(e));
|
log::error!("Could not create new keymap fd: {}", ErrorFmt(e));
|
||||||
|
|
@ -37,8 +37,8 @@ impl ZwpInputMethodKeyboardGrabV2 {
|
||||||
self.client.event(Keymap {
|
self.client.event(Keymap {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
format: wl_keyboard::XKB_V1,
|
format: wl_keyboard::XKB_V1,
|
||||||
fd: map,
|
fd: map.map,
|
||||||
size: kb_state.map_len as _,
|
size: map.len as _,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,8 @@ impl WlKeyboard {
|
||||||
self.seat.client.event(Keymap {
|
self.seat.client.event(Keymap {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
format: XKB_V1,
|
format: XKB_V1,
|
||||||
fd,
|
fd: fd.map,
|
||||||
size: state.map_len as _,
|
size: fd.len as _,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ impl ZwpVirtualKeyboardManagerV1RequestHandler for ZwpVirtualKeyboardManagerV1 {
|
||||||
kb_state: Rc::new(RefCell::new(KeyboardState {
|
kb_state: Rc::new(RefCell::new(KeyboardState {
|
||||||
id: self.client.state.keyboard_state_ids.next(),
|
id: self.client.state.keyboard_state_ids.next(),
|
||||||
map: seat_keymap.map.clone(),
|
map: seat_keymap.map.clone(),
|
||||||
map_len: seat_keymap.map_len,
|
xwayland_map: seat_keymap.xwayland_map.clone(),
|
||||||
pressed_keys: Default::default(),
|
pressed_keys: Default::default(),
|
||||||
mods: Default::default(),
|
mods: Default::default(),
|
||||||
})),
|
})),
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 {
|
||||||
*self.kb_state.borrow_mut() = KeyboardState {
|
*self.kb_state.borrow_mut() = KeyboardState {
|
||||||
id: self.client.state.keyboard_state_ids.next(),
|
id: self.client.state.keyboard_state_ids.next(),
|
||||||
map: map.map.clone(),
|
map: map.map.clone(),
|
||||||
map_len: map.map_len,
|
xwayland_map: map.xwayland_map.clone(),
|
||||||
pressed_keys: Default::default(),
|
pressed_keys: Default::default(),
|
||||||
mods: Default::default(),
|
mods: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
let virtual_keymap_str = {
|
let virtual_keymap_str = {
|
||||||
let xkb = KbvmContext::default();
|
let xkb = KbvmContext::default();
|
||||||
let map = xkb.parse_keymap(VIRTUAL_KEYMAP.as_bytes()).unwrap();
|
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?;
|
let ds = run.create_default_setup().await?;
|
||||||
|
|
|
||||||
28
src/kbvm.rs
28
src/kbvm.rs
|
|
@ -2,7 +2,7 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::KeyState,
|
backend::KeyState,
|
||||||
ifs::wl_seat::WlSeatGlobal,
|
ifs::wl_seat::WlSeatGlobal,
|
||||||
keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId},
|
keyboard::{DynKeyboardState, KeyboardState, KeyboardStateId, KeymapFd},
|
||||||
utils::{oserror::OsError, syncqueue::SyncQueue, vecset::VecSet},
|
utils::{oserror::OsError, syncqueue::SyncQueue, vecset::VecSet},
|
||||||
},
|
},
|
||||||
kbvm::{
|
kbvm::{
|
||||||
|
|
@ -21,7 +21,7 @@ use {
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
},
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
uapi::{c, OwnedFd},
|
uapi::c,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
@ -54,8 +54,8 @@ pub struct KbvmMap {
|
||||||
pub id: KbvmMapId,
|
pub id: KbvmMapId,
|
||||||
pub state_machine: StateMachine,
|
pub state_machine: StateMachine,
|
||||||
pub lookup_table: LookupTable,
|
pub lookup_table: LookupTable,
|
||||||
pub map: Rc<OwnedFd>,
|
pub map: KeymapFd,
|
||||||
pub map_len: usize,
|
pub xwayland_map: KeymapFd,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KbvmState {
|
pub struct KbvmState {
|
||||||
|
|
@ -89,20 +89,23 @@ impl KbvmContext {
|
||||||
.ctx
|
.ctx
|
||||||
.keymap_from_bytes(WriteToLog, None, keymap)
|
.keymap_from_bytes(WriteToLog, None, keymap)
|
||||||
.map_err(KbvmError::CouldNotParseKeymap)?;
|
.map_err(KbvmError::CouldNotParseKeymap)?;
|
||||||
let (memfd, len) = create_keymap_memfd(&map).map_err(KbvmError::KeymapMemfd)?;
|
|
||||||
let builder = map.to_builder();
|
let builder = map.to_builder();
|
||||||
Ok(Rc::new(KbvmMap {
|
Ok(Rc::new(KbvmMap {
|
||||||
id: self.ids.next(),
|
id: self.ids.next(),
|
||||||
state_machine: builder.build_state_machine(),
|
state_machine: builder.build_state_machine(),
|
||||||
map: Rc::new(memfd),
|
map: create_keymap_memfd(&map, false).map_err(KbvmError::KeymapMemfd)?,
|
||||||
map_len: len + 1,
|
xwayland_map: create_keymap_memfd(&map, true).map_err(KbvmError::KeymapMemfd)?,
|
||||||
lookup_table: builder.build_lookup_table(),
|
lookup_table: builder.build_lookup_table(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_keymap_memfd(map: &Keymap) -> Result<(OwnedFd, usize), OsError> {
|
fn create_keymap_memfd(map: &Keymap, xwayland: bool) -> Result<KeymapFd, OsError> {
|
||||||
let str = format!("{}\n", map.format());
|
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)?;
|
let mut memfd = uapi::memfd_create("keymap", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING)?;
|
||||||
memfd.write_all(str.as_bytes())?;
|
memfd.write_all(str.as_bytes())?;
|
||||||
memfd.write_all(&[0])?;
|
memfd.write_all(&[0])?;
|
||||||
|
|
@ -111,7 +114,10 @@ fn create_keymap_memfd(map: &Keymap) -> Result<(OwnedFd, usize), OsError> {
|
||||||
memfd.raw(),
|
memfd.raw(),
|
||||||
c::F_SEAL_SEAL | c::F_SEAL_GROW | c::F_SEAL_SHRINK | c::F_SEAL_WRITE,
|
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 {
|
impl KbvmMap {
|
||||||
|
|
@ -122,7 +128,7 @@ impl KbvmMap {
|
||||||
kb_state: KeyboardState {
|
kb_state: KeyboardState {
|
||||||
id,
|
id,
|
||||||
map: self.map.clone(),
|
map: self.map.clone(),
|
||||||
map_len: self.map_len,
|
xwayland_map: self.xwayland_map.clone(),
|
||||||
pressed_keys: Default::default(),
|
pressed_keys: Default::default(),
|
||||||
mods: Default::default(),
|
mods: Default::default(),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ linear_ids!(KeyboardStateIds, KeyboardStateId, u64);
|
||||||
|
|
||||||
pub struct KeyboardState {
|
pub struct KeyboardState {
|
||||||
pub id: KeyboardStateId,
|
pub id: KeyboardStateId,
|
||||||
pub map: Rc<OwnedFd>,
|
pub map: KeymapFd,
|
||||||
pub map_len: usize,
|
pub xwayland_map: KeymapFd,
|
||||||
pub pressed_keys: VecSet<u32>,
|
pub pressed_keys: VecSet<u32>,
|
||||||
pub mods: Components,
|
pub mods: Components,
|
||||||
}
|
}
|
||||||
|
|
@ -37,13 +37,19 @@ impl DynKeyboardState for RefCell<KeyboardState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyboardState {
|
#[derive(Clone)]
|
||||||
pub fn create_new_keymap_fd(&self) -> Result<Rc<OwnedFd>, KeyboardError> {
|
pub struct KeymapFd {
|
||||||
|
pub map: Rc<OwnedFd>,
|
||||||
|
pub len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeymapFd {
|
||||||
|
pub fn create_unprotected_fd(&self) -> Result<Self, KeyboardError> {
|
||||||
let fd = match uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC) {
|
let fd = match uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC) {
|
||||||
Ok(fd) => fd,
|
Ok(fd) => fd,
|
||||||
Err(e) => return Err(KeyboardError::KeymapMemfd(e.into())),
|
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;
|
let mut pos = 0;
|
||||||
while pos < target {
|
while pos < target {
|
||||||
let rem = target - pos;
|
let rem = target - pos;
|
||||||
|
|
@ -53,6 +59,9 @@ impl KeyboardState {
|
||||||
Err(e) => return Err(KeyboardError::KeymapCopy(e.into())),
|
Err(e) => return Err(KeyboardError::KeymapCopy(e.into())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Rc::new(fd))
|
Ok(Self {
|
||||||
|
map: Rc::new(fd),
|
||||||
|
len: self.len,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue