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