1
0
Fork 0
forked from wry/wry

it: test natural scrolling

This commit is contained in:
Julian Orth 2024-04-02 10:26:42 +02:00
parent f562f887f0
commit adf6d2ae2b
12 changed files with 149 additions and 2 deletions

View file

@ -319,13 +319,17 @@ impl TestBackendMouse {
}
pub fn scroll_px(&self, dy: i32) {
self.scroll_px2(dy, false);
}
pub fn scroll_px2(&self, dy: i32, inverted: bool) {
self.common.event(InputEvent::AxisSource {
source: AxisSource::Finger,
});
self.common.event(InputEvent::AxisPx {
dist: Fixed::from_int(dy),
axis: ScrollAxis::Vertical,
inverted: false,
inverted,
});
self.common.event(InputEvent::AxisFrame {
time_usec: now_usec(),

View file

@ -67,7 +67,7 @@ impl TestClient {
caps: Cell::new(0),
name: Default::default(),
});
self.registry.bind(&tseat, seat.name().raw(), 7)?;
self.registry.bind(&tseat, seat.name().raw(), 9)?;
self.tran.sync().await;
let server = self.tran.get_server_obj(tseat.id)?;
tseat.server.set(Some(server));

View file

@ -19,6 +19,7 @@ pub struct TestPointer {
pub leave: TEEH<Leave>,
pub enter: TEEH<Enter>,
pub motion: TEEH<Motion>,
pub axis_relative_direction: TEEH<AxisRelativeDirection>,
}
impl TestPointer {
@ -76,6 +77,12 @@ impl TestPointer {
let _ev = AxisDiscrete::parse_full(parser)?;
Ok(())
}
fn handle_axis_relative_direction(&self, parser: MsgParser<'_, '_>) -> TestResult {
let ev = AxisRelativeDirection::parse_full(parser)?;
self.axis_relative_direction.push(ev);
Ok(())
}
}
impl Drop for TestPointer {
@ -96,6 +103,7 @@ test_object! {
AXIS_SOURCE => handle_axis_source,
AXIS_STOP => handle_axis_stop,
AXIS_DISCRETE => handle_axis_discrete,
AXIS_RELATIVE_DIRECTION => handle_axis_relative_direction,
}
impl TestObject for TestPointer {}

View file

@ -66,6 +66,7 @@ impl TestSeat {
leave: Rc::new(Default::default()),
enter: Rc::new(Default::default()),
motion: Rc::new(Default::default()),
axis_relative_direction: Rc::new(Default::default()),
});
self.tran.add_obj(pointer.clone())?;
self.tran.sync().await;

View file

@ -1,3 +1,7 @@
pub mod test_container_node_ext;
pub mod test_expected_event;
pub mod test_object_ext;
pub mod test_ouput_node_ext;
pub mod test_toplevel_node_ext;
pub mod test_window;
pub mod test_workspace_node_ext;

View file

@ -0,0 +1,20 @@
use {
crate::{
it::test_error::TestResult,
tree::{ContainerNode, ToplevelNode},
},
std::rc::Rc,
};
pub trait TestContainerExt {
fn first_toplevel(&self) -> TestResult<Rc<dyn ToplevelNode>>;
}
impl TestContainerExt for ContainerNode {
fn first_toplevel(&self) -> TestResult<Rc<dyn ToplevelNode>> {
match self.children.first() {
None => bail!("container does not have children"),
Some(c) => Ok(c.node.clone()),
}
}
}

View file

@ -0,0 +1,20 @@
use {
crate::{
it::test_error::TestResult,
tree::{OutputNode, WorkspaceNode},
},
std::rc::Rc,
};
pub trait TestOutputNodeExt {
fn workspace(&self) -> TestResult<Rc<WorkspaceNode>>;
}
impl TestOutputNodeExt for OutputNode {
fn workspace(&self) -> TestResult<Rc<WorkspaceNode>> {
match self.workspace.get() {
None => bail!("Output node does not have a container"),
Some(w) => Ok(w),
}
}
}

View file

@ -0,0 +1,12 @@
use crate::tree::ToplevelNode;
pub trait TestToplevelNodeExt {
fn center(&self) -> (i32, i32);
}
impl TestToplevelNodeExt for dyn ToplevelNode {
fn center(&self) -> (i32, i32) {
let rect = self.node_absolute_position();
((rect.x1() + rect.x2()) / 2, (rect.y1() + rect.y2()) / 2)
}
}

View file

@ -0,0 +1,20 @@
use {
crate::{
it::test_error::TestResult,
tree::{ContainerNode, WorkspaceNode},
},
std::rc::Rc,
};
pub trait TestWorkspaceNodeExt {
fn container(&self) -> TestResult<Rc<ContainerNode>>;
}
impl TestWorkspaceNodeExt for WorkspaceNode {
fn container(&self) -> TestResult<Rc<ContainerNode>> {
match self.container.get() {
None => bail!("workspace does not have a container"),
Some(c) => Ok(c),
}
}
}

View file

@ -1,6 +1,7 @@
use {
crate::{
client::{ClientId, RequestParser},
fixed::Fixed,
ifs::wl_seat::WlSeatGlobal,
it::{
test_backend::{TestBackend, TestBackendKb, TestBackendMouse, TestConnector},
@ -146,3 +147,12 @@ pub struct DefaultSetup {
pub mouse: Rc<TestBackendMouse>,
pub seat: Rc<WlSeatGlobal>,
}
impl DefaultSetup {
pub fn move_to(&self, x: i32, y: i32) {
let (ox, oy) = self.seat.position();
let (nx, ny) = (Fixed::from_int(x), Fixed::from_int(y));
let (dx, dy) = (nx - ox, ny - oy);
self.mouse.rel(dx.to_f64(), dy.to_f64())
}
}

View file

@ -44,6 +44,7 @@ mod t0015_scroll_partial;
mod t0016_scroll_ws;
mod t0017_remove_unused_ws;
mod t0018_click_to_active_ws;
mod t0019_natural_scrolling;
pub trait TestCase: Sync {
fn name(&self) -> &'static str;
@ -80,5 +81,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
t0016_scroll_ws,
t0017_remove_unused_ws,
t0018_click_to_active_ws,
t0019_natural_scrolling,
}
}

View file

@ -0,0 +1,46 @@
use {
crate::{
ifs::wl_seat::wl_pointer::{IDENTICAL, INVERTED},
it::{
test_error::TestResult,
test_utils::{
test_container_node_ext::TestContainerExt, test_ouput_node_ext::TestOutputNodeExt,
test_toplevel_node_ext::TestToplevelNodeExt,
test_workspace_node_ext::TestWorkspaceNodeExt,
},
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.map2().await?;
let (x, y) = ds
.output
.workspace()?
.container()?
.first_toplevel()?
.center();
ds.move_to(x, y);
let seat = client.get_default_seat().await?;
let ard = seat.pointer.axis_relative_direction.expect()?;
ds.mouse.scroll_px2(1, false);
client.sync().await;
tassert_eq!(ard.next()?.direction, IDENTICAL);
ds.mouse.scroll_px2(1, true);
client.sync().await;
tassert_eq!(ard.next()?.direction, INVERTED);
Ok(())
}