it: test foreign-toplevel-list
This commit is contained in:
parent
6fe6b1b491
commit
a39031d4f9
12 changed files with 276 additions and 18 deletions
|
|
@ -2,6 +2,8 @@ mod test_buffer;
|
|||
pub mod test_callback;
|
||||
pub mod test_compositor;
|
||||
pub mod test_display;
|
||||
pub mod test_ext_foreign_toplevel_handle;
|
||||
pub mod test_ext_foreign_toplevel_list;
|
||||
pub mod test_jay_compositor;
|
||||
pub mod test_keyboard;
|
||||
pub mod test_pointer;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
client::MIN_SERVER_ID,
|
||||
it::{
|
||||
test_error::TestError, test_object::TestObject, test_transport::TestTransport,
|
||||
testrun::ParseFull,
|
||||
|
|
@ -36,7 +37,9 @@ impl TestDisplay {
|
|||
}
|
||||
Some(obj) => {
|
||||
obj.on_remove(&self.tran);
|
||||
self.tran.obj_ids.borrow_mut().release(ev.id);
|
||||
if ev.id < MIN_SERVER_ID {
|
||||
self.tran.obj_ids.borrow_mut().release(ev.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
74
src/it/test_ifs/test_ext_foreign_toplevel_handle.rs
Normal file
74
src/it/test_ifs/test_ext_foreign_toplevel_handle.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::{TestError, TestResult},
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
testrun::ParseFull,
|
||||
},
|
||||
utils::buffd::MsgParser,
|
||||
wire::{ext_foreign_toplevel_handle_v1::*, ExtForeignToplevelHandleV1Id},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct TestExtForeignToplevelHandle {
|
||||
pub id: ExtForeignToplevelHandleV1Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
pub destroyed: Cell<bool>,
|
||||
pub closed: Cell<bool>,
|
||||
pub title: Cell<Option<String>>,
|
||||
pub app_id: Cell<Option<String>>,
|
||||
pub identifier: Cell<Option<String>>,
|
||||
}
|
||||
|
||||
impl TestExtForeignToplevelHandle {
|
||||
fn destroy(&self) -> TestResult {
|
||||
if !self.destroyed.replace(true) {
|
||||
self.tran.send(Destroy { self_id: self.id })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_closed(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let _ev = Closed::parse_full(parser)?;
|
||||
self.closed.set(true);
|
||||
self.destroy()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_done(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let _ev = Done::parse_full(parser)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_title(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Title::parse_full(parser)?;
|
||||
self.title.set(Some(ev.title.to_string()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_app_id(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = AppId::parse_full(parser)?;
|
||||
self.app_id.set(Some(ev.app_id.to_string()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_identifier(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Identifier::parse_full(parser)?;
|
||||
self.identifier.set(Some(ev.identifier.to_string()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestExtForeignToplevelHandle, ExtForeignToplevelHandleV1;
|
||||
|
||||
CLOSED => handle_closed,
|
||||
DONE => handle_done,
|
||||
TITLE => handle_title,
|
||||
APP_ID => handle_app_id,
|
||||
IDENTIFIER => handle_identifier,
|
||||
}
|
||||
|
||||
impl TestObject for TestExtForeignToplevelHandle {}
|
||||
70
src/it/test_ifs/test_ext_foreign_toplevel_list.rs
Normal file
70
src/it/test_ifs/test_ext_foreign_toplevel_list.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::{TestError, TestResult},
|
||||
test_ifs::test_ext_foreign_toplevel_handle::TestExtForeignToplevelHandle,
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
testrun::ParseFull,
|
||||
},
|
||||
utils::buffd::MsgParser,
|
||||
wire::{ext_foreign_toplevel_list_v1::*, ExtForeignToplevelListV1Id},
|
||||
},
|
||||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
rc::Rc,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct TestExtForeignToplevelList {
|
||||
pub id: ExtForeignToplevelListV1Id,
|
||||
pub tran: Rc<TestTransport>,
|
||||
pub destroyed: Cell<bool>,
|
||||
pub toplevels: RefCell<Vec<Rc<TestExtForeignToplevelHandle>>>,
|
||||
}
|
||||
|
||||
impl TestExtForeignToplevelList {
|
||||
#[allow(dead_code)]
|
||||
pub fn stop(&self) -> TestResult {
|
||||
self.tran.send(Stop { self_id: self.id })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn destroy(&self) -> TestResult {
|
||||
if !self.destroyed.replace(true) {
|
||||
self.tran.send(Destroy { self_id: self.id })?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_toplevel(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Toplevel::parse_full(parser)?;
|
||||
let tl = Rc::new(TestExtForeignToplevelHandle {
|
||||
id: ev.toplevel,
|
||||
tran: self.tran.clone(),
|
||||
destroyed: Cell::new(false),
|
||||
closed: Cell::new(false),
|
||||
title: Cell::new(None),
|
||||
app_id: Cell::new(None),
|
||||
identifier: Cell::new(None),
|
||||
});
|
||||
self.tran.add_obj(tl.clone())?;
|
||||
self.toplevels.borrow_mut().push(tl);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_finished(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let _ev = Finished::parse_full(parser)?;
|
||||
self.destroy()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
test_object! {
|
||||
TestExtForeignToplevelList, ExtForeignToplevelListV1;
|
||||
|
||||
TOPLEVEL => handle_toplevel,
|
||||
FINISHED => handle_finished,
|
||||
}
|
||||
|
||||
impl TestObject for TestExtForeignToplevelList {}
|
||||
|
|
@ -2,8 +2,11 @@ use {
|
|||
crate::{
|
||||
client::ClientId,
|
||||
it::{
|
||||
test_error::TestError, test_ifs::test_screenshot::TestJayScreenshot,
|
||||
test_object::TestObject, test_transport::TestTransport, testrun::ParseFull,
|
||||
test_error::{TestError, TestResult},
|
||||
test_ifs::test_screenshot::TestJayScreenshot,
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
testrun::ParseFull,
|
||||
},
|
||||
utils::{buffd::MsgParser, cell_ext::CellExt},
|
||||
wire::{
|
||||
|
|
@ -33,6 +36,11 @@ impl TestJayCompositor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn enable_symmetric_delete(&self) -> TestResult {
|
||||
self.tran.send(EnableSymmetricDelete { self_id: self.id })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn take_screenshot(&self, include_cursor: bool) -> Result<Dmabuf, TestError> {
|
||||
let js = Rc::new(TestJayScreenshot {
|
||||
id: self.tran.id(),
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ use {
|
|||
it::{
|
||||
test_error::TestError,
|
||||
test_ifs::{
|
||||
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
||||
test_shm::TestShm, test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
||||
test_compositor::TestCompositor,
|
||||
test_ext_foreign_toplevel_list::TestExtForeignToplevelList,
|
||||
test_jay_compositor::TestJayCompositor, test_shm::TestShm,
|
||||
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
||||
test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter,
|
||||
test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase,
|
||||
},
|
||||
|
|
@ -17,7 +19,10 @@ use {
|
|||
utils::{buffd::MsgParser, clonecell::CloneCell, copyhashmap::CopyHashMap},
|
||||
wire::{wl_registry::*, WlRegistryId, WlSeat},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
rc::Rc,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct TestGlobal {
|
||||
|
|
@ -35,6 +40,7 @@ pub struct TestRegistrySingletons {
|
|||
pub wp_single_pixel_buffer_manager_v1: u32,
|
||||
pub wp_viewporter: u32,
|
||||
pub xdg_activation_v1: u32,
|
||||
pub ext_foreign_toplevel_list_v1: u32,
|
||||
}
|
||||
|
||||
pub struct TestRegistry {
|
||||
|
|
@ -50,6 +56,7 @@ pub struct TestRegistry {
|
|||
pub viewporter: CloneCell<Option<Rc<TestViewporter>>>,
|
||||
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
||||
pub activation: CloneCell<Option<Rc<TestXdgActivation>>>,
|
||||
pub foreign_toplevel_list: CloneCell<Option<Rc<TestExtForeignToplevelList>>>,
|
||||
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +107,7 @@ impl TestRegistry {
|
|||
wp_single_pixel_buffer_manager_v1,
|
||||
wp_viewporter,
|
||||
xdg_activation_v1,
|
||||
ext_foreign_toplevel_list_v1,
|
||||
};
|
||||
self.singletons.set(Some(singletons.clone()));
|
||||
Ok(singletons)
|
||||
|
|
@ -215,6 +223,23 @@ impl TestRegistry {
|
|||
Ok(jc)
|
||||
}
|
||||
|
||||
pub async fn get_foreign_toplevel_list(
|
||||
&self,
|
||||
) -> Result<Rc<TestExtForeignToplevelList>, TestError> {
|
||||
singleton!(self.foreign_toplevel_list);
|
||||
let singletons = self.get_singletons().await?;
|
||||
singleton!(self.foreign_toplevel_list);
|
||||
let jc = Rc::new(TestExtForeignToplevelList {
|
||||
id: self.tran.id(),
|
||||
tran: self.tran.clone(),
|
||||
destroyed: Cell::new(false),
|
||||
toplevels: RefCell::new(vec![]),
|
||||
});
|
||||
self.bind(&jc, singletons.ext_foreign_toplevel_list_v1, 1)?;
|
||||
self.foreign_toplevel_list.set(Some(jc.clone()));
|
||||
Ok(jc)
|
||||
}
|
||||
|
||||
pub fn bind<O: TestObject>(
|
||||
&self,
|
||||
obj: &Rc<O>,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,14 @@ impl TestXdgToplevelCore {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_title(&self, title: &str) -> Result<(), TestError> {
|
||||
self.tran.send(SetTitle {
|
||||
self_id: self.id,
|
||||
title,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Configure::parse_full(parser)?;
|
||||
self.width.set(ev.width);
|
||||
|
|
|
|||
|
|
@ -13,18 +13,20 @@ macro_rules! tassert {
|
|||
|
||||
macro_rules! tassert_eq {
|
||||
($left:expr, $right:expr) => {{
|
||||
let left = $left;
|
||||
let right = $right;
|
||||
if left != right {
|
||||
bail!(
|
||||
"Assert `{} = {:?} = {:?} = {}` failed ({}:{})",
|
||||
stringify!($left),
|
||||
left,
|
||||
right,
|
||||
stringify!($right),
|
||||
file!(),
|
||||
line!()
|
||||
);
|
||||
match ($left, $right) {
|
||||
(left, right) => {
|
||||
if left != right {
|
||||
bail!(
|
||||
"Assert `{} = {:?} = {:?} = {}` failed ({}:{})",
|
||||
stringify!($left),
|
||||
left,
|
||||
right,
|
||||
stringify!($right),
|
||||
file!(),
|
||||
line!()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ impl TestTransport {
|
|||
viewporter: Default::default(),
|
||||
xdg: Default::default(),
|
||||
activation: Default::default(),
|
||||
foreign_toplevel_list: Default::default(),
|
||||
seats: Default::default(),
|
||||
});
|
||||
self.send(wl_display::GetRegistry {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ impl TestRun {
|
|||
tran.init();
|
||||
let registry = tran.get_registry();
|
||||
let jc = registry.get_jay_compositor().await?;
|
||||
jc.enable_symmetric_delete()?;
|
||||
let client_id = jc.get_client_id().await?;
|
||||
let client = self.state.clients.get(client_id)?;
|
||||
Ok(Rc::new(TestClient {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ mod t0020_surface_offset;
|
|||
mod t0021_preferred_buffer_scale;
|
||||
mod t0022_toplevel_suspended;
|
||||
mod t0023_xdg_activation;
|
||||
mod t0024_foreign_toplevel_list;
|
||||
|
||||
pub trait TestCase: Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
|
|
@ -96,5 +97,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
|||
t0021_preferred_buffer_scale,
|
||||
t0022_toplevel_suspended,
|
||||
t0023_xdg_activation,
|
||||
t0024_foreign_toplevel_list,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
62
src/it/tests/t0024_foreign_toplevel_list.rs
Normal file
62
src/it/tests/t0024_foreign_toplevel_list.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{test_error::TestResult, testrun::TestRun},
|
||||
wire::WlBufferId,
|
||||
},
|
||||
ahash::AHashSet,
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
testcase!();
|
||||
|
||||
async fn test(run: Rc<TestRun>) -> TestResult {
|
||||
let _ds = run.create_default_setup().await?;
|
||||
|
||||
let client1 = run.create_client().await?;
|
||||
let client2 = run.create_client().await?;
|
||||
|
||||
let list = client2.registry.get_foreign_toplevel_list().await?;
|
||||
|
||||
let win1 = client1.create_window().await?;
|
||||
win1.tl.core.set_title("a")?;
|
||||
win1.map().await?;
|
||||
let win2 = client1.create_window().await?;
|
||||
win2.tl.core.set_title("b")?;
|
||||
win2.map().await?;
|
||||
|
||||
client2.sync().await;
|
||||
let tls = list.toplevels.take();
|
||||
tassert_eq!(tls.len(), 2);
|
||||
|
||||
tassert_eq!(tls[0].title.take().as_deref(), Some("a"));
|
||||
tassert_eq!(tls[1].title.take().as_deref(), Some("b"));
|
||||
|
||||
let mut ids = AHashSet::new();
|
||||
ids.insert(tls[0].identifier.take().unwrap());
|
||||
ids.insert(tls[1].identifier.take().unwrap());
|
||||
|
||||
win2.tl.core.set_title("c")?;
|
||||
client1.sync().await;
|
||||
|
||||
client2.sync().await;
|
||||
tassert_eq!(tls[1].title.take().as_deref(), Some("c"));
|
||||
|
||||
win2.surface.attach(WlBufferId::NONE)?;
|
||||
win2.surface.commit()?;
|
||||
client1.sync().await;
|
||||
|
||||
client2.sync().await;
|
||||
tassert!(tls[1].closed.get());
|
||||
|
||||
win2.map().await?;
|
||||
|
||||
client1.sync().await;
|
||||
let tls = list.toplevels.take();
|
||||
tassert_eq!(tls.len(), 1);
|
||||
tassert_eq!(tls[0].title.take().as_deref(), Some("c"));
|
||||
|
||||
ids.insert(tls[0].identifier.take().unwrap());
|
||||
tassert_eq!(ids.len(), 3);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue