1
0
Fork 0
forked from wry/wry

it: test xdg-activation

This commit is contained in:
Julian Orth 2024-04-02 15:03:24 +02:00
parent 91022cd1c8
commit 6fe6b1b491
16 changed files with 239 additions and 23 deletions

View file

@ -11,7 +11,7 @@ use {
test_registry::TestRegistry, test_seat::TestSeat, test_shm::TestShm,
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter,
test_xdg_base::TestXdgWmBase,
test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase,
},
test_transport::TestTransport,
test_utils::test_window::TestWindow,
@ -34,6 +34,7 @@ pub struct TestClient {
pub spbm: Rc<TestSinglePixelBufferManager>,
pub viewporter: Rc<TestViewporter>,
pub xdg: Rc<TestXdgWmBase>,
pub activation: Rc<TestXdgActivation>,
}
pub struct DefaultSeat {
@ -86,22 +87,26 @@ impl TestClient {
self.tran.sync().await;
}
pub async fn take_screenshot(&self) -> Result<Vec<u8>, TestError> {
let dmabuf = self.jc.take_screenshot().await?;
pub async fn take_screenshot(&self, include_cursor: bool) -> Result<Vec<u8>, TestError> {
let dmabuf = self.jc.take_screenshot(include_cursor).await?;
let qoi = buf_to_qoi(&self.server.state.dma_buf_ids, &dmabuf);
Ok(qoi)
}
#[allow(dead_code)]
pub async fn save_screenshot(&self, name: &str) -> Result<(), TestError> {
let qoi = self.take_screenshot().await?;
pub async fn save_screenshot(&self, name: &str, include_cursor: bool) -> Result<(), TestError> {
let qoi = self.take_screenshot(include_cursor).await?;
let path = format!("{}/screenshot_{}.qoi", self.run.out_dir, name);
std::fs::write(path, qoi)?;
Ok(())
}
pub async fn compare_screenshot(&self, name: &str) -> Result<(), TestError> {
let actual = self.take_screenshot().await?;
pub async fn compare_screenshot(
&self,
name: &str,
include_cursor: bool,
) -> Result<(), TestError> {
let actual = self.take_screenshot(include_cursor).await?;
let expected_path = format!("{}/screenshot_{}.qoi", self.run.in_dir, name);
let expected = std::fs::read(expected_path)?;
if actual != expected {

View file

@ -18,6 +18,8 @@ pub mod test_subsurface;
pub mod test_surface;
pub mod test_viewport;
pub mod test_viewporter;
pub mod test_xdg_activation;
pub mod test_xdg_activation_token;
pub mod test_xdg_base;
pub mod test_xdg_surface;
pub mod test_xdg_toplevel;

View file

@ -33,14 +33,15 @@ impl TestJayCompositor {
}
}
pub async fn take_screenshot(&self) -> Result<Dmabuf, TestError> {
pub async fn take_screenshot(&self, include_cursor: bool) -> Result<Dmabuf, TestError> {
let js = Rc::new(TestJayScreenshot {
id: self.tran.id(),
result: Cell::new(None),
});
self.tran.send(TakeScreenshot {
self.tran.send(TakeScreenshot2 {
self_id: self.id,
id: js.id,
include_cursor: include_cursor as _,
})?;
self.tran.add_obj(js.clone())?;
self.tran.sync().await;

View file

@ -8,7 +8,7 @@ use {
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
test_shm::TestShm, test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter,
test_xdg_base::TestXdgWmBase,
test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase,
},
test_object::TestObject,
test_transport::TestTransport,
@ -34,6 +34,7 @@ pub struct TestRegistrySingletons {
pub xdg_wm_base: u32,
pub wp_single_pixel_buffer_manager_v1: u32,
pub wp_viewporter: u32,
pub xdg_activation_v1: u32,
}
pub struct TestRegistry {
@ -48,6 +49,7 @@ pub struct TestRegistry {
pub spbm: CloneCell<Option<Rc<TestSinglePixelBufferManager>>>,
pub viewporter: CloneCell<Option<Rc<TestViewporter>>>,
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
pub activation: CloneCell<Option<Rc<TestXdgActivation>>>,
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
}
@ -97,6 +99,7 @@ impl TestRegistry {
xdg_wm_base,
wp_single_pixel_buffer_manager_v1,
wp_viewporter,
xdg_activation_v1,
};
self.singletons.set(Some(singletons.clone()));
Ok(singletons)
@ -184,6 +187,20 @@ impl TestRegistry {
Ok(jc)
}
pub async fn get_activation(&self) -> Result<Rc<TestXdgActivation>, TestError> {
singleton!(self.activation);
let singletons = self.get_singletons().await?;
singleton!(self.activation);
let jc = Rc::new(TestXdgActivation {
id: self.tran.id(),
tran: self.tran.clone(),
destroyed: Cell::new(false),
});
self.bind(&jc, singletons.xdg_activation_v1, 1)?;
self.activation.set(Some(jc.clone()));
Ok(jc)
}
pub async fn get_xdg(&self) -> Result<Rc<TestXdgWmBase>, TestError> {
singleton!(self.xdg);
let singletons = self.get_singletons().await?;

View file

@ -0,0 +1,66 @@
use {
crate::{
it::{
test_error::{TestError, TestResult},
test_ifs::{
test_surface::TestSurface, test_xdg_activation_token::TestXdgActivationToken,
},
test_object::TestObject,
test_transport::TestTransport,
},
wire::{xdg_activation_v1::*, XdgActivationV1Id},
},
std::{cell::Cell, rc::Rc},
};
pub struct TestXdgActivation {
pub id: XdgActivationV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
}
impl TestXdgActivation {
pub fn destroy(&self) -> Result<(), TestError> {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub async fn get_token(&self) -> Result<String, TestError> {
let token = Rc::new(TestXdgActivationToken {
id: self.tran.id(),
tran: self.tran.clone(),
destroyed: Cell::new(false),
token: Cell::new(None),
});
self.tran.add_obj(token.clone())?;
self.tran.send(GetActivationToken {
self_id: self.id,
id: token.id,
})?;
let res = token.commit().await?;
token.destroy()?;
Ok(res)
}
pub fn activate(&self, tl: &TestSurface, token: &str) -> TestResult {
self.tran.send(Activate {
self_id: self.id,
token,
surface: tl.id,
})
}
}
test_object! {
TestXdgActivation, XdgActivationV1;
}
impl TestObject for TestXdgActivation {}
impl Drop for TestXdgActivation {
fn drop(&mut self) {
let _ = self.destroy();
}
}

View file

@ -0,0 +1,56 @@
use {
crate::{
it::{
test_error::TestError, test_object::TestObject, test_transport::TestTransport,
testrun::ParseFull,
},
utils::buffd::MsgParser,
wire::{xdg_activation_token_v1::*, XdgActivationTokenV1Id},
},
std::{cell::Cell, rc::Rc},
};
pub struct TestXdgActivationToken {
pub id: XdgActivationTokenV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
pub token: Cell<Option<String>>,
}
impl TestXdgActivationToken {
pub fn destroy(&self) -> Result<(), TestError> {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub async fn commit(&self) -> Result<String, TestError> {
self.tran.send(Commit { self_id: self.id })?;
self.tran.sync().await;
match self.token.take() {
Some(t) => Ok(t),
_ => bail!("Server did not send a token"),
}
}
fn handle_done(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = Done::parse_full(parser)?;
self.token.set(Some(ev.token.to_string()));
Ok(())
}
}
test_object! {
TestXdgActivationToken, XdgActivationTokenV1;
DONE => handle_done,
}
impl TestObject for TestXdgActivationToken {}
impl Drop for TestXdgActivationToken {
fn drop(&mut self) {
let _ = self.destroy();
}
}

View file

@ -59,6 +59,7 @@ impl TestTransport {
spbm: Default::default(),
viewporter: Default::default(),
xdg: Default::default(),
activation: Default::default(),
seats: Default::default(),
});
self.send(wl_display::GetRegistry {
@ -161,7 +162,12 @@ impl TestTransport {
_ => bail!("Object with id {} has already been deleted", msg.id()),
};
if obj.interface().name() != msg.interface().name() {
bail!("Object with id {} has an incompatible interface", msg.id());
bail!(
"Object with id {} has an incompatible interface: {} != {}",
msg.id(),
obj.interface().name(),
msg.interface().name()
);
}
let mut fds = vec![];
let mut swapchain = self.swapchain.borrow_mut();

View file

@ -87,6 +87,7 @@ impl TestRun {
spbm: registry.get_spbm().await?,
viewporter: registry.get_viewporter().await?,
xdg: registry.get_xdg().await?,
activation: registry.get_activation().await?,
registry,
}))
}

View file

@ -53,6 +53,7 @@ mod t0019_natural_scrolling;
mod t0020_surface_offset;
mod t0021_preferred_buffer_scale;
mod t0022_toplevel_suspended;
mod t0023_xdg_activation;
pub trait TestCase: Sync {
fn name(&self) -> &'static str;
@ -94,5 +95,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
t0020_surface_offset,
t0021_preferred_buffer_scale,
t0022_toplevel_suspended,
t0023_xdg_activation,
}
}

View file

@ -43,19 +43,17 @@ async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
parent.map().await?;
seat.set_app_cursor(None);
client.compare_screenshot("1").await?;
client.compare_screenshot("1", false).await?;
sub.place_below(parent.surface.id)?;
child.commit()?;
parent.map().await?;
client.compare_screenshot("2").await?;
client.compare_screenshot("2", false).await?;
sub.place_above(parent.surface.id)?;
child.commit()?;
parent.map().await?;
client.compare_screenshot("1").await?;
client.compare_screenshot("1", false).await?;
Ok(())
}

View file

@ -44,12 +44,12 @@ async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
let enter = enter.next()?;
seat.pointer.set_cursor(enter.serial, &surface, 0, 0)?;
client.compare_screenshot("1").await?;
client.compare_screenshot("1", true).await?;
surface.offset(-100, -100)?;
surface.commit()?;
client.compare_screenshot("2").await?;
client.compare_screenshot("2", true).await?;
Ok(())
}

View file

@ -0,0 +1,40 @@
use {
crate::it::{
test_error::TestResult,
test_utils::{
test_ouput_node_ext::TestOutputNodeExt, test_toplevel_node_ext::TestToplevelNodeExt,
},
testrun::TestRun,
},
std::rc::Rc,
};
testcase!();
async fn test(run: Rc<TestRun>) -> TestResult {
let ds = run.create_default_setup().await?;
let client = run.create_client().await?;
let win1 = client.create_window().await?;
win1.set_color(255, 0, 0, 255);
win1.map2().await?;
let win2 = client.create_window().await?;
win2.set_color(0, 255, 0, 255);
win2.map2().await?;
let (x, y) = ds.output.first_toplevel()?.center();
ds.move_to(x, y);
client.sync().await;
run.cfg.set_mono(ds.seat.id(), true)?;
let token = client.activation.get_token().await?;
client.activation.activate(&win2.surface, &token)?;
client.sync().await;
client.compare_screenshot("1", false).await?;
Ok(())
}

Binary file not shown.