seat: implement input methods
This commit is contained in:
parent
5e2cdef388
commit
daf52299db
44 changed files with 2165 additions and 75 deletions
119
src/it/test_ifs/test_input_method.rs
Normal file
119
src/it/test_ifs/test_input_method.rs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::{TestError, TestResult},
|
||||
test_ifs::{
|
||||
test_input_method_keyboard_grab::TestInputMethodKeyboardGrab,
|
||||
test_input_popup_surface::TestInputPopupSurface, test_surface::TestSurface,
|
||||
},
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
test_utils::test_expected_event::TEEH,
|
||||
testrun::ParseFull,
|
||||
},
|
||||
utils::{buffd::MsgParser, numcell::NumCell},
|
||||
wire::{zwp_input_method_v2::*, ZwpInputMethodV2Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestInputMethod {
|
||||
pub id: ZwpInputMethodV2Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
pub destroyed: Cell<bool>,
|
||||
pub activate: TEEH<bool>,
|
||||
pub done: TEEH<()>,
|
||||
pub done_received: NumCell<u32>,
|
||||
}
|
||||
|
||||
impl TestInputMethod {
|
||||
pub fn commit_string(&self, s: &str) -> TestResult {
|
||||
self.tran.send(CommitString {
|
||||
self_id: self.id,
|
||||
text: s,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn commit(&self) -> TestResult {
|
||||
self.tran.send(Commit {
|
||||
self_id: self.id,
|
||||
serial: self.done_received.get(),
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn grab(&self) -> TestResult<Rc<TestInputMethodKeyboardGrab>> {
|
||||
let obj = Rc::new(TestInputMethodKeyboardGrab {
|
||||
id: self.tran.id(),
|
||||
tran: self.tran.clone(),
|
||||
destroyed: Cell::new(false),
|
||||
keymap: Rc::new(Default::default()),
|
||||
key: Rc::new(Default::default()),
|
||||
modifiers: Rc::new(Default::default()),
|
||||
repeat_info: Rc::new(Default::default()),
|
||||
});
|
||||
self.tran.add_obj(obj.clone())?;
|
||||
self.tran.send(GrabKeyboard {
|
||||
self_id: self.id,
|
||||
keyboard: obj.id,
|
||||
})?;
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
pub fn get_popup(&self, surface: &TestSurface) -> TestResult<Rc<TestInputPopupSurface>> {
|
||||
let obj = Rc::new(TestInputPopupSurface {
|
||||
id: self.tran.id(),
|
||||
tran: self.tran.clone(),
|
||||
destroyed: Cell::new(false),
|
||||
});
|
||||
self.tran.add_obj(obj.clone())?;
|
||||
self.tran.send(GetInputPopupSurface {
|
||||
self_id: self.id,
|
||||
id: obj.id,
|
||||
surface: surface.id,
|
||||
})?;
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
pub fn destroy(&self) -> Result<(), TestError> {
|
||||
if !self.destroyed.replace(true) {
|
||||
self.tran.send(Destroy { self_id: self.id })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_activate(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let _ev = Activate::parse_full(parser)?;
|
||||
self.activate.push(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_deactivate(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let _ev = Deactivate::parse_full(parser)?;
|
||||
self.activate.push(false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_done(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let _ev = Done::parse_full(parser)?;
|
||||
self.done.push(());
|
||||
self.done_received.fetch_add(1);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestInputMethod {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestInputMethod, ZwpInputMethodV2;
|
||||
|
||||
ACTIVATE => handle_activate,
|
||||
DEACTIVATE => handle_deactivate,
|
||||
DONE => handle_done,
|
||||
}
|
||||
|
||||
impl TestObject for TestInputMethod {}
|
||||
71
src/it/test_ifs/test_input_method_keyboard_grab.rs
Normal file
71
src/it/test_ifs/test_input_method_keyboard_grab.rs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::TestError, test_object::TestObject, test_transport::TestTransport,
|
||||
test_utils::test_expected_event::TEEH, testrun::ParseFull,
|
||||
},
|
||||
utils::buffd::MsgParser,
|
||||
wire::{zwp_input_method_keyboard_grab_v2::*, ZwpInputMethodKeyboardGrabV2Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestInputMethodKeyboardGrab {
|
||||
pub id: ZwpInputMethodKeyboardGrabV2Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
pub destroyed: Cell<bool>,
|
||||
pub keymap: TEEH<Keymap>,
|
||||
pub key: TEEH<Key>,
|
||||
pub modifiers: TEEH<Modifiers>,
|
||||
pub repeat_info: TEEH<RepeatInfo>,
|
||||
}
|
||||
|
||||
impl TestInputMethodKeyboardGrab {
|
||||
pub fn destroy(&self) -> Result<(), TestError> {
|
||||
if !self.destroyed.replace(true) {
|
||||
self.tran.send(Release { self_id: self.id })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_keymap(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Keymap::parse_full(parser)?;
|
||||
self.keymap.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_key(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Key::parse_full(parser)?;
|
||||
self.key.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_modifiers(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Modifiers::parse_full(parser)?;
|
||||
self.modifiers.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_repeat_info(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = RepeatInfo::parse_full(parser)?;
|
||||
self.repeat_info.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestInputMethodKeyboardGrab {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestInputMethodKeyboardGrab, ZwpInputMethodKeyboardGrabV2;
|
||||
|
||||
KEYMAP => handle_keymap,
|
||||
KEY => handle_key,
|
||||
MODIFIERS => handle_modifiers,
|
||||
REPEAT_INFO => handle_repeat_info,
|
||||
}
|
||||
|
||||
impl TestObject for TestInputMethodKeyboardGrab {}
|
||||
50
src/it/test_ifs/test_input_method_manager.rs
Normal file
50
src/it/test_ifs/test_input_method_manager.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::TestResult,
|
||||
test_ifs::{test_input_method::TestInputMethod, test_seat::TestSeat},
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
},
|
||||
wire::{zwp_input_method_manager_v2::GetInputMethod, ZwpInputMethodManagerV2Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestInputMethodManager {
|
||||
pub id: ZwpInputMethodManagerV2Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
}
|
||||
|
||||
impl TestInputMethodManager {
|
||||
pub fn new(tran: &Rc<TestTransport>) -> Self {
|
||||
Self {
|
||||
id: tran.id(),
|
||||
tran: tran.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_input_method(&self, seat: &TestSeat) -> TestResult<Rc<TestInputMethod>> {
|
||||
let obj = Rc::new(TestInputMethod {
|
||||
id: self.tran.id(),
|
||||
tran: self.tran.clone(),
|
||||
destroyed: Cell::new(false),
|
||||
activate: Rc::new(Default::default()),
|
||||
done: Rc::new(Default::default()),
|
||||
done_received: Default::default(),
|
||||
});
|
||||
self.tran.add_obj(obj.clone())?;
|
||||
self.tran.send(GetInputMethod {
|
||||
self_id: self.id,
|
||||
seat: seat.id,
|
||||
input_method: obj.id,
|
||||
})?;
|
||||
Ok(obj)
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestInputMethodManager, ZwpInputMethodManagerV2;
|
||||
}
|
||||
|
||||
impl TestObject for TestInputMethodManager {}
|
||||
34
src/it/test_ifs/test_input_popup_surface.rs
Normal file
34
src/it/test_ifs/test_input_popup_surface.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{test_error::TestError, test_object::TestObject, test_transport::TestTransport},
|
||||
wire::{zwp_input_popup_surface_v2::*, ZwpInputPopupSurfaceV2Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestInputPopupSurface {
|
||||
pub id: ZwpInputPopupSurfaceV2Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
pub destroyed: Cell<bool>,
|
||||
}
|
||||
|
||||
impl TestInputPopupSurface {
|
||||
pub fn destroy(&self) -> Result<(), TestError> {
|
||||
if !self.destroyed.replace(true) {
|
||||
self.tran.send(Destroy { self_id: self.id })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestInputPopupSurface {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestInputPopupSurface, ZwpInputPopupSurfaceV2;
|
||||
}
|
||||
|
||||
impl TestObject for TestInputPopupSurface {}
|
||||
|
|
@ -11,9 +11,11 @@ use {
|
|||
test_data_control_manager::TestDataControlManager,
|
||||
test_data_device_manager::TestDataDeviceManager, test_dmabuf::TestDmabuf,
|
||||
test_ext_foreign_toplevel_list::TestExtForeignToplevelList,
|
||||
test_input_method_manager::TestInputMethodManager,
|
||||
test_jay_compositor::TestJayCompositor, test_shm::TestShm,
|
||||
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
||||
test_subcompositor::TestSubcompositor, test_syncobj_manager::TestSyncobjManager,
|
||||
test_text_input_manager::TestTextInputManager,
|
||||
test_toplevel_drag_manager::TestToplevelDragManager,
|
||||
test_viewporter::TestViewporter,
|
||||
test_virtual_keyboard_manager::TestVirtualKeyboardManager,
|
||||
|
|
@ -54,6 +56,8 @@ pub struct TestRegistrySingletons {
|
|||
pub xdg_toplevel_drag_manager_v1: u32,
|
||||
pub wp_alpha_modifier_v1: u32,
|
||||
pub zwp_virtual_keyboard_manager_v1: u32,
|
||||
pub zwp_input_method_manager_v2: u32,
|
||||
pub zwp_text_input_manager_v3: u32,
|
||||
}
|
||||
|
||||
pub struct TestRegistry {
|
||||
|
|
@ -79,6 +83,8 @@ pub struct TestRegistry {
|
|||
pub drag_manager: CloneCell<Option<Rc<TestToplevelDragManager>>>,
|
||||
pub alpha_modifier: CloneCell<Option<Rc<TestAlphaModifier>>>,
|
||||
pub virtual_keyboard_manager: CloneCell<Option<Rc<TestVirtualKeyboardManager>>>,
|
||||
pub input_method_manager: CloneCell<Option<Rc<TestInputMethodManager>>>,
|
||||
pub text_input_manager: CloneCell<Option<Rc<TestTextInputManager>>>,
|
||||
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
||||
}
|
||||
|
||||
|
|
@ -148,6 +154,8 @@ impl TestRegistry {
|
|||
xdg_toplevel_drag_manager_v1,
|
||||
wp_alpha_modifier_v1,
|
||||
zwp_virtual_keyboard_manager_v1,
|
||||
zwp_input_method_manager_v2,
|
||||
zwp_text_input_manager_v3,
|
||||
};
|
||||
self.singletons.set(Some(singletons.clone()));
|
||||
Ok(singletons)
|
||||
|
|
@ -249,6 +257,20 @@ impl TestRegistry {
|
|||
1,
|
||||
TestVirtualKeyboardManager
|
||||
);
|
||||
create_singleton!(
|
||||
get_input_method_manager,
|
||||
input_method_manager,
|
||||
zwp_input_method_manager_v2,
|
||||
1,
|
||||
TestInputMethodManager
|
||||
);
|
||||
create_singleton!(
|
||||
get_text_input_manager,
|
||||
text_input_manager,
|
||||
zwp_text_input_manager_v3,
|
||||
1,
|
||||
TestTextInputManager
|
||||
);
|
||||
|
||||
pub fn bind<O: TestObject>(
|
||||
&self,
|
||||
|
|
|
|||
97
src/it/test_ifs/test_text_input.rs
Normal file
97
src/it/test_ifs/test_text_input.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::{TestError, TestResult},
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
test_utils::test_expected_event::TEEH,
|
||||
testrun::ParseFull,
|
||||
},
|
||||
utils::buffd::MsgParser,
|
||||
wire::{zwp_text_input_v3::*, ZwpTextInputV3Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestTextInput {
|
||||
pub id: ZwpTextInputV3Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
pub destroyed: Cell<bool>,
|
||||
pub enter: TEEH<Enter>,
|
||||
pub leave: TEEH<Leave>,
|
||||
pub commit_string: TEEH<String>,
|
||||
pub done: TEEH<Done>,
|
||||
}
|
||||
|
||||
impl TestTextInput {
|
||||
pub fn destroy(&self) -> Result<(), TestError> {
|
||||
if !self.destroyed.replace(true) {
|
||||
self.tran.send(Destroy { self_id: self.id })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn enable(&self) -> TestResult {
|
||||
self.tran.send(Enable { self_id: self.id })
|
||||
}
|
||||
|
||||
pub fn disable(&self) -> TestResult {
|
||||
self.tran.send(Disable { self_id: self.id })
|
||||
}
|
||||
|
||||
pub fn set_cursor_rectangle(&self, x: i32, y: i32, width: i32, height: i32) -> TestResult {
|
||||
self.tran.send(SetCursorRectangle {
|
||||
self_id: self.id,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn commit(&self) -> TestResult {
|
||||
self.tran.send(Commit { self_id: self.id })
|
||||
}
|
||||
|
||||
fn handle_enter(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Enter::parse_full(parser)?;
|
||||
self.enter.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_leave(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Leave::parse_full(parser)?;
|
||||
self.leave.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_commit_string(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = CommitString::parse_full(parser)?;
|
||||
self.commit_string
|
||||
.push(ev.text.unwrap_or_default().to_string());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_done(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Done::parse_full(parser)?;
|
||||
self.done.push(ev);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestTextInput {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestTextInput, ZwpTextInputV3;
|
||||
|
||||
ENTER => handle_enter,
|
||||
LEAVE => handle_leave,
|
||||
COMMIT_STRING => handle_commit_string,
|
||||
DONE => handle_done,
|
||||
}
|
||||
|
||||
impl TestObject for TestTextInput {}
|
||||
51
src/it/test_ifs/test_text_input_manager.rs
Normal file
51
src/it/test_ifs/test_text_input_manager.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::TestResult,
|
||||
test_ifs::{test_seat::TestSeat, test_text_input::TestTextInput},
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
},
|
||||
wire::{zwp_text_input_manager_v3::*, ZwpTextInputManagerV3Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestTextInputManager {
|
||||
pub id: ZwpTextInputManagerV3Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
}
|
||||
|
||||
impl TestTextInputManager {
|
||||
pub fn new(tran: &Rc<TestTransport>) -> Self {
|
||||
Self {
|
||||
id: tran.id(),
|
||||
tran: tran.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_text_input(&self, seat: &TestSeat) -> TestResult<Rc<TestTextInput>> {
|
||||
let obj = Rc::new(TestTextInput {
|
||||
id: self.tran.id(),
|
||||
tran: self.tran.clone(),
|
||||
destroyed: Cell::new(false),
|
||||
enter: Rc::new(Default::default()),
|
||||
leave: Rc::new(Default::default()),
|
||||
commit_string: Rc::new(Default::default()),
|
||||
done: Rc::new(Default::default()),
|
||||
});
|
||||
self.tran.add_obj(obj.clone())?;
|
||||
self.tran.send(GetTextInput {
|
||||
self_id: self.id,
|
||||
id: obj.id,
|
||||
seat: seat.id,
|
||||
})?;
|
||||
Ok(obj)
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestTextInputManager, ZwpTextInputManagerV3;
|
||||
}
|
||||
|
||||
impl TestObject for TestTextInputManager {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue