diff --git a/src/forker.rs b/src/forker.rs index 49870589..0f47a710 100644 --- a/src/forker.rs +++ b/src/forker.rs @@ -106,7 +106,7 @@ impl ForkerProxy { Forked::Child { .. } => { drop(parent); Forker::handle(pid, child) - }, + } } } diff --git a/src/it/test_config.rs b/src/it/test_config.rs index 4d9437fb..a34a6f39 100644 --- a/src/it/test_config.rs +++ b/src/it/test_config.rs @@ -1,6 +1,8 @@ use { crate::{ - backend::InputDeviceId, ifs::wl_seat::SeatId, it::test_error::TestError, + backend::InputDeviceId, + ifs::wl_seat::SeatId, + it::test_error::{TestError, TestResult}, utils::stack::Stack, }, isnt::std_1::primitive::IsntConstPtrExt, @@ -11,6 +13,7 @@ use { ConfigEntry, VERSION, }, input::{InputDevice, Seat}, + Direction, }, std::{cell::Cell, ops::Deref, ptr, rc::Rc}, }; @@ -171,6 +174,13 @@ impl TestConfig { }) } + pub fn focus(&self, seat: SeatId, direction: Direction) -> TestResult { + self.send(ClientMessage::Focus { + seat: Seat(seat.raw() as _), + direction, + }) + } + fn clear(&self) { unsafe { if let Some(srv) = self.srv.take() { diff --git a/src/it/test_ifs/test_keyboard.rs b/src/it/test_ifs/test_keyboard.rs index 3218d538..87858ee8 100644 --- a/src/it/test_ifs/test_keyboard.rs +++ b/src/it/test_ifs/test_keyboard.rs @@ -23,6 +23,7 @@ pub struct TestKeyboard { pub server: CloneCell>>, pub destroyed: Once, pub enter: TEEH, + pub leave: TEEH, } impl TestKeyboard { @@ -49,7 +50,8 @@ impl TestKeyboard { } fn handle_leave(&self, parser: MsgParser<'_, '_>) -> TestResult { - let _ev = Leave::parse_full(parser)?; + let ev = Leave::parse_full(parser)?; + self.leave.push(ev); Ok(()) } diff --git a/src/it/test_ifs/test_seat.rs b/src/it/test_ifs/test_seat.rs index 7fb6871f..48d2e5e3 100644 --- a/src/it/test_ifs/test_seat.rs +++ b/src/it/test_ifs/test_seat.rs @@ -43,6 +43,7 @@ impl TestSeat { server: Default::default(), destroyed: Default::default(), enter: Default::default(), + leave: Default::default(), }); self.tran.add_obj(kb.clone())?; self.tran.sync().await; diff --git a/src/it/test_utils/test_expected_event.rs b/src/it/test_utils/test_expected_event.rs index 106d6f9d..de5b7d17 100644 --- a/src/it/test_utils/test_expected_event.rs +++ b/src/it/test_utils/test_expected_event.rs @@ -1,5 +1,6 @@ use { crate::{it::test_error::TestResult, utils::clonecell::CloneCell}, + isnt::std_1::collections::IsntVecDequeExt, std::{cell::RefCell, collections::VecDeque, rc::Rc}, }; @@ -22,6 +23,13 @@ impl TestExpectedEvent { _ => bail!("No event occurred"), } } + + pub fn none(&self) -> TestResult { + if self.data.events.borrow_mut().is_not_empty() { + bail!("There are unexpected events"); + } + Ok(()) + } } pub struct TestExpectedEventHolder { diff --git a/src/it/tests.rs b/src/it/tests.rs index c55b422c..b12090a8 100644 --- a/src/it/tests.rs +++ b/src/it/tests.rs @@ -34,6 +34,7 @@ mod t0005_create_seat; mod t0006_region; mod t0007_subsurface; mod t0008_map_focus; +mod t0009_tab_focus; pub trait TestCase: Sync { fn name(&self) -> &'static str; @@ -60,5 +61,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> { t0006_region, t0007_subsurface, t0008_map_focus, + t0009_tab_focus, } } diff --git a/src/it/tests/t0009_tab_focus.rs b/src/it/tests/t0009_tab_focus.rs new file mode 100644 index 00000000..da04e9bf --- /dev/null +++ b/src/it/tests/t0009_tab_focus.rs @@ -0,0 +1,51 @@ +use { + crate::it::{ + test_error::{TestError, TestErrorExt}, + testrun::TestRun, + }, + jay_config::Direction, + std::rc::Rc, +}; + +testcase!(); + +async fn test(run: Rc) -> Result<(), TestError> { + let ds = run.create_default_setup().await?; + ds.mouse.rel(1.0, 1.0); + + let client = run.create_client().await?; + let default_seat = client.get_default_seat().await?; + + let eleave = default_seat.kb.leave.expect()?; + let eenter = default_seat.kb.enter.expect()?; + + let window = client.create_window().await?; + window.map().await?; + + tassert!(eenter.next().is_ok()); + tassert!(eleave.next().is_err()); + + let window2 = client.create_window().await?; + window2.map().await?; + + let leave = eleave.next().with_context(|| "Did not leave")?; + let enter = eenter.next().with_context(|| "Did not enter")?; + + tassert_eq!(leave.surface, window.surface.id); + tassert_eq!(enter.surface, window2.surface.id); + + eenter.none().with_context(|| "Unexpected enter")?; + eleave.none().with_context(|| "Unexpected leave")?; + + run.cfg.focus(ds.seat.id(), Direction::Left)?; + + client.sync().await; + + let leave = eleave.next().with_context(|| "Did not leave")?; + let enter = eenter.next().with_context(|| "Did not enter")?; + + tassert_eq!(leave.surface, window2.surface.id); + tassert_eq!(enter.surface, window.surface.id); + + Ok(()) +}