From 552c8a9950e47c5ff22c8daaa631672a70322bac Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 2 May 2022 00:00:45 +0200 Subject: [PATCH] autocommit 2022-05-02 00:00:45 CEST --- src/it.rs | 2 ++ src/it/test_client.rs | 28 ++++++++++++++-- src/it/test_utils.rs | 1 + src/it/test_utils/test_window.rs | 48 +++++++++++++++++++++++++++ src/it/tests.rs | 16 ++++++++- src/it/tests/t0002_window.rs | 53 ++++++++++-------------------- src/it/tests/t0003_multi_window.rs | 38 +++++++++++++++++++++ src/state.rs | 12 ++++--- 8 files changed, 155 insertions(+), 43 deletions(-) create mode 100644 src/it/test_utils.rs create mode 100644 src/it/test_utils/test_window.rs create mode 100644 src/it/tests/t0003_multi_window.rs diff --git a/src/it.rs b/src/it.rs index 887962fa..f6f22c09 100644 --- a/src/it.rs +++ b/src/it.rs @@ -26,6 +26,7 @@ mod test_ifs; mod test_logger; mod test_mem; mod test_transport; +mod test_utils; mod testrun; mod tests; @@ -64,6 +65,7 @@ struct ItRun { } fn run_test(it_run: &ItRun, test: &'static dyn TestCase) { + log::info!("Running {}", test.name()); let dir = format!("{}/{}", it_run.path, test.name()); std::fs::create_dir_all(&dir).unwrap(); let log_path = format!("{}/log", dir); diff --git a/src/it/test_client.rs b/src/it/test_client.rs index 8daa4f14..7a17bcd0 100644 --- a/src/it/test_client.rs +++ b/src/it/test_client.rs @@ -2,6 +2,7 @@ use { crate::{ cli::screenshot::buf_to_qoi, client::Client, + format::ARGB8888, it::{ test_error::TestError, test_ifs::{ @@ -9,10 +10,13 @@ use { test_registry::TestRegistry, test_shm::TestShm, test_xdg_base::TestXdgWmBase, }, test_transport::TestTransport, + test_utils::test_window::TestWindow, testrun::TestRun, }, + theme::Color, + utils::clonecell::CloneCell, }, - std::rc::Rc, + std::{cell::Cell, rc::Rc}, }; pub struct TestClient { @@ -27,19 +31,39 @@ pub struct TestClient { } impl TestClient { + #[allow(dead_code)] pub fn error(&self, msg: &str) { self.tran.error(msg) } - pub async fn sync(self: &Rc) { + pub async fn sync(&self) { self.tran.sync().await } + #[allow(dead_code)] pub async fn take_screenshot(&self) -> Result, TestError> { let dmabuf = self.jc.take_screenshot().await?; let qoi = buf_to_qoi(&dmabuf); Ok(qoi) } + + pub async fn create_window(&self) -> Result, TestError> { + let surface = self.comp.create_surface().await?; + let shm = self.shm.create_pool(0)?; + let buffer = shm.create_buffer(0, 0, 0, 0, ARGB8888)?; + let xdg = self.xdg.create_xdg_surface(surface.id).await?; + let tl = xdg.create_toplevel().await?; + surface.commit(); + self.sync().await; + Ok(Rc::new(TestWindow { + surface, + xdg, + tl, + shm, + buffer: CloneCell::new(buffer), + color: Cell::new(Color::from_rgba_straight(0, 0, 0, 0)), + })) + } } impl Drop for TestClient { diff --git a/src/it/test_utils.rs b/src/it/test_utils.rs new file mode 100644 index 00000000..4bd1bfc6 --- /dev/null +++ b/src/it/test_utils.rs @@ -0,0 +1 @@ +pub mod test_window; diff --git a/src/it/test_utils/test_window.rs b/src/it/test_utils/test_window.rs new file mode 100644 index 00000000..db4557c3 --- /dev/null +++ b/src/it/test_utils/test_window.rs @@ -0,0 +1,48 @@ +use { + crate::{ + format::ARGB8888, + it::{ + test_error::TestError, + test_ifs::{ + test_shm_buffer::TestShmBuffer, test_shm_pool::TestShmPool, + test_surface::TestSurface, test_xdg_surface::TestXdgSurface, + test_xdg_toplevel::TestXdgToplevel, + }, + }, + theme::Color, + utils::clonecell::CloneCell, + }, + std::{cell::Cell, rc::Rc}, +}; + +pub struct TestWindow { + pub surface: Rc, + pub xdg: Rc, + pub tl: Rc, + pub shm: Rc, + pub buffer: CloneCell>, + pub color: Cell, +} + +impl TestWindow { + pub async fn map(&self) -> Result<(), TestError> { + let width = self.tl.width.get(); + let height = self.tl.height.get(); + let stride = width * 4; + let size = (stride * height) as usize; + self.shm.resize(size)?; + let buffer = self.shm.create_buffer(0, width, height, stride, ARGB8888)?; + buffer.fill(self.color.get()); + self.surface.attach(buffer.id); + self.xdg.ack_configure(self.xdg.last_serial.get()); + self.surface.commit(); + self.buffer.set(buffer); + self.surface.tran.sync().await; + Ok(()) + } + + #[allow(dead_code)] + pub fn set_color(&self, r: u8, g: u8, b: u8, a: u8) { + self.color.set(Color::from_rgba_straight(r, g, b, a)); + } +} diff --git a/src/it/tests.rs b/src/it/tests.rs index 578ccca6..1bd79600 100644 --- a/src/it/tests.rs +++ b/src/it/tests.rs @@ -55,6 +55,7 @@ macro_rules! tassert_eq { mod t0001_shm_formats; mod t0002_window; +mod t0003_multi_window; pub trait TestCase { fn name(&self) -> &'static str; @@ -62,5 +63,18 @@ pub trait TestCase { } pub fn tests() -> Vec<&'static dyn TestCase> { - vec![&t0001_shm_formats::Test, &t0002_window::Test] + macro_rules! tests { + ($($module:ident,)*) => { + vec![ + $( + &$module::Test, + )* + ] + } + } + tests! { + t0001_shm_formats, + t0002_window, + t0003_multi_window, + } } diff --git a/src/it/tests/t0002_window.rs b/src/it/tests/t0002_window.rs index 3df698b2..fe72dae6 100644 --- a/src/it/tests/t0002_window.rs +++ b/src/it/tests/t0002_window.rs @@ -1,8 +1,8 @@ use { crate::{ - format::ARGB8888, it::{test_error::TestError, testrun::TestRun}, - theme::Color, + rect::Rect, + tree::Node, }, std::rc::Rc, }; @@ -14,43 +14,26 @@ async fn test(run: Rc) -> Result<(), TestError> { run.backend.install_default(); let client = run.create_client().await?; - let surface = client.comp.create_surface().await?; - let xdg_surface = client.xdg.create_xdg_surface(surface.id).await?; - let xdg_toplevel = xdg_surface.create_toplevel().await?; - surface.commit(); - client.sync().await; - { - let pool = client.shm.create_pool(0)?; - let buffer = pool.create_buffer(0, 0, 0, 0, ARGB8888)?; - xdg_surface.ack_configure(xdg_surface.last_serial.get()); - surface.attach(buffer.id); - surface.commit(); - client.sync().await; - } + let window = client.create_window().await?; + window.map().await?; - tassert_eq!(xdg_toplevel.width.get(), 800); - tassert!(xdg_toplevel.height.get() >= 500); + tassert_eq!(window.tl.width.get(), 800); + tassert_eq!( + window.tl.height.get(), + 600 - 2 * (run.state.theme.title_height.get() + 1) + ); - { - let pool = client - .shm - .create_pool((xdg_toplevel.width.get() * xdg_toplevel.height.get() * 4) as _)?; - let buffer = pool.create_buffer( + tassert_eq!( + window.tl.server.node_absolute_position(), + Rect::new_sized( 0, - xdg_toplevel.width.get(), - xdg_toplevel.height.get(), - xdg_toplevel.width.get() * 4, - ARGB8888, - )?; - buffer.fill(Color::from_rgba_straight(255, 0, 0, 100)); - xdg_surface.ack_configure(xdg_surface.last_serial.get()); - surface.attach(buffer.id); - surface.commit(); - } - - let screenshot = client.take_screenshot().await?; - std::fs::write(format!("{}/screenshot.qoi", run.dir), screenshot)?; + 2 * (run.state.theme.title_height.get() + 1), + window.tl.width.get(), + window.tl.height.get(), + ) + .unwrap() + ); Ok(()) } diff --git a/src/it/tests/t0003_multi_window.rs b/src/it/tests/t0003_multi_window.rs new file mode 100644 index 00000000..adf48b34 --- /dev/null +++ b/src/it/tests/t0003_multi_window.rs @@ -0,0 +1,38 @@ +use { + crate::{ + it::{test_error::TestError, testrun::TestRun}, + rect::Rect, + tree::Node, + }, + std::rc::Rc, +}; + +testcase!(); + +/// Create and map two surfaces +async fn test(run: Rc) -> Result<(), TestError> { + run.backend.install_default(); + + let client = run.create_client().await?; + + let window = client.create_window().await?; + window.map().await?; + + let window2 = client.create_window().await?; + window2.map().await?; + + let otop = 2 * (run.state.theme.title_height.get() + 1); + let bw = run.state.theme.border_width.get(); + + tassert_eq!( + window.tl.server.node_absolute_position(), + Rect::new_sized(0, otop, (800 - bw) / 2, 600 - otop).unwrap() + ); + + tassert_eq!( + window2.tl.server.node_absolute_position(), + Rect::new_sized((800 - bw) / 2 + bw, otop, (800 - bw) / 2, 600 - otop).unwrap() + ); + + Ok(()) +} diff --git a/src/state.rs b/src/state.rs index 8da3c926..7fa49334 100644 --- a/src/state.rs +++ b/src/state.rs @@ -241,15 +241,17 @@ impl State { pub fn map_tiled_on(self: &Rc, node: Rc, ws: &Rc) { if let Some(c) = ws.container.get() { - let la = c.tl_last_active_child(); + let la = c.clone().tl_last_active_child(); let lap = la .tl_data() .parent .get() - .unwrap() - .node_into_container() - .unwrap(); - lap.add_child_after(la.tl_as_node(), node); + .and_then(|n| n.node_into_container()); + if let Some(lap) = lap { + lap.add_child_after(la.tl_as_node(), node); + } else { + c.append_child(node); + } } else { let container = ContainerNode::new(self, &ws, ws.clone(), node, ContainerSplit::Horizontal);