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: AbsEvent = 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: RelEvent = 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: ButtonEvent = 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: MemberName<'_> = ev
129 .member()
130 .ok_or(err: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}
202