tree: focus container mono child after scroll
This commit is contained in:
parent
3abd72b330
commit
fca7c7e1d2
9 changed files with 140 additions and 9 deletions
|
|
@ -769,7 +769,7 @@ impl Node for WlSurface {
|
|||
seat.button_surface(&self, button, state, serial);
|
||||
}
|
||||
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) {
|
||||
seat.scroll_surface(&*self, event);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ use {
|
|||
crate::{
|
||||
async_engine::SpawnedFuture,
|
||||
backend::{
|
||||
Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId,
|
||||
InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent,
|
||||
KeyState, Mode, MonitorInfo, TransformMatrix,
|
||||
AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId,
|
||||
ConnectorKernelId, InputDevice, InputDeviceAccelProfile, InputDeviceCapability,
|
||||
InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, ScrollAxis, TransformMatrix,
|
||||
},
|
||||
compositor::TestFuture,
|
||||
fixed::Fixed,
|
||||
|
|
@ -275,6 +275,14 @@ impl TestBackendMouse {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn abs(&self, connector: &TestConnector, x: f64, y: f64) {
|
||||
self.common.event(InputEvent::ConnectorPosition {
|
||||
0: connector.id,
|
||||
1: Fixed::from_f64(x),
|
||||
2: Fixed::from_f64(y),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn click(self: &Rc<Self>, button: u32) -> TestMouseClick {
|
||||
self.common
|
||||
.event(InputEvent::Button(button, KeyState::Pressed));
|
||||
|
|
@ -283,6 +291,17 @@ impl TestBackendMouse {
|
|||
button,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll(&self, dy: i32) {
|
||||
self.common.event(InputEvent::AxisSource(AxisSource::Wheel));
|
||||
self.common
|
||||
.event(InputEvent::AxisDiscrete(dy, ScrollAxis::Vertical));
|
||||
self.common.event(InputEvent::Axis(
|
||||
Fixed::from_int(dy * 15),
|
||||
ScrollAxis::Vertical,
|
||||
));
|
||||
self.common.event(InputEvent::Frame);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestBackendKb {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use {
|
|||
},
|
||||
input::{InputDevice, Seat},
|
||||
keyboard::{keymap::Keymap, ModifiedKeySym},
|
||||
Direction,
|
||||
Axis, Direction,
|
||||
},
|
||||
std::{cell::Cell, ops::Deref, ptr, rc::Rc},
|
||||
};
|
||||
|
|
@ -191,6 +191,20 @@ impl TestConfig {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn create_split(&self, seat: SeatId, axis: Axis) -> TestResult {
|
||||
self.send(ClientMessage::CreateSplit {
|
||||
seat: Seat(seat.raw() as _),
|
||||
axis,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_mono(&self, seat: SeatId, mono: bool) -> TestResult {
|
||||
self.send(ClientMessage::SetMono {
|
||||
seat: Seat(seat.raw() as _),
|
||||
mono,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_shortcut<T: Into<ModifiedKeySym>>(
|
||||
&self,
|
||||
seat: SeatId,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@ use {
|
|||
crate::{
|
||||
ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel,
|
||||
it::{
|
||||
test_error::TestError, test_object::TestObject, test_transport::TestTransport,
|
||||
test_error::{TestError, TestResult},
|
||||
test_object::TestObject,
|
||||
test_transport::TestTransport,
|
||||
testrun::ParseFull,
|
||||
},
|
||||
tree::{ContainerNode, ToplevelNode},
|
||||
utils::buffd::MsgParser,
|
||||
wire::{xdg_toplevel::*, XdgToplevelId},
|
||||
},
|
||||
|
|
@ -36,6 +39,17 @@ impl TestXdgToplevel {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn container_parent(&self) -> TestResult<Rc<ContainerNode>> {
|
||||
let parent = match self.server.tl_data().parent.get() {
|
||||
Some(p) => p,
|
||||
_ => bail!("toplevel has no parent"),
|
||||
};
|
||||
match parent.node_into_container() {
|
||||
Some(p) => Ok(p),
|
||||
_ => bail!("toplevel parent is not a container"),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
|
||||
let ev = Configure::parse_full(parser)?;
|
||||
self.width.set(ev.width);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use {
|
|||
crate::{
|
||||
format::ARGB8888,
|
||||
it::{
|
||||
test_error::TestError,
|
||||
test_error::{TestError, TestResult},
|
||||
test_ifs::{
|
||||
test_shm_buffer::TestShmBuffer, test_shm_pool::TestShmPool,
|
||||
test_surface::TestSurface, test_xdg_surface::TestXdgSurface,
|
||||
|
|
@ -41,6 +41,11 @@ impl TestWindow {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn map2(&self) -> TestResult {
|
||||
self.map().await?;
|
||||
self.map().await
|
||||
}
|
||||
|
||||
#[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));
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ mod t0010_fullscreen_focus;
|
|||
mod t0011_set_keymap;
|
||||
mod t0012_subsurface_focus;
|
||||
mod t0013_graphics_initialized;
|
||||
mod t0014_container_scroll_focus;
|
||||
|
||||
pub trait TestCase: Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
|
|
@ -70,5 +71,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
|||
t0011_set_keymap,
|
||||
t0012_subsurface_focus,
|
||||
t0013_graphics_initialized,
|
||||
t0014_container_scroll_focus,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
72
src/it/tests/t0014_container_scroll_focus.rs
Normal file
72
src/it/tests/t0014_container_scroll_focus.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
use {
|
||||
crate::{
|
||||
it::{
|
||||
test_error::{TestErrorExt, TestResult},
|
||||
testrun::TestRun,
|
||||
},
|
||||
tree::ToplevelNode,
|
||||
},
|
||||
jay_config::Axis,
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
testcase!();
|
||||
|
||||
/// Test that scrolling a mono container header activates the new window
|
||||
async fn test(run: Rc<TestRun>) -> TestResult {
|
||||
let ds = run.create_default_setup().await?;
|
||||
ds.mouse.rel(1.0, 1.0);
|
||||
|
||||
let client = run.create_client().await?;
|
||||
let dss = client.get_default_seat().await?;
|
||||
|
||||
let w_tiled = client.create_window().await?;
|
||||
w_tiled.map2().await?;
|
||||
let w_mono1 = client.create_window().await?;
|
||||
w_mono1.map2().await?;
|
||||
|
||||
run.cfg.create_split(ds.seat.id(), Axis::Horizontal)?;
|
||||
run.cfg.set_mono(ds.seat.id(), true)?;
|
||||
|
||||
let w_mono2 = client.create_window().await?;
|
||||
w_mono2.map2().await?;
|
||||
|
||||
// current state:
|
||||
// | w_tiled | [ w_mono1 | w_mono2 ] | with w_mono2 visible and active
|
||||
|
||||
client.sync().await;
|
||||
tassert_eq!(w_tiled.tl.width.get(), w_mono2.tl.width.get());
|
||||
|
||||
let enters = dss.kb.enter.expect()?;
|
||||
|
||||
ds.mouse.abs(&ds.connector, 0.0, 0.0);
|
||||
ds.mouse.abs(&ds.connector, 10.0, 500.0);
|
||||
client.sync().await;
|
||||
|
||||
let enter = enters.next().with_context(|| "no enter event")?;
|
||||
tassert_eq!(enter.surface, w_tiled.surface.id);
|
||||
|
||||
let mono_container = w_mono2.tl.container_parent()?;
|
||||
let container_pos = mono_container.tl_data().pos.get();
|
||||
log::info!("cp {:?}", container_pos);
|
||||
let w_mono1_title = mono_container.render_data.borrow_mut().title_rects[0]
|
||||
.move_(container_pos.x1(), container_pos.y1());
|
||||
ds.mouse.abs(
|
||||
&ds.connector,
|
||||
w_mono1_title.x1() as _,
|
||||
w_mono1_title.y1() as _,
|
||||
);
|
||||
|
||||
client.sync().await;
|
||||
tassert!(enters.next().is_err());
|
||||
|
||||
ds.mouse.scroll(-1);
|
||||
client.sync().await;
|
||||
|
||||
client.save_screenshot("s2").await?;
|
||||
|
||||
let enter = enters.next().with_context(|| "no enter event 2")?;
|
||||
tassert_eq!(enter.surface, w_mono1.surface.id);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ pub trait Node: 'static {
|
|||
let _ = serial;
|
||||
}
|
||||
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) {
|
||||
let _ = seat;
|
||||
let _ = event;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1141,7 +1141,7 @@ impl Node for ContainerNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) {
|
||||
let mut seat_datas = self.seats.borrow_mut();
|
||||
let seat_data = match seat_datas.get_mut(&seat.id()) {
|
||||
Some(s) => s,
|
||||
|
|
@ -1176,6 +1176,10 @@ impl Node for ContainerNode {
|
|||
};
|
||||
}
|
||||
self.activate_child(&new_mc);
|
||||
new_mc
|
||||
.node
|
||||
.clone()
|
||||
.node_do_focus(seat, Direction::Unspecified);
|
||||
}
|
||||
|
||||
fn node_on_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
|
|
@ -1347,6 +1351,7 @@ impl ToplevelNode for ContainerNode {
|
|||
}
|
||||
|
||||
fn tl_change_extents(self: Rc<Self>, rect: &Rect) {
|
||||
self.toplevel_data.pos.set(*rect);
|
||||
self.abs_x1.set(rect.x1());
|
||||
self.abs_y1.set(rect.y1());
|
||||
let mut size_changed = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue