1#[cfg(feature = "zbus")]
2use crate::events::MessageConversion;
3#[cfg(feature = "zbus")]
4use crate::EventProperties;
5use crate::{
6 error::AtspiError,
7 events::{
8 DBusInterface, DBusMatchRule, DBusMember, EventBody, EventBodyOwned, ObjectRef,
9 RegistryEventString,
10 },
11 State,
12};
13use std::hash::Hash;
14#[cfg(feature = "zbus")]
15use zbus::message::{Body as DbusBody, Header};
16use zvariant::{OwnedValue, Value};
17
18const ACCESSIBLE_NAME_PROPERTY_NAME: &str = "accessible-name";
19const ACCESSIBLE_DESCRIPTION_PROPERTY_NAME: &str = "accessible-description";
20const ACCESSIBLE_HELP_TEXT_PROPERTY_NAME: &str = "accessible-help-text";
21const ACCESSIBLE_PARENT_PROPERTY_NAME: &str = "accessible-parent";
22const ACCESSIBLE_ROLE_PROPERTY_NAME: &str = "accessible-role";
23const ACCESSIBLE_TABLE_CAPTION_PROPERTY_NAME: &str = "accessible-table-caption";
24const ACCESSIBLE_TABLE_COLUMN_DESCRIPTION_PROPERTY_NAME: &str =
25 "accessible-table-column-description";
26const ACCESSIBLE_TABLE_COLUMN_HEADER_PROPERTY_NAME: &str = "accessible-table-column-header";
27const ACCESSIBLE_TABLE_ROW_DESCRIPTION_PROPERTY_NAME: &str = "accessible-table-row-description";
28const ACCESSIBLE_TABLE_ROW_HEADER_PROPERTY_NAME: &str = "accessible-table-row-header";
29const ACCESSIBLE_TABLE_SUMMARY_PROPERTY_NAME: &str = "accessible-table-summary";
30
31#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
33pub struct PropertyChangeEvent {
34 pub item: crate::events::ObjectRef,
36 pub property: String,
38 pub value: Property,
39}
40
41impl_event_type_properties_for_event!(PropertyChangeEvent);
42
43impl Hash for PropertyChangeEvent {
44 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
45 self.item.hash(state);
46 self.property.hash(state);
47 }
48}
49
50impl Eq for PropertyChangeEvent {}
52
53#[allow(clippy::derivable_impls)]
56impl Default for PropertyChangeEvent {
57 fn default() -> Self {
58 Self { item: ObjectRef::default(), property: String::default(), value: Property::default() }
59 }
60}
61
62#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
66#[non_exhaustive]
67pub enum Property {
68 Name(String),
69 Description(String),
70 Role(crate::Role),
71 Parent(ObjectRef),
72 TableCaption(String),
73 TableColumnDescription(String),
74 TableColumnHeader(String),
75 TableRowDescription(String),
76 TableRowHeader(String),
77 TableSummary(String),
78 HelpText(String),
79 Other((String, OwnedValue)),
80}
81
82impl Clone for Property {
83 fn clone(&self) -> Self {
84 match self {
85 Property::Name(name) => Self::Name(name.clone()),
86 Property::Description(description) => Self::Description(description.clone()),
87 Property::Role(role) => Self::Role(*role),
88 Property::Parent(parent) => Self::Parent(parent.clone()),
89 Property::TableCaption(table_caption) => Self::TableCaption(table_caption.clone()),
90 Property::TableColumnDescription(table_column_description) => {
91 Self::TableColumnDescription(table_column_description.clone())
92 }
93 Property::TableColumnHeader(table_column_header) => {
94 Self::TableColumnHeader(table_column_header.clone())
95 }
96 Property::TableRowDescription(table_row_description) => {
97 Self::TableRowDescription(table_row_description.clone())
98 }
99 Property::TableRowHeader(table_row_header) => {
100 Self::TableRowHeader(table_row_header.clone())
101 }
102 Property::TableSummary(table_summary) => Self::TableSummary(table_summary.clone()),
103 Property::HelpText(help_text) => Self::HelpText(help_text.clone()),
104 Property::Other((property, value)) => Self::Other((
105 property.clone(),
106 value
107 .try_clone()
108 .expect("Could not clone 'value'. Since properties are not known to carry files, we do not expect to exceed open file limit."),
109 )),
110 }
111 }
112}
113
114impl Default for Property {
115 fn default() -> Self {
116 Self::Other((String::default(), u64::default().into()))
117 }
118}
119
120impl TryFrom<EventBody<'_>> for Property {
121 type Error = AtspiError;
122
123 fn try_from(mut body: EventBody<'_>) -> Result<Self, Self::Error> {
124 let property = body.kind();
125
126 match property {
127 ACCESSIBLE_NAME_PROPERTY_NAME => Ok(Self::Name(
128 body.take_any_data()
129 .try_into()
130 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_NAME_PROPERTY_NAME))?,
131 )),
132 ACCESSIBLE_DESCRIPTION_PROPERTY_NAME => Ok(Self::Description(
133 body.take_any_data()
134 .try_into()
135 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_DESCRIPTION_PROPERTY_NAME))?,
136 )),
137 ACCESSIBLE_ROLE_PROPERTY_NAME => Ok(Self::Role({
138 let role_int: u32 = body
139 .any_data()
140 .try_into()
141 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_ROLE_PROPERTY_NAME))?;
142 let role: crate::Role = crate::Role::try_from(role_int)
143 .map_err(|_| AtspiError::ParseError("accessible-role"))?;
144 role
145 })),
146 ACCESSIBLE_PARENT_PROPERTY_NAME => Ok(Self::Parent(
147 body.take_any_data()
148 .try_into()
149 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_PARENT_PROPERTY_NAME))?,
150 )),
151 ACCESSIBLE_TABLE_CAPTION_PROPERTY_NAME => Ok(Self::TableCaption(
152 body.take_any_data()
153 .try_into()
154 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_TABLE_CAPTION_PROPERTY_NAME))?,
155 )),
156 ACCESSIBLE_TABLE_COLUMN_DESCRIPTION_PROPERTY_NAME => {
157 Ok(Self::TableColumnDescription(body.take_any_data().try_into().map_err(|_| {
158 AtspiError::ParseError(ACCESSIBLE_TABLE_COLUMN_DESCRIPTION_PROPERTY_NAME)
159 })?))
160 }
161 ACCESSIBLE_TABLE_COLUMN_HEADER_PROPERTY_NAME => {
162 Ok(Self::TableColumnHeader(body.take_any_data().try_into().map_err(|_| {
163 AtspiError::ParseError(ACCESSIBLE_TABLE_COLUMN_HEADER_PROPERTY_NAME)
164 })?))
165 }
166 ACCESSIBLE_TABLE_ROW_DESCRIPTION_PROPERTY_NAME => {
167 Ok(Self::TableRowDescription(body.take_any_data().try_into().map_err(|_| {
168 AtspiError::ParseError(ACCESSIBLE_TABLE_ROW_DESCRIPTION_PROPERTY_NAME)
169 })?))
170 }
171 ACCESSIBLE_TABLE_ROW_HEADER_PROPERTY_NAME => {
172 Ok(Self::TableRowHeader(body.take_any_data().try_into().map_err(|_| {
173 AtspiError::ParseError(ACCESSIBLE_TABLE_ROW_HEADER_PROPERTY_NAME)
174 })?))
175 }
176 ACCESSIBLE_TABLE_SUMMARY_PROPERTY_NAME => Ok(Self::TableSummary(
177 body.take_any_data()
178 .try_into()
179 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_TABLE_SUMMARY_PROPERTY_NAME))?,
180 )),
181 ACCESSIBLE_HELP_TEXT_PROPERTY_NAME => Ok(Self::HelpText(
182 body.take_any_data()
183 .try_into()
184 .map_err(|_| AtspiError::ParseError(ACCESSIBLE_HELP_TEXT_PROPERTY_NAME))?,
185 )),
186 _ => Ok(Self::Other((property.to_string(), body.take_any_data()))),
187 }
188 }
189}
190
191impl From<Property> for OwnedValue {
192 fn from(property: Property) -> Self {
193 let value = match property {
194 Property::Name(name) => Value::from(name),
195 Property::Description(description) => Value::from(description),
196 Property::Role(role) => Value::from(role as u32),
197 Property::Parent(parent) => Value::from(parent),
198 Property::TableCaption(table_caption) => Value::from(table_caption),
199 Property::TableColumnDescription(table_column_description) => {
200 Value::from(table_column_description)
201 }
202 Property::TableColumnHeader(table_column_header) => Value::from(table_column_header),
203 Property::TableRowDescription(table_row_description) => {
204 Value::from(table_row_description)
205 }
206 Property::TableRowHeader(table_row_header) => Value::from(table_row_header),
207 Property::TableSummary(table_summary) => Value::from(table_summary),
208 Property::HelpText(help_text) => Value::from(help_text),
209 Property::Other((_, value)) => value.into(),
210 };
211 value.try_into().expect("Should succeed as there are no borrowed file descriptors involved that could, potentially, exceed the open file limit when converted to OwnedValue")
212 }
213}
214
215#[cfg(test)]
216mod test_property {
217 use crate::events::object::{Property, PropertyChangeEvent};
218 use crate::events::{EventBody, EventBodyOwned};
219 use crate::{ObjectRef, Role};
220 macro_rules! property_subtype_test {
221 ($name:ident, $key:expr, $prop:path, $val:expr) => {
222 #[test]
223 fn $name() {
224 let prop = $prop($val);
225 let prop_ev = PropertyChangeEvent {
226 item: ObjectRef::default(),
227 property: $key.to_string(),
228 value: prop.clone(),
229 };
230 let ev_body: EventBodyOwned = prop_ev.try_into().expect("Valid event body!");
231 let ev: EventBody<'_> = ev_body.into();
232 let prop2: Property = ev.try_into().expect("Valid Property value");
233 assert_eq!(prop, prop2);
234 }
235 };
236 }
237 property_subtype_test!(
238 test_prop_type_desc,
239 "accessible-description",
240 Property::Description,
241 "Accessible description text here!".to_string()
242 );
243 property_subtype_test!(
244 test_prop_type_name,
245 "accessible-name",
246 Property::Name,
247 "Accessible name here!".to_string()
248 );
249 property_subtype_test!(test_prop_type_role, "accessible-role", Property::Role, Role::Invalid);
250 property_subtype_test!(
251 test_prop_type_parent,
252 "accessible-parent",
253 Property::Parent,
254 ObjectRef {
255 name: ":420.69".try_into().unwrap(),
256 path: "/fake/a11y/addr".try_into().unwrap()
257 }
258 );
259 property_subtype_test!(
260 test_prop_type_table_caption,
261 "accessible-table-caption",
262 Property::TableCaption,
263 "Accessible table description here".to_string()
264 );
265 property_subtype_test!(
266 test_prop_type_table_cd,
267 "accessible-table-column-description",
268 Property::TableColumnDescription,
269 "Accessible table column description here!".to_string()
270 );
271 property_subtype_test!(
272 test_prop_type_table_ch,
273 "accessible-table-column-header",
274 Property::TableColumnHeader,
275 "Accessible table column header here!".to_string()
276 );
277 property_subtype_test!(
278 test_prop_type_table_rd,
279 "accessible-table-row-description",
280 Property::TableRowDescription,
281 "Accessible table row description here!".to_string()
282 );
283 property_subtype_test!(
284 test_prop_type_table_rh,
285 "accessible-table-row-header",
286 Property::TableRowHeader,
287 "Accessible table row header here!".to_string()
288 );
289 property_subtype_test!(
290 test_prop_help_text,
291 "accessible-help-text",
292 Property::HelpText,
293 "Accessible help text here!".to_string()
294 );
295}
296
297#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
298pub struct BoundsChangedEvent {
299 pub item: crate::events::ObjectRef,
301}
302
303impl_event_type_properties_for_event!(BoundsChangedEvent);
304
305#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
306pub struct LinkSelectedEvent {
307 pub item: crate::events::ObjectRef,
309}
310
311impl_event_type_properties_for_event!(LinkSelectedEvent);
312
313#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
316pub struct StateChangedEvent {
317 pub item: crate::events::ObjectRef,
319 pub state: State,
321 #[serde(with = "i32_bool_conversion")]
323 pub enabled: bool,
324}
325
326impl_event_type_properties_for_event!(StateChangedEvent);
327
328mod i32_bool_conversion {
329 use serde::{Deserialize, Deserializer, Serializer};
330 pub fn deserialize<'de, D>(de: D) -> Result<bool, D::Error>
333 where
334 D: Deserializer<'de>,
335 {
336 let int: i32 = Deserialize::deserialize(de)?;
337 Ok(int > 0)
338 }
339
340 #[allow(clippy::trivially_copy_pass_by_ref)]
345 pub fn serialize<S>(b: &bool, ser: S) -> Result<S::Ok, S::Error>
346 where
347 S: Serializer,
348 {
349 let val: i32 = (*b).into();
350 ser.serialize_i32(val)
351 }
352}
353
354#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
356pub struct ChildrenChangedEvent {
357 pub item: crate::events::ObjectRef,
359 pub operation: crate::Operation,
361 pub index_in_parent: i32,
363 pub child: ObjectRef,
365}
366
367impl_event_type_properties_for_event!(ChildrenChangedEvent);
368
369#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
370pub struct VisibleDataChangedEvent {
371 pub item: crate::events::ObjectRef,
373}
374
375impl_event_type_properties_for_event!(VisibleDataChangedEvent);
376
377#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
378pub struct SelectionChangedEvent {
379 pub item: crate::events::ObjectRef,
381}
382
383impl_event_type_properties_for_event!(SelectionChangedEvent);
384
385#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
386pub struct ModelChangedEvent {
387 pub item: crate::events::ObjectRef,
389}
390
391impl_event_type_properties_for_event!(ModelChangedEvent);
392
393#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
394pub struct ActiveDescendantChangedEvent {
395 pub item: crate::events::ObjectRef,
397 pub child: ObjectRef,
398}
399
400impl_event_type_properties_for_event!(ActiveDescendantChangedEvent);
401
402#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
403pub struct AnnouncementEvent {
404 pub item: crate::events::ObjectRef,
406 pub text: String,
408 pub live: crate::Politeness,
410}
411
412impl_event_type_properties_for_event!(AnnouncementEvent);
413
414#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
415pub struct AttributesChangedEvent {
416 pub item: crate::events::ObjectRef,
418}
419
420impl_event_type_properties_for_event!(AttributesChangedEvent);
421
422#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
424pub struct RowInsertedEvent {
425 pub item: crate::events::ObjectRef,
427}
428
429impl_event_type_properties_for_event!(RowInsertedEvent);
430
431#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
433pub struct RowReorderedEvent {
434 pub item: crate::events::ObjectRef,
436}
437
438impl_event_type_properties_for_event!(RowReorderedEvent);
439
440#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
442pub struct RowDeletedEvent {
443 pub item: crate::events::ObjectRef,
445}
446
447impl_event_type_properties_for_event!(RowDeletedEvent);
448
449#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
451pub struct ColumnInsertedEvent {
452 pub item: crate::events::ObjectRef,
454}
455
456impl_event_type_properties_for_event!(ColumnInsertedEvent);
457
458#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
460pub struct ColumnReorderedEvent {
461 pub item: crate::events::ObjectRef,
463}
464
465impl_event_type_properties_for_event!(ColumnReorderedEvent);
466
467#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
469pub struct ColumnDeletedEvent {
470 pub item: crate::events::ObjectRef,
472}
473
474impl_event_type_properties_for_event!(ColumnDeletedEvent);
475
476#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
477pub struct TextBoundsChangedEvent {
478 pub item: crate::events::ObjectRef,
480}
481
482impl_event_type_properties_for_event!(TextBoundsChangedEvent);
483
484#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
485pub struct TextSelectionChangedEvent {
486 pub item: crate::events::ObjectRef,
488}
489
490impl_event_type_properties_for_event!(TextSelectionChangedEvent);
491
492#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
494pub struct TextChangedEvent {
495 pub item: crate::events::ObjectRef,
497 pub operation: crate::Operation,
499 pub start_pos: i32,
501 pub length: i32,
503 pub text: String,
505}
506
507impl_event_type_properties_for_event!(TextChangedEvent);
508
509#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
513pub struct TextAttributesChangedEvent {
514 pub item: crate::events::ObjectRef,
516}
517
518impl_event_type_properties_for_event!(TextAttributesChangedEvent);
519
520#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
522pub struct TextCaretMovedEvent {
523 pub item: crate::events::ObjectRef,
525 pub position: i32,
527}
528
529impl_event_type_properties_for_event!(TextCaretMovedEvent);
530
531impl_member_interface_registry_string_and_match_rule_for_event!(
532 PropertyChangeEvent,
533 "PropertyChange",
534 "org.a11y.atspi.Event.Object",
535 "object:property-change",
536 "type='signal',interface='org.a11y.atspi.Event.Object',member='PropertyChange'"
537);
538
539#[cfg(feature = "zbus")]
540impl MessageConversion<'_> for PropertyChangeEvent {
541 type Body<'b> = EventBody<'b>;
542
543 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
544 let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
545 let property: String = body.take_kind();
546 let value: Property = body.try_into()?;
547 Ok(Self { item, property, value })
548 }
549
550 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
551 let item = header.try_into()?;
552 let body = msg.body();
553 Self::from_message_unchecked_parts(item, body)
554 }
555
556 fn body(&self) -> Self::Body<'_> {
557 let copy = self.clone();
558 EventBodyOwned::from(copy).into()
559 }
560}
561
562impl_member_interface_registry_string_and_match_rule_for_event!(
563 BoundsChangedEvent,
564 "BoundsChanged",
565 "org.a11y.atspi.Event.Object",
566 "object:bounds-changed",
567 "type='signal',interface='org.a11y.atspi.Event.Object',member='BoundsChanged'"
568);
569
570impl_member_interface_registry_string_and_match_rule_for_event!(
571 LinkSelectedEvent,
572 "LinkSelected",
573 "org.a11y.atspi.Event.Object",
574 "object:link-selected",
575 "type='signal',interface='org.a11y.atspi.Event.Object',member='LinkSelected'"
576);
577
578impl_member_interface_registry_string_and_match_rule_for_event!(
579 StateChangedEvent,
580 "StateChanged",
581 "org.a11y.atspi.Event.Object",
582 "object:state-changed",
583 "type='signal',interface='org.a11y.atspi.Event.Object',member='StateChanged'"
584);
585
586#[cfg(feature = "zbus")]
587impl MessageConversion<'_> for StateChangedEvent {
588 type Body<'a> = EventBody<'a>;
589
590 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
591 let body: Self::Body<'_> = body.deserialize_unchecked()?;
592 Ok(Self { item, state: body.kind().into(), enabled: body.detail1() > 0 })
593 }
594
595 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
596 let item = header.try_into()?;
597 let body = msg.body();
598 Self::from_message_unchecked_parts(item, body)
599 }
600
601 fn body(&self) -> Self::Body<'_> {
602 let copy = self.clone();
603 copy.into()
604 }
605}
606
607impl_member_interface_registry_string_and_match_rule_for_event!(
608 ChildrenChangedEvent,
609 "ChildrenChanged",
610 "org.a11y.atspi.Event.Object",
611 "object:children-changed",
612 "type='signal',interface='org.a11y.atspi.Event.Object',member='ChildrenChanged'"
613);
614
615#[cfg(feature = "zbus")]
616impl MessageConversion<'_> for ChildrenChangedEvent {
617 type Body<'a> = EventBody<'a>;
618
619 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
620 let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
621 Ok(Self {
622 item,
623 operation: body.kind().parse()?,
624 index_in_parent: body.detail1(),
625 child: body.take_any_data().try_into()?,
626 })
627 }
628
629 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
630 let item = header.try_into()?;
631 let body = msg.body();
632 Self::from_message_unchecked_parts(item, body)
633 }
634
635 fn body(&self) -> Self::Body<'_> {
636 EventBodyOwned::from(self.clone()).into()
637 }
638}
639
640impl_member_interface_registry_string_and_match_rule_for_event!(
641 VisibleDataChangedEvent,
642 "VisibleDataChanged",
643 "org.a11y.atspi.Event.Object",
644 "object:visible-data-changed",
645 "type='signal',interface='org.a11y.atspi.Event.Object',member='VisibleDataChanged'"
646);
647
648impl_member_interface_registry_string_and_match_rule_for_event!(
649 SelectionChangedEvent,
650 "SelectionChanged",
651 "org.a11y.atspi.Event.Object",
652 "object:selection-changed",
653 "type='signal',interface='org.a11y.atspi.Event.Object',member='SelectionChanged'"
654);
655
656impl_member_interface_registry_string_and_match_rule_for_event!(
657 ModelChangedEvent,
658 "ModelChanged",
659 "org.a11y.atspi.Event.Object",
660 "object:model-changed",
661 "type='signal',interface='org.a11y.atspi.Event.Object',member='ModelChanged'"
662);
663
664impl_member_interface_registry_string_and_match_rule_for_event!(
665 ActiveDescendantChangedEvent,
666 "ActiveDescendantChanged",
667 "org.a11y.atspi.Event.Object",
668 "object:active-descendant-changed",
669 "type='signal',interface='org.a11y.atspi.Event.Object',member='ActiveDescendantChanged'"
670);
671
672#[cfg(feature = "zbus")]
673impl MessageConversion<'_> for ActiveDescendantChangedEvent {
674 type Body<'a> = EventBody<'a>;
675
676 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
677 let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
678 Ok(Self { item, child: body.take_any_data().try_into()? })
679 }
680
681 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
682 let item = header.try_into()?;
683 let body = msg.body();
684 Self::from_message_unchecked_parts(item, body)
685 }
686
687 fn body(&self) -> Self::Body<'_> {
688 EventBodyOwned::from(self.clone()).into()
689 }
690}
691
692impl_member_interface_registry_string_and_match_rule_for_event!(
693 AnnouncementEvent,
694 "Announcement",
695 "org.a11y.atspi.Event.Object",
696 "object:announcement",
697 "type='signal',interface='org.a11y.atspi.Event.Object',member='Announcement'"
698);
699
700#[cfg(feature = "zbus")]
701impl MessageConversion<'_> for AnnouncementEvent {
702 type Body<'a> = EventBody<'a>;
703
704 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
705 let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
706 Ok(Self {
707 item,
708 text: body
709 .take_any_data()
710 .try_into()
711 .map_err(|_| AtspiError::Conversion("text"))?,
712 live: body.detail1().try_into()?,
713 })
714 }
715
716 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
717 let item = header.try_into()?;
718 let body = msg.body();
719 Self::from_message_unchecked_parts(item, body)
720 }
721
722 fn body(&self) -> Self::Body<'_> {
723 EventBodyOwned::from(self.clone()).into()
724 }
725}
726
727impl_member_interface_registry_string_and_match_rule_for_event!(
728 AttributesChangedEvent,
729 "AttributesChanged",
730 "org.a11y.atspi.Event.Object",
731 "object:attributes-changed",
732 "type='signal',interface='org.a11y.atspi.Event.Object',member='AttributesChanged'"
733);
734
735impl_member_interface_registry_string_and_match_rule_for_event!(
736 RowInsertedEvent,
737 "RowInserted",
738 "org.a11y.atspi.Event.Object",
739 "object:row-inserted",
740 "type='signal',interface='org.a11y.atspi.Event.Object',member='RowInserted'"
741);
742
743impl_member_interface_registry_string_and_match_rule_for_event!(
744 RowReorderedEvent,
745 "RowReordered",
746 "org.a11y.atspi.Event.Object",
747 "object:row-reordered",
748 "type='signal',interface='org.a11y.atspi.Event.Object',member='RowReordered'"
749);
750
751impl_member_interface_registry_string_and_match_rule_for_event!(
752 RowDeletedEvent,
753 "RowDeleted",
754 "org.a11y.atspi.Event.Object",
755 "object:row-deleted",
756 "type='signal',interface='org.a11y.atspi.Event.Object',member='RowDeleted'"
757);
758
759impl_member_interface_registry_string_and_match_rule_for_event!(
760 ColumnInsertedEvent,
761 "ColumnInserted",
762 "org.a11y.atspi.Event.Object",
763 "object:column-inserted",
764 "type='signal',interface='org.a11y.atspi.Event.Object',member='ColumnInserted'"
765);
766
767impl_member_interface_registry_string_and_match_rule_for_event!(
768 ColumnReorderedEvent,
769 "ColumnReordered",
770 "org.a11y.atspi.Event.Object",
771 "object:column-reordered",
772 "type='signal',interface='org.a11y.atspi.Event.Object',member='ColumnReordered'"
773);
774
775impl_member_interface_registry_string_and_match_rule_for_event!(
776 ColumnDeletedEvent,
777 "ColumnDeleted",
778 "org.a11y.atspi.Event.Object",
779 "object:column-deleted",
780 "type='signal',interface='org.a11y.atspi.Event.Object',member='ColumnDeleted'"
781);
782
783impl_member_interface_registry_string_and_match_rule_for_event!(
784 TextBoundsChangedEvent,
785 "TextBoundsChanged",
786 "org.a11y.atspi.Event.Object",
787 "object:text-bounds-changed",
788 "type='signal',interface='org.a11y.atspi.Event.Object',member='TextBoundsChanged'"
789);
790
791impl_member_interface_registry_string_and_match_rule_for_event!(
792 TextSelectionChangedEvent,
793 "TextSelectionChanged",
794 "org.a11y.atspi.Event.Object",
795 "object:text-selection-changed",
796 "type='signal',interface='org.a11y.atspi.Event.Object',member='TextSelectionChanged'"
797);
798
799impl_member_interface_registry_string_and_match_rule_for_event!(
800 TextChangedEvent,
801 "TextChanged",
802 "org.a11y.atspi.Event.Object",
803 "object:text-changed",
804 "type='signal',interface='org.a11y.atspi.Event.Object',member='TextChanged'"
805);
806
807#[cfg(feature = "zbus")]
808impl MessageConversion<'_> for TextChangedEvent {
809 type Body<'a> = EventBody<'a>;
810
811 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
812 let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
813 Ok(Self {
814 item,
815 operation: body.kind().parse()?,
816 start_pos: body.detail1(),
817 length: body.detail2(),
818 text: body.take_any_data().try_into()?,
819 })
820 }
821
822 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
823 let item = header.try_into()?;
824 let body = msg.body();
825 Self::from_message_unchecked_parts(item, body)
826 }
827
828 fn body(&self) -> Self::Body<'_> {
829 EventBodyOwned::from(self.clone()).into()
830 }
831}
832
833impl_member_interface_registry_string_and_match_rule_for_event!(
834 TextAttributesChangedEvent,
835 "TextAttributesChanged",
836 "org.a11y.atspi.Event.Object",
837 "object:text-attributes-changed",
838 "type='signal',interface='org.a11y.atspi.Event.Object',member='TextAttributesChanged'"
839);
840
841impl_member_interface_registry_string_and_match_rule_for_event!(
842 TextCaretMovedEvent,
843 "TextCaretMoved",
844 "org.a11y.atspi.Event.Object",
845 "object:text-caret-moved",
846 "type='signal',interface='org.a11y.atspi.Event.Object',member='TextCaretMoved'"
847);
848
849#[cfg(feature = "zbus")]
850impl MessageConversion<'_> for TextCaretMovedEvent {
851 type Body<'a> = EventBody<'a>;
852
853 fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
854 let body = body.deserialize_unchecked::<Self::Body<'_>>()?;
855 Ok(Self { item, position: body.detail1() })
856 }
857
858 fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
859 let item = header.try_into()?;
860 let body = msg.body();
861 Self::from_message_unchecked_parts(item, body)
862 }
863
864 fn body(&self) -> Self::Body<'_> {
865 EventBodyOwned::from(self.clone()).into()
866 }
867}
868
869event_test_cases!(PropertyChangeEvent);
870impl_to_dbus_message!(PropertyChangeEvent);
871impl_from_dbus_message!(PropertyChangeEvent);
872impl_event_properties!(PropertyChangeEvent);
873
874impl From<PropertyChangeEvent> for EventBodyOwned {
875 fn from(event: PropertyChangeEvent) -> Self {
876 EventBodyOwned { kind: event.property, any_data: event.value.into(), ..Default::default() }
877 }
878}
879
880impl From<&PropertyChangeEvent> for EventBodyOwned {
881 fn from(event: &PropertyChangeEvent) -> Self {
882 EventBodyOwned {
883 kind: event.property.to_string(),
884 any_data: event.value.clone().into(),
885 ..Default::default()
886 }
887 }
888}
889
890impl From<PropertyChangeEvent> for EventBody<'_> {
891 fn from(event: PropertyChangeEvent) -> Self {
892 EventBodyOwned::from(event).into()
893 }
894}
895
896event_test_cases!(BoundsChangedEvent);
897impl_to_dbus_message!(BoundsChangedEvent);
898impl_from_dbus_message!(BoundsChangedEvent);
899impl_event_properties!(BoundsChangedEvent);
900impl_from_object_ref!(BoundsChangedEvent);
901
902event_test_cases!(LinkSelectedEvent);
903impl_to_dbus_message!(LinkSelectedEvent);
904impl_from_dbus_message!(LinkSelectedEvent);
905impl_event_properties!(LinkSelectedEvent);
906impl_from_object_ref!(LinkSelectedEvent);
907
908event_test_cases!(StateChangedEvent);
909impl_to_dbus_message!(StateChangedEvent);
910impl_from_dbus_message!(StateChangedEvent);
911impl_event_properties!(StateChangedEvent);
912
913impl From<StateChangedEvent> for EventBodyOwned {
914 fn from(event: StateChangedEvent) -> Self {
915 EventBodyOwned {
916 kind: event.state.to_string(),
917 detail1: event.enabled.into(),
918 ..Default::default()
919 }
920 }
921}
922
923impl From<&StateChangedEvent> for EventBodyOwned {
924 fn from(event: &StateChangedEvent) -> Self {
925 EventBodyOwned {
926 kind: event.state.to_string(),
927 detail1: event.enabled.into(),
928 ..Default::default()
929 }
930 }
931}
932
933impl From<StateChangedEvent> for EventBody<'_> {
934 fn from(event: StateChangedEvent) -> Self {
935 EventBodyOwned::from(event).into()
936 }
937}
938
939event_test_cases!(ChildrenChangedEvent);
940impl_to_dbus_message!(ChildrenChangedEvent);
941impl_from_dbus_message!(ChildrenChangedEvent);
942impl_event_properties!(ChildrenChangedEvent);
943
944impl From<ChildrenChangedEvent> for EventBodyOwned {
945 fn from(event: ChildrenChangedEvent) -> Self {
946 EventBodyOwned {
947 kind: event.operation.to_string(),
948 detail1: event.index_in_parent,
949
950 any_data: Value::from(event.child)
954 .try_into()
955 .expect("Failed to convert child to OwnedValue"),
956 ..Default::default()
957 }
958 }
959}
960
961impl From<&ChildrenChangedEvent> for EventBodyOwned {
962 fn from(event: &ChildrenChangedEvent) -> Self {
963 EventBodyOwned {
964 kind: event.operation.to_string(),
965 detail1: event.index_in_parent,
966 detail2: i32::default(),
967 any_data: Value::from(event.child.clone())
971 .try_into()
972 .expect("ObjectRef should convert to OwnedValue without error"),
973 properties: super::event_body::Properties,
974 }
975 }
976}
977
978impl From<ChildrenChangedEvent> for EventBody<'_> {
979 fn from(event: ChildrenChangedEvent) -> Self {
980 EventBodyOwned::from(event).into()
981 }
982}
983
984event_test_cases!(VisibleDataChangedEvent);
985impl_to_dbus_message!(VisibleDataChangedEvent);
986impl_from_dbus_message!(VisibleDataChangedEvent);
987impl_event_properties!(VisibleDataChangedEvent);
988impl_from_object_ref!(VisibleDataChangedEvent);
989
990event_test_cases!(SelectionChangedEvent);
991impl_to_dbus_message!(SelectionChangedEvent);
992impl_from_dbus_message!(SelectionChangedEvent);
993impl_event_properties!(SelectionChangedEvent);
994impl_from_object_ref!(SelectionChangedEvent);
995
996event_test_cases!(ModelChangedEvent);
997impl_to_dbus_message!(ModelChangedEvent);
998impl_from_dbus_message!(ModelChangedEvent);
999impl_event_properties!(ModelChangedEvent);
1000impl_from_object_ref!(ModelChangedEvent);
1001
1002event_test_cases!(ActiveDescendantChangedEvent);
1003impl_to_dbus_message!(ActiveDescendantChangedEvent);
1004impl_from_dbus_message!(ActiveDescendantChangedEvent);
1005impl_event_properties!(ActiveDescendantChangedEvent);
1006impl From<ActiveDescendantChangedEvent> for EventBodyOwned {
1007 fn from(event: ActiveDescendantChangedEvent) -> Self {
1008 EventBodyOwned {
1009 any_data: Value::from(event.child)
1013 .try_to_owned()
1014 .expect("Failed to convert child to OwnedValue"),
1015 ..Default::default()
1016 }
1017 }
1018}
1019
1020event_test_cases!(AnnouncementEvent);
1021impl_to_dbus_message!(AnnouncementEvent);
1022impl_from_dbus_message!(AnnouncementEvent);
1023impl_event_properties!(AnnouncementEvent);
1024impl From<AnnouncementEvent> for EventBodyOwned {
1025 fn from(event: AnnouncementEvent) -> Self {
1026 EventBodyOwned {
1027 detail1: event.live as i32,
1028 any_data: Value::from(event.text)
1031 .try_to_owned()
1032 .expect("Failed to convert text to OwnedValue"),
1033 ..Default::default()
1034 }
1035 }
1036}
1037
1038event_test_cases!(AttributesChangedEvent);
1039impl_to_dbus_message!(AttributesChangedEvent);
1040impl_from_dbus_message!(AttributesChangedEvent);
1041impl_event_properties!(AttributesChangedEvent);
1042impl_from_object_ref!(AttributesChangedEvent);
1043
1044event_test_cases!(RowInsertedEvent);
1045impl_to_dbus_message!(RowInsertedEvent);
1046impl_from_dbus_message!(RowInsertedEvent);
1047impl_event_properties!(RowInsertedEvent);
1048impl_from_object_ref!(RowInsertedEvent);
1049
1050event_test_cases!(RowReorderedEvent);
1051impl_to_dbus_message!(RowReorderedEvent);
1052impl_from_dbus_message!(RowReorderedEvent);
1053impl_event_properties!(RowReorderedEvent);
1054impl_from_object_ref!(RowReorderedEvent);
1055
1056event_test_cases!(RowDeletedEvent);
1057impl_to_dbus_message!(RowDeletedEvent);
1058impl_from_dbus_message!(RowDeletedEvent);
1059impl_event_properties!(RowDeletedEvent);
1060impl_from_object_ref!(RowDeletedEvent);
1061
1062event_test_cases!(ColumnInsertedEvent);
1063impl_to_dbus_message!(ColumnInsertedEvent);
1064impl_from_dbus_message!(ColumnInsertedEvent);
1065impl_event_properties!(ColumnInsertedEvent);
1066impl_from_object_ref!(ColumnInsertedEvent);
1067
1068event_test_cases!(ColumnReorderedEvent);
1069impl_to_dbus_message!(ColumnReorderedEvent);
1070impl_from_dbus_message!(ColumnReorderedEvent);
1071impl_event_properties!(ColumnReorderedEvent);
1072impl_from_object_ref!(ColumnReorderedEvent);
1073
1074event_test_cases!(ColumnDeletedEvent);
1075impl_to_dbus_message!(ColumnDeletedEvent);
1076impl_from_dbus_message!(ColumnDeletedEvent);
1077impl_event_properties!(ColumnDeletedEvent);
1078impl_from_object_ref!(ColumnDeletedEvent);
1079
1080event_test_cases!(TextBoundsChangedEvent);
1081impl_to_dbus_message!(TextBoundsChangedEvent);
1082impl_from_dbus_message!(TextBoundsChangedEvent);
1083impl_event_properties!(TextBoundsChangedEvent);
1084impl_from_object_ref!(TextBoundsChangedEvent);
1085
1086event_test_cases!(TextSelectionChangedEvent);
1087impl_to_dbus_message!(TextSelectionChangedEvent);
1088impl_from_dbus_message!(TextSelectionChangedEvent);
1089impl_event_properties!(TextSelectionChangedEvent);
1090impl_from_object_ref!(TextSelectionChangedEvent);
1091
1092event_test_cases!(TextChangedEvent);
1093
1094assert_impl_all!(TextChangedEvent:Clone,std::fmt::Debug,serde::Serialize,serde::Deserialize<'static>,Default,PartialEq,Eq,std::hash::Hash,crate::EventProperties,crate::EventTypeProperties);
1095#[cfg(feature = "zbus")]
1096assert_impl_all!(zbus::Message:TryFrom<TextChangedEvent>);
1097
1098impl_to_dbus_message!(TextChangedEvent);
1099impl_from_dbus_message!(TextChangedEvent);
1100impl_event_properties!(TextChangedEvent);
1101impl From<TextChangedEvent> for EventBodyOwned {
1102 fn from(event: TextChangedEvent) -> Self {
1103 EventBodyOwned {
1104 kind: event.operation.to_string(),
1105 detail1: event.start_pos,
1106 detail2: event.length,
1107 any_data: Value::from(event.text)
1110 .try_to_owned()
1111 .expect("Failed to convert child to OwnedValue"),
1112 ..Default::default()
1113 }
1114 }
1115}
1116
1117event_test_cases!(TextAttributesChangedEvent);
1118impl_to_dbus_message!(TextAttributesChangedEvent);
1119impl_from_dbus_message!(TextAttributesChangedEvent);
1120impl_event_properties!(TextAttributesChangedEvent);
1121impl_from_object_ref!(TextAttributesChangedEvent);
1122
1123event_test_cases!(TextCaretMovedEvent);
1124impl_to_dbus_message!(TextCaretMovedEvent);
1125impl_from_dbus_message!(TextCaretMovedEvent);
1126impl_event_properties!(TextCaretMovedEvent);
1127impl From<TextCaretMovedEvent> for EventBodyOwned {
1128 fn from(event: TextCaretMovedEvent) -> Self {
1129 EventBodyOwned { detail1: event.position, ..Default::default() }
1130 }
1131}
1132
1133impl_msg_conversion_ext_for_target_type!(PropertyChangeEvent);
1134impl_msg_conversion_ext_for_target_type!(BoundsChangedEvent);
1135impl_msg_conversion_ext_for_target_type!(LinkSelectedEvent);
1136impl_msg_conversion_ext_for_target_type!(StateChangedEvent);
1137impl_msg_conversion_ext_for_target_type!(ChildrenChangedEvent);
1138impl_msg_conversion_ext_for_target_type!(VisibleDataChangedEvent);
1139impl_msg_conversion_ext_for_target_type!(SelectionChangedEvent);
1140impl_msg_conversion_ext_for_target_type!(ModelChangedEvent);
1141impl_msg_conversion_ext_for_target_type!(ActiveDescendantChangedEvent);
1142impl_msg_conversion_ext_for_target_type!(AnnouncementEvent);
1143impl_msg_conversion_ext_for_target_type!(AttributesChangedEvent);
1144impl_msg_conversion_ext_for_target_type!(RowInsertedEvent);
1145impl_msg_conversion_ext_for_target_type!(RowReorderedEvent);
1146impl_msg_conversion_ext_for_target_type!(RowDeletedEvent);
1147impl_msg_conversion_ext_for_target_type!(ColumnInsertedEvent);
1148impl_msg_conversion_ext_for_target_type!(ColumnReorderedEvent);
1149impl_msg_conversion_ext_for_target_type!(ColumnDeletedEvent);
1150impl_msg_conversion_ext_for_target_type!(TextBoundsChangedEvent);
1151impl_msg_conversion_ext_for_target_type!(TextSelectionChangedEvent);
1152impl_msg_conversion_ext_for_target_type!(TextChangedEvent);
1153impl_msg_conversion_ext_for_target_type!(TextAttributesChangedEvent);
1154impl_msg_conversion_ext_for_target_type!(TextCaretMovedEvent);
1155
1156impl_msg_conversion_for_types_built_from_object_ref!(BoundsChangedEvent);
1157impl_msg_conversion_for_types_built_from_object_ref!(LinkSelectedEvent);
1158impl_msg_conversion_for_types_built_from_object_ref!(VisibleDataChangedEvent);
1159impl_msg_conversion_for_types_built_from_object_ref!(SelectionChangedEvent);
1160impl_msg_conversion_for_types_built_from_object_ref!(ModelChangedEvent);
1161impl_msg_conversion_for_types_built_from_object_ref!(AttributesChangedEvent);
1162impl_msg_conversion_for_types_built_from_object_ref!(RowInsertedEvent);
1163impl_msg_conversion_for_types_built_from_object_ref!(RowReorderedEvent);
1164impl_msg_conversion_for_types_built_from_object_ref!(RowDeletedEvent);
1165impl_msg_conversion_for_types_built_from_object_ref!(ColumnInsertedEvent);
1166impl_msg_conversion_for_types_built_from_object_ref!(ColumnReorderedEvent);
1167impl_msg_conversion_for_types_built_from_object_ref!(ColumnDeletedEvent);
1168impl_msg_conversion_for_types_built_from_object_ref!(TextBoundsChangedEvent);
1169impl_msg_conversion_for_types_built_from_object_ref!(TextSelectionChangedEvent);
1170impl_msg_conversion_for_types_built_from_object_ref!(TextAttributesChangedEvent);