it: test natural scrolling
This commit is contained in:
parent
f562f887f0
commit
adf6d2ae2b
12 changed files with 149 additions and 2 deletions
|
|
@ -319,13 +319,17 @@ impl TestBackendMouse {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_px(&self, dy: i32) {
|
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 {
|
self.common.event(InputEvent::AxisSource {
|
||||||
source: AxisSource::Finger,
|
source: AxisSource::Finger,
|
||||||
});
|
});
|
||||||
self.common.event(InputEvent::AxisPx {
|
self.common.event(InputEvent::AxisPx {
|
||||||
dist: Fixed::from_int(dy),
|
dist: Fixed::from_int(dy),
|
||||||
axis: ScrollAxis::Vertical,
|
axis: ScrollAxis::Vertical,
|
||||||
inverted: false,
|
inverted,
|
||||||
});
|
});
|
||||||
self.common.event(InputEvent::AxisFrame {
|
self.common.event(InputEvent::AxisFrame {
|
||||||
time_usec: now_usec(),
|
time_usec: now_usec(),
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ impl TestClient {
|
||||||
caps: Cell::new(0),
|
caps: Cell::new(0),
|
||||||
name: Default::default(),
|
name: Default::default(),
|
||||||
});
|
});
|
||||||
self.registry.bind(&tseat, seat.name().raw(), 7)?;
|
self.registry.bind(&tseat, seat.name().raw(), 9)?;
|
||||||
self.tran.sync().await;
|
self.tran.sync().await;
|
||||||
let server = self.tran.get_server_obj(tseat.id)?;
|
let server = self.tran.get_server_obj(tseat.id)?;
|
||||||
tseat.server.set(Some(server));
|
tseat.server.set(Some(server));
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ pub struct TestPointer {
|
||||||
pub leave: TEEH<Leave>,
|
pub leave: TEEH<Leave>,
|
||||||
pub enter: TEEH<Enter>,
|
pub enter: TEEH<Enter>,
|
||||||
pub motion: TEEH<Motion>,
|
pub motion: TEEH<Motion>,
|
||||||
|
pub axis_relative_direction: TEEH<AxisRelativeDirection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestPointer {
|
impl TestPointer {
|
||||||
|
|
@ -76,6 +77,12 @@ impl TestPointer {
|
||||||
let _ev = AxisDiscrete::parse_full(parser)?;
|
let _ev = AxisDiscrete::parse_full(parser)?;
|
||||||
Ok(())
|
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 {
|
impl Drop for TestPointer {
|
||||||
|
|
@ -96,6 +103,7 @@ test_object! {
|
||||||
AXIS_SOURCE => handle_axis_source,
|
AXIS_SOURCE => handle_axis_source,
|
||||||
AXIS_STOP => handle_axis_stop,
|
AXIS_STOP => handle_axis_stop,
|
||||||
AXIS_DISCRETE => handle_axis_discrete,
|
AXIS_DISCRETE => handle_axis_discrete,
|
||||||
|
AXIS_RELATIVE_DIRECTION => handle_axis_relative_direction,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestObject for TestPointer {}
|
impl TestObject for TestPointer {}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ impl TestSeat {
|
||||||
leave: Rc::new(Default::default()),
|
leave: Rc::new(Default::default()),
|
||||||
enter: Rc::new(Default::default()),
|
enter: Rc::new(Default::default()),
|
||||||
motion: Rc::new(Default::default()),
|
motion: Rc::new(Default::default()),
|
||||||
|
axis_relative_direction: Rc::new(Default::default()),
|
||||||
});
|
});
|
||||||
self.tran.add_obj(pointer.clone())?;
|
self.tran.add_obj(pointer.clone())?;
|
||||||
self.tran.sync().await;
|
self.tran.sync().await;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
pub mod test_container_node_ext;
|
||||||
pub mod test_expected_event;
|
pub mod test_expected_event;
|
||||||
pub mod test_object_ext;
|
pub mod test_object_ext;
|
||||||
|
pub mod test_ouput_node_ext;
|
||||||
|
pub mod test_toplevel_node_ext;
|
||||||
pub mod test_window;
|
pub mod test_window;
|
||||||
|
pub mod test_workspace_node_ext;
|
||||||
|
|
|
||||||
20
src/it/test_utils/test_container_node_ext.rs
Normal file
20
src/it/test_utils/test_container_node_ext.rs
Normal 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()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/it/test_utils/test_ouput_node_ext.rs
Normal file
20
src/it/test_utils/test_ouput_node_ext.rs
Normal 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/it/test_utils/test_toplevel_node_ext.rs
Normal file
12
src/it/test_utils/test_toplevel_node_ext.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/it/test_utils/test_workspace_node_ext.rs
Normal file
20
src/it/test_utils/test_workspace_node_ext.rs
Normal 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
client::{ClientId, RequestParser},
|
client::{ClientId, RequestParser},
|
||||||
|
fixed::Fixed,
|
||||||
ifs::wl_seat::WlSeatGlobal,
|
ifs::wl_seat::WlSeatGlobal,
|
||||||
it::{
|
it::{
|
||||||
test_backend::{TestBackend, TestBackendKb, TestBackendMouse, TestConnector},
|
test_backend::{TestBackend, TestBackendKb, TestBackendMouse, TestConnector},
|
||||||
|
|
@ -146,3 +147,12 @@ pub struct DefaultSetup {
|
||||||
pub mouse: Rc<TestBackendMouse>,
|
pub mouse: Rc<TestBackendMouse>,
|
||||||
pub seat: Rc<WlSeatGlobal>,
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ mod t0015_scroll_partial;
|
||||||
mod t0016_scroll_ws;
|
mod t0016_scroll_ws;
|
||||||
mod t0017_remove_unused_ws;
|
mod t0017_remove_unused_ws;
|
||||||
mod t0018_click_to_active_ws;
|
mod t0018_click_to_active_ws;
|
||||||
|
mod t0019_natural_scrolling;
|
||||||
|
|
||||||
pub trait TestCase: Sync {
|
pub trait TestCase: Sync {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
@ -80,5 +81,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
||||||
t0016_scroll_ws,
|
t0016_scroll_ws,
|
||||||
t0017_remove_unused_ws,
|
t0017_remove_unused_ws,
|
||||||
t0018_click_to_active_ws,
|
t0018_click_to_active_ws,
|
||||||
|
t0019_natural_scrolling,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
src/it/tests/t0019_natural_scrolling.rs
Normal file
46
src/it/tests/t0019_natural_scrolling.rs
Normal 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(())
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue