it: test subsurface positioning
This commit is contained in:
parent
fd027d9a5a
commit
cbf539cbcc
17 changed files with 291 additions and 9 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
|
async_engine::Phase,
|
||||||
it::{
|
it::{
|
||||||
test_backend::TestBackend,
|
test_backend::TestBackend,
|
||||||
test_config::{with_test_config, TestConfig},
|
test_config::{with_test_config, TestConfig},
|
||||||
|
|
@ -132,12 +133,14 @@ fn run_test(it_run: &ItRun, test: &'static dyn TestCase, cfg: Rc<TestConfig>) {
|
||||||
backend,
|
backend,
|
||||||
errors: Default::default(),
|
errors: Default::default(),
|
||||||
server_addr,
|
server_addr,
|
||||||
dir: dir.clone(),
|
out_dir: dir.clone(),
|
||||||
|
in_dir: format!("{}/{}", env!("CARGO_MANIFEST_DIR"), test.dir()),
|
||||||
cfg: cfg.clone(),
|
cfg: cfg.clone(),
|
||||||
});
|
});
|
||||||
let errors = errors2.clone();
|
let errors = errors2.clone();
|
||||||
Box::new(async move {
|
Box::new(async move {
|
||||||
let future: Pin<_> = test.run(testrun.clone()).into();
|
let future: Pin<_> = test.run(testrun.clone()).into();
|
||||||
|
let future = state.eng.spawn2(Phase::Present, future);
|
||||||
let timeout = state.eng.timeout(5000).unwrap();
|
let timeout = state.eng.timeout(5000).unwrap();
|
||||||
match future::select(future, timeout).await {
|
match future::select(future, timeout).await {
|
||||||
Either::Left((Ok(..), _)) => {}
|
Either::Left((Ok(..), _)) => {}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ use {
|
||||||
test_error::TestError,
|
test_error::TestError,
|
||||||
test_ifs::{
|
test_ifs::{
|
||||||
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
||||||
test_registry::TestRegistry, test_shm::TestShm, test_xdg_base::TestXdgWmBase,
|
test_registry::TestRegistry, test_shm::TestShm,
|
||||||
|
test_subcompositor::TestSubcompositor, test_xdg_base::TestXdgWmBase,
|
||||||
},
|
},
|
||||||
test_transport::TestTransport,
|
test_transport::TestTransport,
|
||||||
test_utils::test_window::TestWindow,
|
test_utils::test_window::TestWindow,
|
||||||
|
|
@ -26,6 +27,7 @@ pub struct TestClient {
|
||||||
pub registry: Rc<TestRegistry>,
|
pub registry: Rc<TestRegistry>,
|
||||||
pub jc: Rc<TestJayCompositor>,
|
pub jc: Rc<TestJayCompositor>,
|
||||||
pub comp: Rc<TestCompositor>,
|
pub comp: Rc<TestCompositor>,
|
||||||
|
pub sub: Rc<TestSubcompositor>,
|
||||||
pub shm: Rc<TestShm>,
|
pub shm: Rc<TestShm>,
|
||||||
pub xdg: Rc<TestXdgWmBase>,
|
pub xdg: Rc<TestXdgWmBase>,
|
||||||
}
|
}
|
||||||
|
|
@ -40,13 +42,35 @@ impl TestClient {
|
||||||
self.tran.sync().await
|
self.tran.sync().await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub async fn take_screenshot(&self) -> Result<Vec<u8>, TestError> {
|
pub async fn take_screenshot(&self) -> Result<Vec<u8>, TestError> {
|
||||||
let dmabuf = self.jc.take_screenshot().await?;
|
let dmabuf = self.jc.take_screenshot().await?;
|
||||||
let qoi = buf_to_qoi(&dmabuf);
|
let qoi = buf_to_qoi(&dmabuf);
|
||||||
Ok(qoi)
|
Ok(qoi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub async fn save_screenshot(&self, name: &str) -> Result<(), TestError> {
|
||||||
|
let qoi = self.take_screenshot().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?;
|
||||||
|
let expected_path = format!("{}/screenshot_{}.qoi", self.run.in_dir, name);
|
||||||
|
let expected = std::fs::read(expected_path)?;
|
||||||
|
if actual != expected {
|
||||||
|
let actual_out_path = format!("{}/screenshot_{}_actual.qoi", self.run.out_dir, name);
|
||||||
|
let expected_out_path =
|
||||||
|
format!("{}/screenshot_{}_expected.qoi", self.run.out_dir, name);
|
||||||
|
let _ = std::fs::write(actual_out_path, actual);
|
||||||
|
let _ = std::fs::write(expected_out_path, expected);
|
||||||
|
bail!("Screenshots differ");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn create_window(&self) -> Result<Rc<TestWindow>, TestError> {
|
pub async fn create_window(&self) -> Result<Rc<TestWindow>, TestError> {
|
||||||
let surface = self.comp.create_surface().await?;
|
let surface = self.comp.create_surface().await?;
|
||||||
let shm = self.shm.create_pool(0)?;
|
let shm = self.shm.create_pool(0)?;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
use {
|
use {
|
||||||
crate::{ifs::wl_seat::SeatId, it::test_error::TestError, utils::stack::Stack},
|
crate::{ifs::wl_seat::SeatId, it::test_error::TestError, utils::stack::Stack},
|
||||||
isnt::std_1::primitive::IsntConstPtrExt,
|
isnt::std_1::primitive::IsntConstPtrExt,
|
||||||
jay_config::_private::{
|
jay_config::{
|
||||||
bincode_ops,
|
_private::{
|
||||||
ipc::{ClientMessage, Response, ServerMessage},
|
bincode_ops,
|
||||||
ConfigEntry, VERSION,
|
ipc::{ClientMessage, Response, ServerMessage},
|
||||||
|
ConfigEntry, VERSION,
|
||||||
|
},
|
||||||
|
input::Seat,
|
||||||
},
|
},
|
||||||
std::{cell::Cell, ops::Deref, ptr, rc::Rc},
|
std::{cell::Cell, ops::Deref, ptr, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
@ -149,6 +152,15 @@ impl TestConfig {
|
||||||
Ok(SeatId::from_raw(seat.0 as _))
|
Ok(SeatId::from_raw(seat.0 as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn show_workspace(&self, seat: SeatId, name: &str) -> Result<(), TestError> {
|
||||||
|
let reply = self.send_with_reply(ClientMessage::GetWorkspace { name })?;
|
||||||
|
get_response!(reply, GetWorkspace { workspace });
|
||||||
|
self.send(ClientMessage::ShowWorkspace {
|
||||||
|
seat: Seat(seat.raw() as _),
|
||||||
|
workspace,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn clear(&self) {
|
fn clear(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(srv) = self.srv.take() {
|
if let Some(srv) = self.srv.take() {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ pub mod test_screenshot;
|
||||||
pub mod test_shm;
|
pub mod test_shm;
|
||||||
pub mod test_shm_buffer;
|
pub mod test_shm_buffer;
|
||||||
pub mod test_shm_pool;
|
pub mod test_shm_pool;
|
||||||
|
pub mod test_subcompositor;
|
||||||
|
pub mod test_subsurface;
|
||||||
pub mod test_surface;
|
pub mod test_surface;
|
||||||
pub mod test_xdg_base;
|
pub mod test_xdg_base;
|
||||||
pub mod test_xdg_surface;
|
pub mod test_xdg_surface;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ use {
|
||||||
test_error::TestError,
|
test_error::TestError,
|
||||||
test_ifs::{
|
test_ifs::{
|
||||||
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
||||||
test_shm::TestShm, test_xdg_base::TestXdgWmBase,
|
test_shm::TestShm, test_subcompositor::TestSubcompositor,
|
||||||
|
test_xdg_base::TestXdgWmBase,
|
||||||
},
|
},
|
||||||
test_object::TestObject,
|
test_object::TestObject,
|
||||||
test_transport::TestTransport,
|
test_transport::TestTransport,
|
||||||
|
|
@ -27,6 +28,7 @@ pub struct TestGlobal {
|
||||||
pub struct TestRegistrySingletons {
|
pub struct TestRegistrySingletons {
|
||||||
pub jay_compositor: u32,
|
pub jay_compositor: u32,
|
||||||
pub wl_compositor: u32,
|
pub wl_compositor: u32,
|
||||||
|
pub wl_subcompositor: u32,
|
||||||
pub wl_shm: u32,
|
pub wl_shm: u32,
|
||||||
pub xdg_wm_base: u32,
|
pub xdg_wm_base: u32,
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +40,7 @@ pub struct TestRegistry {
|
||||||
pub singletons: CloneCell<Option<Rc<TestRegistrySingletons>>>,
|
pub singletons: CloneCell<Option<Rc<TestRegistrySingletons>>>,
|
||||||
pub jay_compositor: CloneCell<Option<Rc<TestJayCompositor>>>,
|
pub jay_compositor: CloneCell<Option<Rc<TestJayCompositor>>>,
|
||||||
pub compositor: CloneCell<Option<Rc<TestCompositor>>>,
|
pub compositor: CloneCell<Option<Rc<TestCompositor>>>,
|
||||||
|
pub subcompositor: CloneCell<Option<Rc<TestSubcompositor>>>,
|
||||||
pub shm: CloneCell<Option<Rc<TestShm>>>,
|
pub shm: CloneCell<Option<Rc<TestShm>>>,
|
||||||
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
||||||
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
||||||
|
|
@ -84,6 +87,7 @@ impl TestRegistry {
|
||||||
let singletons = singleton! {
|
let singletons = singleton! {
|
||||||
jay_compositor,
|
jay_compositor,
|
||||||
wl_compositor,
|
wl_compositor,
|
||||||
|
wl_subcompositor,
|
||||||
wl_shm,
|
wl_shm,
|
||||||
xdg_wm_base,
|
xdg_wm_base,
|
||||||
};
|
};
|
||||||
|
|
@ -118,6 +122,20 @@ impl TestRegistry {
|
||||||
Ok(jc)
|
Ok(jc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_subcompositor(&self) -> Result<Rc<TestSubcompositor>, TestError> {
|
||||||
|
singleton!(self.subcompositor);
|
||||||
|
let singletons = self.get_singletons().await?;
|
||||||
|
singleton!(self.subcompositor);
|
||||||
|
let jc = Rc::new(TestSubcompositor {
|
||||||
|
id: self.tran.id(),
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
destroyed: Cell::new(false),
|
||||||
|
});
|
||||||
|
self.bind(&jc, singletons.wl_subcompositor, 1)?;
|
||||||
|
self.subcompositor.set(Some(jc.clone()));
|
||||||
|
Ok(jc)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_shm(&self) -> Result<Rc<TestShm>, TestError> {
|
pub async fn get_shm(&self) -> Result<Rc<TestShm>, TestError> {
|
||||||
singleton!(self.shm);
|
singleton!(self.shm);
|
||||||
let singletons = self.get_singletons().await?;
|
let singletons = self.get_singletons().await?;
|
||||||
|
|
|
||||||
60
src/it/test_ifs/test_subcompositor.rs
Normal file
60
src/it/test_ifs/test_subcompositor.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
it::{
|
||||||
|
test_error::TestError, test_ifs::test_subsurface::TestSubsurface,
|
||||||
|
test_object::TestObject, test_transport::TestTransport,
|
||||||
|
},
|
||||||
|
wire::{wl_subcompositor::*, WlSubcompositorId, WlSurfaceId},
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestSubcompositor {
|
||||||
|
pub id: WlSubcompositorId,
|
||||||
|
pub tran: Rc<TestTransport>,
|
||||||
|
pub destroyed: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestSubcompositor {
|
||||||
|
pub fn destroy(&self) -> Result<(), TestError> {
|
||||||
|
if !self.destroyed.replace(true) {
|
||||||
|
self.tran.send(Destroy { self_id: self.id })?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_subsurface(
|
||||||
|
&self,
|
||||||
|
surface: WlSurfaceId,
|
||||||
|
parent: WlSurfaceId,
|
||||||
|
) -> Result<Rc<TestSubsurface>, TestError> {
|
||||||
|
let id = self.tran.id();
|
||||||
|
self.tran.send(GetSubsurface {
|
||||||
|
self_id: self.id,
|
||||||
|
id,
|
||||||
|
surface,
|
||||||
|
parent,
|
||||||
|
})?;
|
||||||
|
self.tran.sync().await;
|
||||||
|
let ss = Rc::new(TestSubsurface {
|
||||||
|
id,
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
destroyed: Cell::new(false),
|
||||||
|
server: self.tran.get_object(id)?,
|
||||||
|
});
|
||||||
|
self.tran.add_obj(ss.clone())?;
|
||||||
|
Ok(ss)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TestSubcompositor {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_object! {
|
||||||
|
TestSubcompositor, WlSubcompositor;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObject for TestSubcompositor {}
|
||||||
68
src/it/test_ifs/test_subsurface.rs
Normal file
68
src/it/test_ifs/test_subsurface.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
ifs::wl_surface::wl_subsurface::WlSubsurface,
|
||||||
|
it::{test_error::TestError, test_object::TestObject, test_transport::TestTransport},
|
||||||
|
wire::{wl_subsurface::*, WlSubsurfaceId, WlSurfaceId},
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestSubsurface {
|
||||||
|
pub id: WlSubsurfaceId,
|
||||||
|
pub tran: Rc<TestTransport>,
|
||||||
|
pub destroyed: Cell<bool>,
|
||||||
|
pub server: Rc<WlSubsurface>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestSubsurface {
|
||||||
|
pub fn destroy(&self) -> Result<(), TestError> {
|
||||||
|
if !self.destroyed.replace(true) {
|
||||||
|
self.tran.send(Destroy { self_id: self.id })?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_position(&self, x: i32, y: i32) -> Result<(), TestError> {
|
||||||
|
self.tran.send(SetPosition {
|
||||||
|
self_id: self.id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn place_above(&self, surface: WlSurfaceId) -> Result<(), TestError> {
|
||||||
|
self.tran.send(PlaceAbove {
|
||||||
|
self_id: self.id,
|
||||||
|
sibling: surface,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn place_below(&self, surface: WlSurfaceId) -> Result<(), TestError> {
|
||||||
|
self.tran.send(PlaceBelow {
|
||||||
|
self_id: self.id,
|
||||||
|
sibling: surface,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn set_sync(&self) -> Result<(), TestError> {
|
||||||
|
self.tran.send(SetSync { self_id: self.id })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn set_desync(&self) -> Result<(), TestError> {
|
||||||
|
self.tran.send(SetDesync { self_id: self.id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TestSubsurface {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_object! {
|
||||||
|
TestSubsurface, WlSubsurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObject for TestSubsurface {}
|
||||||
|
|
@ -6,6 +6,7 @@ use {
|
||||||
test_error::{StdError, TestError},
|
test_error::{StdError, TestError},
|
||||||
test_ifs::{test_callback::TestCallback, test_registry::TestRegistry},
|
test_ifs::{test_callback::TestCallback, test_registry::TestRegistry},
|
||||||
test_object::TestObject,
|
test_object::TestObject,
|
||||||
|
test_utils::test_object_ext::TestObjectExt,
|
||||||
testrun::TestRun,
|
testrun::TestRun,
|
||||||
},
|
},
|
||||||
object::{ObjectId, WL_DISPLAY_ID},
|
object::{ObjectId, WL_DISPLAY_ID},
|
||||||
|
|
@ -52,6 +53,7 @@ impl TestTransport {
|
||||||
singletons: Default::default(),
|
singletons: Default::default(),
|
||||||
jay_compositor: Default::default(),
|
jay_compositor: Default::default(),
|
||||||
compositor: Default::default(),
|
compositor: Default::default(),
|
||||||
|
subcompositor: Default::default(),
|
||||||
shm: Default::default(),
|
shm: Default::default(),
|
||||||
xdg: Default::default(),
|
xdg: Default::default(),
|
||||||
seats: Default::default(),
|
seats: Default::default(),
|
||||||
|
|
@ -169,6 +171,11 @@ impl TestTransport {
|
||||||
self.flush_request.trigger();
|
self.flush_request.trigger();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_object<I: Into<ObjectId>, T: 'static>(&self, id: I) -> Result<Rc<T>, TestError> {
|
||||||
|
let client = self.get_client()?;
|
||||||
|
client.objects.get_obj(id.into())?.downcast()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Outgoing {
|
struct Outgoing {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
pub mod test_object_ext;
|
||||||
pub mod test_window;
|
pub mod test_window;
|
||||||
|
|
|
||||||
17
src/it/test_utils/test_object_ext.rs
Normal file
17
src/it/test_utils/test_object_ext.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use {
|
||||||
|
crate::{it::test_error::TestError, object::Object},
|
||||||
|
std::rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait TestObjectExt {
|
||||||
|
fn downcast<T: 'static>(self: Rc<Self>) -> Result<Rc<T>, TestError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObjectExt for dyn Object {
|
||||||
|
fn downcast<T: 'static>(self: Rc<Self>) -> Result<Rc<T>, TestError> {
|
||||||
|
match self.into_any().downcast() {
|
||||||
|
Ok(t) => Ok(t),
|
||||||
|
_ => bail!("Object has an incompatible type id"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,8 @@ pub struct TestRun {
|
||||||
pub backend: Rc<TestBackend>,
|
pub backend: Rc<TestBackend>,
|
||||||
pub errors: Stack<String>,
|
pub errors: Stack<String>,
|
||||||
pub server_addr: c::sockaddr_un,
|
pub server_addr: c::sockaddr_un,
|
||||||
pub dir: String,
|
pub out_dir: String,
|
||||||
|
pub in_dir: String,
|
||||||
pub cfg: Rc<TestConfig>,
|
pub cfg: Rc<TestConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,6 +86,7 @@ impl TestRun {
|
||||||
tran,
|
tran,
|
||||||
jc,
|
jc,
|
||||||
comp: registry.get_compositor().await?,
|
comp: registry.get_compositor().await?,
|
||||||
|
sub: registry.get_subcompositor().await?,
|
||||||
shm: registry.get_shm().await?,
|
shm: registry.get_shm().await?,
|
||||||
xdg: registry.get_xdg().await?,
|
xdg: registry.get_xdg().await?,
|
||||||
registry,
|
registry,
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ macro_rules! testcase {
|
||||||
module_path!().strip_prefix("jay::it::tests::").unwrap()
|
module_path!().strip_prefix("jay::it::tests::").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dir(&self) -> &'static str {
|
||||||
|
file!().strip_suffix(".rs").unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
testrun: std::rc::Rc<crate::it::testrun::TestRun>,
|
testrun: std::rc::Rc<crate::it::testrun::TestRun>,
|
||||||
|
|
@ -28,9 +32,11 @@ mod t0003_multi_window;
|
||||||
mod t0004_quit;
|
mod t0004_quit;
|
||||||
mod t0005_create_seat;
|
mod t0005_create_seat;
|
||||||
mod t0006_region;
|
mod t0006_region;
|
||||||
|
mod t0007_subsurface;
|
||||||
|
|
||||||
pub trait TestCase: Sync {
|
pub trait TestCase: Sync {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
fn dir(&self) -> &'static str;
|
||||||
fn run(&self, testrun: Rc<TestRun>) -> Box<dyn Future<Output = Result<(), TestError>>>;
|
fn run(&self, testrun: Rc<TestRun>) -> Box<dyn Future<Output = Result<(), TestError>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,5 +57,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
||||||
t0004_quit,
|
t0004_quit,
|
||||||
t0005_create_seat,
|
t0005_create_seat,
|
||||||
t0006_region,
|
t0006_region,
|
||||||
|
t0007_subsurface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
55
src/it/tests/t0007_subsurface.rs
Normal file
55
src/it/tests/t0007_subsurface.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
format::ARGB8888,
|
||||||
|
it::{test_error::TestError, testrun::TestRun},
|
||||||
|
theme::Color,
|
||||||
|
},
|
||||||
|
std::rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
|
testcase!();
|
||||||
|
|
||||||
|
async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
|
||||||
|
run.backend.install_default();
|
||||||
|
|
||||||
|
let seat = run.get_seat("default")?;
|
||||||
|
|
||||||
|
run.state.eng.yield_now().await;
|
||||||
|
|
||||||
|
run.cfg.show_workspace(seat.id(), "")?;
|
||||||
|
|
||||||
|
let client = run.create_client().await?;
|
||||||
|
|
||||||
|
let parent = client.create_window().await?;
|
||||||
|
parent.map().await?;
|
||||||
|
parent.set_color(0, 0, 0, 255);
|
||||||
|
|
||||||
|
let child = client.comp.create_surface().await?;
|
||||||
|
let sub = client
|
||||||
|
.sub
|
||||||
|
.get_subsurface(child.id, parent.surface.id)
|
||||||
|
.await?;
|
||||||
|
sub.set_position(100, 100)?;
|
||||||
|
|
||||||
|
let pool = client.shm.create_pool(100 * 100 * 4)?;
|
||||||
|
let buffer = pool.create_buffer(0, 100, 100, 100 * 4, ARGB8888)?;
|
||||||
|
buffer.fill(Color::from_rgba_straight(255, 255, 255, 255));
|
||||||
|
|
||||||
|
child.attach(buffer.id)?;
|
||||||
|
|
||||||
|
parent.map().await?;
|
||||||
|
|
||||||
|
seat.set_app_cursor(None);
|
||||||
|
|
||||||
|
client.compare_screenshot("1").await?;
|
||||||
|
|
||||||
|
sub.place_below(parent.surface.id)?;
|
||||||
|
parent.map().await?;
|
||||||
|
client.compare_screenshot("2").await?;
|
||||||
|
|
||||||
|
sub.place_above(parent.surface.id)?;
|
||||||
|
parent.map().await?;
|
||||||
|
client.compare_screenshot("1").await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
BIN
src/it/tests/t0007_subsurface/screenshot_1.qoi
Normal file
BIN
src/it/tests/t0007_subsurface/screenshot_1.qoi
Normal file
Binary file not shown.
BIN
src/it/tests/t0007_subsurface/screenshot_2.qoi
Normal file
BIN
src/it/tests/t0007_subsurface/screenshot_2.qoi
Normal file
Binary file not shown.
|
|
@ -18,6 +18,10 @@ macro_rules! object_base {
|
||||||
self.id.into()
|
self.id.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_any(self: std::rc::Rc<Self>) -> std::rc::Rc<dyn std::any::Any> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused_variables, unreachable_code)]
|
#[allow(unused_variables, unreachable_code)]
|
||||||
fn handle_request(
|
fn handle_request(
|
||||||
self: std::rc::Rc<Self>,
|
self: std::rc::Rc<Self>,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{client::ClientError, utils::buffd::MsgParser, wire::WlDisplayId},
|
crate::{client::ClientError, utils::buffd::MsgParser, wire::WlDisplayId},
|
||||||
std::{
|
std::{
|
||||||
|
any::Any,
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
},
|
},
|
||||||
|
|
@ -31,6 +32,7 @@ impl Display for ObjectId {
|
||||||
|
|
||||||
pub trait ObjectBase {
|
pub trait ObjectBase {
|
||||||
fn id(&self) -> ObjectId;
|
fn id(&self) -> ObjectId;
|
||||||
|
fn into_any(self: Rc<Self>) -> Rc<dyn Any>;
|
||||||
fn handle_request(
|
fn handle_request(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
request: u32,
|
request: u32,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue