it: test dnd focus change on drop
This commit is contained in:
parent
a39031d4f9
commit
c6b34550d8
16 changed files with 421 additions and 9 deletions
|
|
@ -6,10 +6,10 @@ use {
|
||||||
it::{
|
it::{
|
||||||
test_error::{TestError, TestResult},
|
test_error::{TestError, TestResult},
|
||||||
test_ifs::{
|
test_ifs::{
|
||||||
test_compositor::TestCompositor, test_jay_compositor::TestJayCompositor,
|
test_compositor::TestCompositor, test_data_device_manager::TestDataDeviceManager,
|
||||||
test_keyboard::TestKeyboard, test_pointer::TestPointer,
|
test_jay_compositor::TestJayCompositor, test_keyboard::TestKeyboard,
|
||||||
test_registry::TestRegistry, test_seat::TestSeat, test_shm::TestShm,
|
test_pointer::TestPointer, test_registry::TestRegistry, test_seat::TestSeat,
|
||||||
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
test_shm::TestShm, test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
||||||
test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter,
|
test_subcompositor::TestSubcompositor, test_viewporter::TestViewporter,
|
||||||
test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase,
|
test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase,
|
||||||
},
|
},
|
||||||
|
|
@ -35,6 +35,7 @@ pub struct TestClient {
|
||||||
pub viewporter: Rc<TestViewporter>,
|
pub viewporter: Rc<TestViewporter>,
|
||||||
pub xdg: Rc<TestXdgWmBase>,
|
pub xdg: Rc<TestXdgWmBase>,
|
||||||
pub activation: Rc<TestXdgActivation>,
|
pub activation: Rc<TestXdgActivation>,
|
||||||
|
pub data_device_manager: Rc<TestDataDeviceManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultSeat {
|
pub struct DefaultSeat {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
mod test_buffer;
|
mod test_buffer;
|
||||||
pub mod test_callback;
|
pub mod test_callback;
|
||||||
pub mod test_compositor;
|
pub mod test_compositor;
|
||||||
|
pub mod test_data_device;
|
||||||
|
pub mod test_data_device_manager;
|
||||||
|
pub mod test_data_offer;
|
||||||
|
pub mod test_data_source;
|
||||||
pub mod test_display;
|
pub mod test_display;
|
||||||
pub mod test_ext_foreign_toplevel_handle;
|
pub mod test_ext_foreign_toplevel_handle;
|
||||||
pub mod test_ext_foreign_toplevel_list;
|
pub mod test_ext_foreign_toplevel_list;
|
||||||
|
|
|
||||||
115
src/it/test_ifs/test_data_device.rs
Normal file
115
src/it/test_ifs/test_data_device.rs
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
it::{
|
||||||
|
test_error::TestResult,
|
||||||
|
test_ifs::{
|
||||||
|
test_data_offer::TestDataOffer, test_data_source::TestDataSource,
|
||||||
|
test_surface::TestSurface,
|
||||||
|
},
|
||||||
|
test_object::TestObject,
|
||||||
|
test_transport::TestTransport,
|
||||||
|
testrun::ParseFull,
|
||||||
|
},
|
||||||
|
utils::buffd::MsgParser,
|
||||||
|
wire::{wl_data_device::*, WlDataDeviceId, WlSurfaceId},
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestDataDevice {
|
||||||
|
pub id: WlDataDeviceId,
|
||||||
|
pub tran: Rc<TestTransport>,
|
||||||
|
pub destroyed: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestDataDevice {
|
||||||
|
pub fn destroy(&self) -> TestResult {
|
||||||
|
if !self.destroyed.replace(true) {
|
||||||
|
self.tran.send(Release { self_id: self.id })?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_drag(
|
||||||
|
&self,
|
||||||
|
source: &TestDataSource,
|
||||||
|
origin: &TestSurface,
|
||||||
|
icon: Option<&TestSurface>,
|
||||||
|
serial: u32,
|
||||||
|
) -> TestResult {
|
||||||
|
self.tran.send(StartDrag {
|
||||||
|
self_id: self.id,
|
||||||
|
source: source.id,
|
||||||
|
origin: origin.id,
|
||||||
|
icon: icon.map(|i| i.id).unwrap_or(WlSurfaceId::NONE),
|
||||||
|
serial,
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn set_selection(&self, source: &TestDataSource, serial: u32) -> TestResult {
|
||||||
|
self.tran.send(SetSelection {
|
||||||
|
self_id: self.id,
|
||||||
|
source: source.id,
|
||||||
|
serial,
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_data_offer(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let ev = DataOffer::parse_full(parser)?;
|
||||||
|
let offer = Rc::new(TestDataOffer {
|
||||||
|
id: ev.id,
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
destroyed: Cell::new(false),
|
||||||
|
});
|
||||||
|
self.tran.add_obj(offer.clone())?;
|
||||||
|
offer.destroy()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_enter(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Enter::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_leave(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Leave::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_motion(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Motion::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_drop(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Drop::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_selection(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Selection::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Drop for TestDataDevice {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_object! {
|
||||||
|
TestDataDevice, WlDataDevice;
|
||||||
|
|
||||||
|
DATA_OFFER => handle_data_offer,
|
||||||
|
ENTER => handle_enter,
|
||||||
|
LEAVE => handle_leave,
|
||||||
|
MOTION => handle_motion,
|
||||||
|
DROP => handle_drop,
|
||||||
|
SELECTION => handle_selection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObject for TestDataDevice {}
|
||||||
57
src/it/test_ifs/test_data_device_manager.rs
Normal file
57
src/it/test_ifs/test_data_device_manager.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
it::{
|
||||||
|
test_error::TestResult,
|
||||||
|
test_ifs::{
|
||||||
|
test_data_device::TestDataDevice, test_data_source::TestDataSource,
|
||||||
|
test_seat::TestSeat,
|
||||||
|
},
|
||||||
|
test_object::TestObject,
|
||||||
|
test_transport::TestTransport,
|
||||||
|
},
|
||||||
|
wire::{wl_data_device_manager::*, WlDataDeviceManagerId},
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestDataDeviceManager {
|
||||||
|
pub id: WlDataDeviceManagerId,
|
||||||
|
pub tran: Rc<TestTransport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestDataDeviceManager {
|
||||||
|
pub fn create_data_source(&self) -> TestResult<Rc<TestDataSource>> {
|
||||||
|
let data_source = Rc::new(TestDataSource {
|
||||||
|
id: self.tran.id(),
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
destroyed: Cell::new(false),
|
||||||
|
});
|
||||||
|
self.tran.add_obj(data_source.clone())?;
|
||||||
|
self.tran.send(CreateDataSource {
|
||||||
|
self_id: self.id,
|
||||||
|
id: data_source.id,
|
||||||
|
})?;
|
||||||
|
Ok(data_source)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_data_device(&self, seat: &TestSeat) -> TestResult<Rc<TestDataDevice>> {
|
||||||
|
let data_device = Rc::new(TestDataDevice {
|
||||||
|
id: self.tran.id(),
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
destroyed: Cell::new(false),
|
||||||
|
});
|
||||||
|
self.tran.add_obj(data_device.clone())?;
|
||||||
|
self.tran.send(GetDataDevice {
|
||||||
|
self_id: self.id,
|
||||||
|
id: data_device.id,
|
||||||
|
seat: seat.id,
|
||||||
|
})?;
|
||||||
|
Ok(data_device)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_object! {
|
||||||
|
TestDataDeviceManager, WlDataDeviceManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObject for TestDataDeviceManager {}
|
||||||
57
src/it/test_ifs/test_data_offer.rs
Normal file
57
src/it/test_ifs/test_data_offer.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
it::{
|
||||||
|
test_error::TestResult, test_object::TestObject, test_transport::TestTransport,
|
||||||
|
testrun::ParseFull,
|
||||||
|
},
|
||||||
|
utils::buffd::MsgParser,
|
||||||
|
wire::{wl_data_offer::*, WlDataOfferId},
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestDataOffer {
|
||||||
|
pub id: WlDataOfferId,
|
||||||
|
pub tran: Rc<TestTransport>,
|
||||||
|
pub destroyed: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestDataOffer {
|
||||||
|
pub fn destroy(&self) -> TestResult {
|
||||||
|
if !self.destroyed.replace(true) {
|
||||||
|
self.tran.send(Destroy { self_id: self.id })?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_offer(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Offer::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_source_actions(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = SourceActions::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_action(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Action::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TestDataOffer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_object! {
|
||||||
|
TestDataOffer, WlDataOffer;
|
||||||
|
|
||||||
|
OFFER => handle_offer,
|
||||||
|
SOURCE_ACTIONS => handle_source_actions,
|
||||||
|
ACTION => handle_action,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObject for TestDataOffer {}
|
||||||
93
src/it/test_ifs/test_data_source.rs
Normal file
93
src/it/test_ifs/test_data_source.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
it::{
|
||||||
|
test_error::TestResult, test_object::TestObject, test_transport::TestTransport,
|
||||||
|
testrun::ParseFull,
|
||||||
|
},
|
||||||
|
utils::buffd::MsgParser,
|
||||||
|
wire::{wl_data_source::*, WlDataSourceId},
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TestDataSource {
|
||||||
|
pub id: WlDataSourceId,
|
||||||
|
pub tran: Rc<TestTransport>,
|
||||||
|
pub destroyed: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestDataSource {
|
||||||
|
pub fn destroy(&self) -> TestResult {
|
||||||
|
if !self.destroyed.replace(true) {
|
||||||
|
self.tran.send(Destroy { self_id: self.id })?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn offer(&self, mime_type: &str) -> TestResult {
|
||||||
|
self.tran.send(Offer {
|
||||||
|
self_id: self.id,
|
||||||
|
mime_type,
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn set_actions(&self, actions: u32) -> TestResult {
|
||||||
|
self.tran.send(SetActions {
|
||||||
|
self_id: self.id,
|
||||||
|
dnd_actions: actions,
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_target(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Target::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_send(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Send::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_cancelled(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Cancelled::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_dnd_drop_performed(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = DndDropPerformed::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_dnd_finished(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = DndFinished::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_action(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
|
let _ev = Action::parse_full(parser)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TestDataSource {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = self.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_object! {
|
||||||
|
TestDataSource, WlDataSource;
|
||||||
|
|
||||||
|
TARGET => handle_target,
|
||||||
|
SEND => handle_send,
|
||||||
|
CANCELLED => handle_cancelled,
|
||||||
|
DND_DROP_PERFORMED => handle_dnd_drop_performed,
|
||||||
|
DND_FINISHED => handle_dnd_finished,
|
||||||
|
ACTION => handle_action,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestObject for TestDataSource {}
|
||||||
|
|
@ -20,6 +20,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 button: TEEH<Button>,
|
||||||
pub axis_relative_direction: TEEH<AxisRelativeDirection>,
|
pub axis_relative_direction: TEEH<AxisRelativeDirection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,7 +68,8 @@ impl TestPointer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_button(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
fn handle_button(&self, parser: MsgParser<'_, '_>) -> TestResult {
|
||||||
let _ev = Button::parse_full(parser)?;
|
let ev = Button::parse_full(parser)?;
|
||||||
|
self.button.push(ev);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use {
|
||||||
it::{
|
it::{
|
||||||
test_error::TestError,
|
test_error::TestError,
|
||||||
test_ifs::{
|
test_ifs::{
|
||||||
test_compositor::TestCompositor,
|
test_compositor::TestCompositor, test_data_device_manager::TestDataDeviceManager,
|
||||||
test_ext_foreign_toplevel_list::TestExtForeignToplevelList,
|
test_ext_foreign_toplevel_list::TestExtForeignToplevelList,
|
||||||
test_jay_compositor::TestJayCompositor, test_shm::TestShm,
|
test_jay_compositor::TestJayCompositor, test_shm::TestShm,
|
||||||
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
|
||||||
|
|
@ -41,6 +41,7 @@ pub struct TestRegistrySingletons {
|
||||||
pub wp_viewporter: u32,
|
pub wp_viewporter: u32,
|
||||||
pub xdg_activation_v1: u32,
|
pub xdg_activation_v1: u32,
|
||||||
pub ext_foreign_toplevel_list_v1: u32,
|
pub ext_foreign_toplevel_list_v1: u32,
|
||||||
|
pub wl_data_device_manager: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestRegistry {
|
pub struct TestRegistry {
|
||||||
|
|
@ -57,6 +58,7 @@ pub struct TestRegistry {
|
||||||
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
pub xdg: CloneCell<Option<Rc<TestXdgWmBase>>>,
|
||||||
pub activation: CloneCell<Option<Rc<TestXdgActivation>>>,
|
pub activation: CloneCell<Option<Rc<TestXdgActivation>>>,
|
||||||
pub foreign_toplevel_list: CloneCell<Option<Rc<TestExtForeignToplevelList>>>,
|
pub foreign_toplevel_list: CloneCell<Option<Rc<TestExtForeignToplevelList>>>,
|
||||||
|
pub data_device_manager: CloneCell<Option<Rc<TestDataDeviceManager>>>,
|
||||||
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,6 +110,7 @@ impl TestRegistry {
|
||||||
wp_viewporter,
|
wp_viewporter,
|
||||||
xdg_activation_v1,
|
xdg_activation_v1,
|
||||||
ext_foreign_toplevel_list_v1,
|
ext_foreign_toplevel_list_v1,
|
||||||
|
wl_data_device_manager,
|
||||||
};
|
};
|
||||||
self.singletons.set(Some(singletons.clone()));
|
self.singletons.set(Some(singletons.clone()));
|
||||||
Ok(singletons)
|
Ok(singletons)
|
||||||
|
|
@ -240,6 +243,19 @@ impl TestRegistry {
|
||||||
Ok(jc)
|
Ok(jc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_data_device_manager(&self) -> Result<Rc<TestDataDeviceManager>, TestError> {
|
||||||
|
singleton!(self.data_device_manager);
|
||||||
|
let singletons = self.get_singletons().await?;
|
||||||
|
singleton!(self.data_device_manager);
|
||||||
|
let jc = Rc::new(TestDataDeviceManager {
|
||||||
|
id: self.tran.id(),
|
||||||
|
tran: self.tran.clone(),
|
||||||
|
});
|
||||||
|
self.bind(&jc, singletons.wl_data_device_manager, 3)?;
|
||||||
|
self.data_device_manager.set(Some(jc.clone()));
|
||||||
|
Ok(jc)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bind<O: TestObject>(
|
pub fn bind<O: TestObject>(
|
||||||
&self,
|
&self,
|
||||||
obj: &Rc<O>,
|
obj: &Rc<O>,
|
||||||
|
|
|
||||||
|
|
@ -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()),
|
||||||
|
button: Rc::new(Default::default()),
|
||||||
axis_relative_direction: Rc::new(Default::default()),
|
axis_relative_direction: Rc::new(Default::default()),
|
||||||
});
|
});
|
||||||
self.tran.add_obj(pointer.clone())?;
|
self.tran.add_obj(pointer.clone())?;
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ impl TestTransport {
|
||||||
xdg: Default::default(),
|
xdg: Default::default(),
|
||||||
activation: Default::default(),
|
activation: Default::default(),
|
||||||
foreign_toplevel_list: Default::default(),
|
foreign_toplevel_list: Default::default(),
|
||||||
|
data_device_manager: Default::default(),
|
||||||
seats: Default::default(),
|
seats: Default::default(),
|
||||||
});
|
});
|
||||||
self.send(wl_display::GetRegistry {
|
self.send(wl_display::GetRegistry {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,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_ouput_node_ext;
|
||||||
|
pub mod test_rect_ext;
|
||||||
pub mod test_toplevel_node_ext;
|
pub mod test_toplevel_node_ext;
|
||||||
pub mod test_window;
|
pub mod test_window;
|
||||||
pub mod test_workspace_node_ext;
|
pub mod test_workspace_node_ext;
|
||||||
|
|
|
||||||
11
src/it/test_utils/test_rect_ext.rs
Normal file
11
src/it/test_utils/test_rect_ext.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
use crate::rect::Rect;
|
||||||
|
|
||||||
|
pub trait TestRectExt {
|
||||||
|
fn center(&self) -> (i32, i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestRectExt for Rect {
|
||||||
|
fn center(&self) -> (i32, i32) {
|
||||||
|
((self.x1() + self.x2()) / 2, (self.y1() + self.y2()) / 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::tree::ToplevelNode;
|
use crate::{it::test_utils::test_rect_ext::TestRectExt, tree::ToplevelNode};
|
||||||
|
|
||||||
pub trait TestToplevelNodeExt {
|
pub trait TestToplevelNodeExt {
|
||||||
fn center(&self) -> (i32, i32);
|
fn center(&self) -> (i32, i32);
|
||||||
|
|
@ -6,7 +6,6 @@ pub trait TestToplevelNodeExt {
|
||||||
|
|
||||||
impl TestToplevelNodeExt for dyn ToplevelNode {
|
impl TestToplevelNodeExt for dyn ToplevelNode {
|
||||||
fn center(&self) -> (i32, i32) {
|
fn center(&self) -> (i32, i32) {
|
||||||
let rect = self.node_absolute_position();
|
self.node_absolute_position().center()
|
||||||
((rect.x1() + rect.x2()) / 2, (rect.y1() + rect.y2()) / 2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ impl TestRun {
|
||||||
viewporter: registry.get_viewporter().await?,
|
viewporter: registry.get_viewporter().await?,
|
||||||
xdg: registry.get_xdg().await?,
|
xdg: registry.get_xdg().await?,
|
||||||
activation: registry.get_activation().await?,
|
activation: registry.get_activation().await?,
|
||||||
|
data_device_manager: registry.get_data_device_manager().await?,
|
||||||
registry,
|
registry,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ mod t0021_preferred_buffer_scale;
|
||||||
mod t0022_toplevel_suspended;
|
mod t0022_toplevel_suspended;
|
||||||
mod t0023_xdg_activation;
|
mod t0023_xdg_activation;
|
||||||
mod t0024_foreign_toplevel_list;
|
mod t0024_foreign_toplevel_list;
|
||||||
|
mod t0025_dnd_focus_change;
|
||||||
|
|
||||||
pub trait TestCase: Sync {
|
pub trait TestCase: Sync {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
@ -98,5 +99,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
||||||
t0022_toplevel_suspended,
|
t0022_toplevel_suspended,
|
||||||
t0023_xdg_activation,
|
t0023_xdg_activation,
|
||||||
t0024_foreign_toplevel_list,
|
t0024_foreign_toplevel_list,
|
||||||
|
t0025_dnd_focus_change,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
src/it/tests/t0025_dnd_focus_change.rs
Normal file
51
src/it/tests/t0025_dnd_focus_change.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
ifs::wl_seat::BTN_LEFT,
|
||||||
|
it::{test_error::TestResult, test_utils::test_rect_ext::TestRectExt, testrun::TestRun},
|
||||||
|
tree::Node,
|
||||||
|
},
|
||||||
|
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 win2 = client.create_window().await?;
|
||||||
|
win2.map2().await?;
|
||||||
|
|
||||||
|
let seat = client.get_default_seat().await?;
|
||||||
|
let button = seat.pointer.button.expect()?;
|
||||||
|
|
||||||
|
let (x, y) = win1.tl.server.node_absolute_position().center();
|
||||||
|
ds.move_to(x, y);
|
||||||
|
let click = ds.mouse.click(BTN_LEFT);
|
||||||
|
|
||||||
|
client.sync().await;
|
||||||
|
let dev = client.data_device_manager.get_data_device(&seat.seat)?;
|
||||||
|
let src = client.data_device_manager.create_data_source()?;
|
||||||
|
src.set_actions(1)?;
|
||||||
|
dev.start_drag(&src, &win1.surface, None, button.next()?.serial)?;
|
||||||
|
|
||||||
|
client.sync().await;
|
||||||
|
let enter = seat.pointer.enter.expect()?;
|
||||||
|
|
||||||
|
let (x, y) = win2.tl.server.node_absolute_position().center();
|
||||||
|
ds.move_to(x, y);
|
||||||
|
|
||||||
|
client.sync().await;
|
||||||
|
tassert!(enter.next().is_err());
|
||||||
|
|
||||||
|
drop(click);
|
||||||
|
|
||||||
|
client.sync().await;
|
||||||
|
client.sync().await;
|
||||||
|
tassert_eq!(enter.next()?.surface, win2.surface.id);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue