1
0
Fork 0
forked from wry/wry

seat: update xkb_state when keymap changes

This commit is contained in:
Julian Orth 2022-05-04 22:10:38 +02:00
parent a80c5690c8
commit 76c47c24d0
7 changed files with 123 additions and 5 deletions

View file

@ -265,7 +265,15 @@ impl WlSeatGlobal {
}
pub fn set_keymap(&self, keymap: &Rc<XkbKeymap>) {
let state = match keymap.state() {
Ok(s) => s,
Err(e) => {
log::error!("Could not create keymap state: {}", ErrorFmt(e));
return;
}
};
self.kb_map.set(keymap.clone());
*self.kb_state.borrow_mut() = state;
let bindings = self.bindings.borrow_mut();
for (id, client) in bindings.iter() {
for seat in client.values() {

View file

@ -4,7 +4,7 @@ use {
backend::{
Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId,
InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent,
Mode, MonitorInfo, TransformMatrix,
KeyState, Mode, MonitorInfo, TransformMatrix,
},
compositor::TestFuture,
fixed::Fixed,
@ -258,6 +258,29 @@ pub struct TestBackendKb {
pub common: TestInputDeviceCommon,
}
pub struct PressedKey {
pub kb: Rc<TestBackendKb>,
pub key: u32,
}
impl Drop for PressedKey {
fn drop(&mut self) {
self.kb
.common
.event(InputEvent::Key(self.key, KeyState::Released));
}
}
impl TestBackendKb {
pub fn press(self: &Rc<Self>, key: u32) -> PressedKey {
self.common.event(InputEvent::Key(key, KeyState::Pressed));
PressedKey {
kb: self.clone(),
key,
}
}
}
impl TestInputDevice for TestBackendKb {
fn common(&self) -> &TestInputDeviceCommon {
&self.common

View file

@ -3,7 +3,7 @@ use {
backend::InputDeviceId,
ifs::wl_seat::SeatId,
it::test_error::{TestError, TestResult},
utils::stack::Stack,
utils::{copyhashmap::CopyHashMap, stack::Stack},
},
isnt::std_1::primitive::IsntConstPtrExt,
jay_config::{
@ -13,6 +13,7 @@ use {
ConfigEntry, VERSION,
},
input::{InputDevice, Seat},
keyboard::{keymap::Keymap, ModifiedKeySym},
Direction,
},
std::{cell::Cell, ops::Deref, ptr, rc::Rc},
@ -36,6 +37,7 @@ where
let tc = Rc::new(TestConfig {
srv: Cell::new(None),
responses: Default::default(),
invoked_shortcuts: Default::default(),
});
let old = CONFIG;
CONFIG = tc.deref();
@ -86,7 +88,10 @@ unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) {
ServerMessage::Response { response } => {
tc.responses.push(response);
}
ServerMessage::InvokeShortcut { .. } => {}
ServerMessage::InvokeShortcut { seat, mods, sym } => {
tc.invoked_shortcuts
.set((SeatId::from_raw(seat.0 as _), mods | sym), ());
}
ServerMessage::NewInputDevice { .. } => {}
ServerMessage::DelInputDevice { .. } => {}
ServerMessage::ConnectorConnect { .. } => {}
@ -109,6 +114,7 @@ struct ServerData {
pub struct TestConfig {
srv: Cell<Option<ServerData>>,
responses: Stack<Response>,
pub invoked_shortcuts: CopyHashMap<(SeatId, ModifiedKeySym), ()>,
}
macro_rules! get_response {
@ -167,6 +173,35 @@ impl TestConfig {
})
}
pub fn parse_keymap(&self, keymap: &str) -> Result<Keymap, TestError> {
let reply = self.send_with_reply(ClientMessage::ParseKeymap { keymap })?;
get_response!(reply, ParseKeymap { keymap });
if keymap.is_invalid() {
bail!("Could not parse the keymap");
}
Ok(keymap)
}
pub fn set_keymap(&self, seat: SeatId, keymap: Keymap) -> TestResult {
self.send(ClientMessage::SeatSetKeymap {
seat: Seat(seat.raw() as _),
keymap,
})
}
pub fn add_shortcut<T: Into<ModifiedKeySym>>(
&self,
seat: SeatId,
key: T,
) -> Result<(), TestError> {
let key = key.into();
self.send(ClientMessage::AddShortcut {
seat: Seat(seat.raw() as _),
mods: key.mods,
sym: key.sym,
})
}
pub fn set_input_device_seat(&self, id: InputDeviceId, seat: SeatId) -> Result<(), TestError> {
self.send(ClientMessage::SetSeat {
device: InputDevice(id.raw() as _),

View file

@ -125,6 +125,10 @@ impl TestRun {
seat,
})
}
pub async fn sync(&self) {
self.state.eng.yield_now().await;
}
}
pub trait ParseFull<'a>: Sized {

View file

@ -19,7 +19,7 @@ macro_rules! testcase {
fn run(
&self,
testrun: std::rc::Rc<crate::it::testrun::TestRun>,
) -> Box<dyn std::future::Future<Output = Result<(), TestError>>> {
) -> Box<dyn std::future::Future<Output = crate::it::test_error::TestResult>> {
Box::new(test(testrun))
}
}
@ -36,6 +36,7 @@ mod t0007_subsurface;
mod t0008_map_focus;
mod t0009_tab_focus;
mod t0010_fullscreen_focus;
mod t0011_set_keymap;
pub trait TestCase: Sync {
fn name(&self) -> &'static str;
@ -64,5 +65,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
t0008_map_focus,
t0009_tab_focus,
t0010_fullscreen_focus,
t0011_set_keymap,
}
}

View file

@ -0,0 +1,46 @@
use {
crate::it::{test_error::TestResult, testrun::TestRun},
jay_config::keyboard::syms::SYM_F13,
std::rc::Rc,
};
testcase!();
async fn test(run: Rc<TestRun>) -> TestResult {
let ds = run.create_default_setup().await?;
run.cfg.add_shortcut(ds.seat.id(), SYM_F13)?;
run.sync().await;
ds.kb.press(1);
run.sync().await;
tassert!(run.cfg.invoked_shortcuts.is_empty());
let keymap = r#"
xkb_keymap {
xkb_keycodes {
<1> = 9; # ESC
};
xkb_types {
};
xkb_compatibility {
};
xkb_symbols {
key <1> { [ F13 ] };
};
};
"#;
let keymap = run.cfg.parse_keymap(keymap)?;
run.cfg.set_keymap(ds.seat.id(), keymap)?;
run.sync().await;
ds.kb.press(1);
run.sync().await;
tassert!(run
.cfg
.invoked_shortcuts
.contains(&(ds.seat.id(), SYM_F13.into())));
Ok(())
}