atspi_common/events/
mouse.rs

1use crate::{
2	error::AtspiError,
3	events::{Accessible, EventBodyOwned, GenericEvent, HasMatchRule, HasRegistryEventString},
4	Event,
5};
6use zvariant::ObjectPath;
7
8#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
9pub enum MouseEvents {
10	/// See: [`AbsEvent`].
11	Abs(AbsEvent),
12	/// See: [`RelEvent`].
13	Rel(RelEvent),
14	/// See: [`ButtonEvent`].
15	Button(ButtonEvent),
16}
17
18impl_from_interface_event_enum_for_event!(MouseEvents, Event::Mouse);
19impl_try_from_event_for_user_facing_event_type!(MouseEvents, Event::Mouse);
20
21event_wrapper_test_cases!(MouseEvents, AbsEvent);
22
23impl HasMatchRule for MouseEvents {
24	const MATCH_RULE_STRING: &'static str = "type='signal',interface='org.a11y.atspi.Event.Mouse'";
25}
26
27#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
28pub struct AbsEvent {
29	/// The [`Accessible`] which the event applies to.
30	pub item: crate::events::Accessible,
31	pub x: i32,
32	pub y: i32,
33}
34
35#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
36pub struct RelEvent {
37	/// The [`Accessible`] which the event applies to.
38	pub item: crate::events::Accessible,
39	pub x: i32,
40	pub y: i32,
41}
42
43#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
44pub struct ButtonEvent {
45	/// The [`Accessible`] which the event applies to.
46	pub item: crate::events::Accessible,
47	pub detail: String,
48	pub mouse_x: i32,
49	pub mouse_y: i32,
50}
51
52impl GenericEvent<'_> for AbsEvent {
53	const DBUS_MEMBER: &'static str = "Abs";
54	const DBUS_INTERFACE: &'static str = "org.a11y.atspi.Event.Mouse";
55	const MATCH_RULE_STRING: &'static str =
56		"type='signal',interface='org.a11y.atspi.Event.Mouse',member='Abs'";
57	const REGISTRY_EVENT_STRING: &'static str = "Mouse:";
58
59	type Body = EventBodyOwned;
60
61	fn build(item: Accessible, body: Self::Body) -> Result<Self, AtspiError> {
62		Ok(Self { item, x: body.detail1, y: body.detail2 })
63	}
64	fn sender(&self) -> String {
65		self.item.name.clone()
66	}
67	fn path<'a>(&self) -> ObjectPath<'_> {
68		self.item.path.clone().into()
69	}
70	fn body(&self) -> Self::Body {
71		let copy = self.clone();
72		copy.into()
73	}
74}
75
76impl GenericEvent<'_> for RelEvent {
77	const DBUS_MEMBER: &'static str = "Rel";
78	const DBUS_INTERFACE: &'static str = "org.a11y.atspi.Event.Mouse";
79	const MATCH_RULE_STRING: &'static str =
80		"type='signal',interface='org.a11y.atspi.Event.Mouse',member='Rel'";
81	const REGISTRY_EVENT_STRING: &'static str = "Mouse:";
82
83	type Body = EventBodyOwned;
84
85	fn build(item: Accessible, body: Self::Body) -> Result<Self, AtspiError> {
86		Ok(Self { item, x: body.detail1, y: body.detail2 })
87	}
88	fn sender(&self) -> String {
89		self.item.name.clone()
90	}
91	fn path<'a>(&self) -> ObjectPath<'_> {
92		self.item.path.clone().into()
93	}
94	fn body(&self) -> Self::Body {
95		let copy = self.clone();
96		copy.into()
97	}
98}
99
100impl GenericEvent<'_> for ButtonEvent {
101	const DBUS_MEMBER: &'static str = "Button";
102	const DBUS_INTERFACE: &'static str = "org.a11y.atspi.Event.Mouse";
103	const MATCH_RULE_STRING: &'static str =
104		"type='signal',interface='org.a11y.atspi.Event.Mouse',member='Button'";
105	const REGISTRY_EVENT_STRING: &'static str = "Mouse:";
106
107	type Body = EventBodyOwned;
108
109	fn build(item: Accessible, body: Self::Body) -> Result<Self, AtspiError> {
110		Ok(Self { item, detail: body.kind, mouse_x: body.detail1, mouse_y: body.detail2 })
111	}
112	fn sender(&self) -> String {
113		self.item.name.clone()
114	}
115	fn path<'a>(&self) -> ObjectPath<'_> {
116		self.item.path.clone().into()
117	}
118	fn body(&self) -> Self::Body {
119		let copy = self.clone();
120		copy.into()
121	}
122}
123
124#[cfg(feature = "zbus")]
125impl TryFrom<&zbus::Message> for MouseEvents {
126	type Error = AtspiError;
127	fn try_from(ev: &zbus::Message) -> Result<Self, Self::Error> {
128		let member = ev
129			.member()
130			.ok_or(AtspiError::MemberMatch("Event without member".into()))?;
131		match member.as_str() {
132			"Abs" => Ok(MouseEvents::Abs(ev.try_into()?)),
133			"Rel" => Ok(MouseEvents::Rel(ev.try_into()?)),
134			"Button" => Ok(MouseEvents::Button(ev.try_into()?)),
135			_ => Err(AtspiError::MemberMatch("No matching member for Mouse".into())),
136		}
137	}
138}
139
140impl_from_user_facing_event_for_interface_event_enum!(AbsEvent, MouseEvents, MouseEvents::Abs);
141impl_from_user_facing_type_for_event_enum!(AbsEvent, Event::Mouse);
142impl_try_from_event_for_user_facing_type!(AbsEvent, MouseEvents::Abs, Event::Mouse);
143
144event_test_cases!(AbsEvent);
145impl_to_dbus_message!(AbsEvent);
146impl_from_dbus_message!(AbsEvent);
147impl From<AbsEvent> for EventBodyOwned {
148	fn from(event: AbsEvent) -> Self {
149		EventBodyOwned {
150			properties: std::collections::HashMap::new(),
151			kind: String::default(),
152			detail1: event.x,
153			detail2: event.y,
154			any_data: zvariant::Value::U8(0).into(),
155		}
156	}
157}
158
159impl_from_user_facing_event_for_interface_event_enum!(RelEvent, MouseEvents, MouseEvents::Rel);
160impl_from_user_facing_type_for_event_enum!(RelEvent, Event::Mouse);
161impl_try_from_event_for_user_facing_type!(RelEvent, MouseEvents::Rel, Event::Mouse);
162event_test_cases!(RelEvent);
163impl_to_dbus_message!(RelEvent);
164impl_from_dbus_message!(RelEvent);
165impl From<RelEvent> for EventBodyOwned {
166	fn from(event: RelEvent) -> Self {
167		EventBodyOwned {
168			properties: std::collections::HashMap::new(),
169			kind: String::default(),
170			detail1: event.x,
171			detail2: event.y,
172			any_data: zvariant::Value::U8(0).into(),
173		}
174	}
175}
176
177impl_from_user_facing_event_for_interface_event_enum!(
178	ButtonEvent,
179	MouseEvents,
180	MouseEvents::Button
181);
182impl_from_user_facing_type_for_event_enum!(ButtonEvent, Event::Mouse);
183impl_try_from_event_for_user_facing_type!(ButtonEvent, MouseEvents::Button, Event::Mouse);
184event_test_cases!(ButtonEvent);
185impl_to_dbus_message!(ButtonEvent);
186impl_from_dbus_message!(ButtonEvent);
187impl From<ButtonEvent> for EventBodyOwned {
188	fn from(event: ButtonEvent) -> Self {
189		EventBodyOwned {
190			properties: std::collections::HashMap::new(),
191			kind: event.detail,
192			detail1: event.mouse_x,
193			detail2: event.mouse_y,
194			any_data: zvariant::Value::U8(0).into(),
195		}
196	}
197}
198
199impl HasRegistryEventString for MouseEvents {
200	const REGISTRY_EVENT_STRING: &'static str = "Mouse:";
201}