seat: update xkb_state when keymap changes
This commit is contained in:
parent
a80c5690c8
commit
76c47c24d0
7 changed files with 123 additions and 5 deletions
|
|
@ -8,7 +8,7 @@ pub mod keymap;
|
|||
pub mod mods;
|
||||
pub mod syms;
|
||||
|
||||
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Hash, Debug)]
|
||||
pub struct ModifiedKeySym {
|
||||
pub mods: Modifiers,
|
||||
pub sym: KeySym,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 _),
|
||||
|
|
|
|||
|
|
@ -125,6 +125,10 @@ impl TestRun {
|
|||
seat,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn sync(&self) {
|
||||
self.state.eng.yield_now().await;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ParseFull<'a>: Sized {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
46
src/it/tests/t0011_set_keymap.rs
Normal file
46
src/it/tests/t0011_set_keymap.rs
Normal 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(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue