atspi_common/events/
object.rs

1#[cfg(feature = "zbus")]
2use crate::events::MessageConversion;
3#[cfg(any(feature = "wrappers", 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
18/// The `org.a11y.atspi.Event.Object:PropertyChange` event.
19#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
20pub struct PropertyChangeEvent {
21	/// The [`crate::ObjectRef`] which the event applies to.
22	pub item: crate::events::ObjectRef,
23	// TODO: this is not necessary since the string is encoded in the `Property` type.
24	pub property: String,
25	pub value: Property,
26}
27
28impl_event_type_properties_for_event!(PropertyChangeEvent);
29
30impl Hash for PropertyChangeEvent {
31	fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
32		self.item.hash(state);
33		self.property.hash(state);
34	}
35}
36
37// Do not derive Eq if not all fields implement Eq
38impl Eq for PropertyChangeEvent {}
39
40// TODO: Looks like a false positive Clippy lint
41// Derive me.
42#[allow(clippy::derivable_impls)]
43impl Default for PropertyChangeEvent {
44	fn default() -> Self {
45		Self { item: ObjectRef::default(), property: String::default(), value: Property::default() }
46	}
47}
48
49/// Any accessibility related property on an [`crate::ObjectRef`].
50/// This is used only in the [`PropertyChangeEvent`]; this event gets triggered if a role or accessible
51/// description of an item changes.
52#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
53#[non_exhaustive]
54pub enum Property {
55	Name(String),
56	Description(String),
57	Role(crate::Role),
58	Parent(ObjectRef),
59	TableCaption(String),
60	TableColumnDescription(String),
61	TableColumnHeader(String),
62	TableRowDescription(String),
63	TableRowHeader(String),
64	TableSummary(String),
65	Other((String, OwnedValue)),
66}
67
68impl Clone for Property {
69	fn clone(&self) -> Self {
70		match self {
71			Property::Name(name) => Self::Name(name.clone()),
72			Property::Description(description) => Self::Description(description.clone()),
73			Property::Role(role) => Self::Role(*role),
74			Property::Parent(parent) => Self::Parent(parent.clone()),
75			Property::TableCaption(table_caption) => Self::TableCaption(table_caption.clone()),
76			Property::TableColumnDescription(table_column_description) => {
77				Self::TableColumnDescription(table_column_description.clone())
78			}
79			Property::TableColumnHeader(table_column_header) => {
80				Self::TableColumnHeader(table_column_header.clone())
81			}
82			Property::TableRowDescription(table_row_description) => {
83				Self::TableRowDescription(table_row_description.clone())
84			}
85			Property::TableRowHeader(table_row_header) => {
86				Self::TableRowHeader(table_row_header.clone())
87			}
88			Property::TableSummary(table_summary) => Self::TableSummary(table_summary.clone()),
89			Property::Other((property, value)) => Self::Other((
90				property.clone(),
91				value
92					.try_clone()
93					.expect("Could not clone 'value'.  Since properties are not known to carry files, we do not expect to exceed open file limit."),
94			)),
95		}
96	}
97}
98
99impl Default for Property {
100	fn default() -> Self {
101		Self::Other((String::default(), u64::default().into()))
102	}
103}
104
105impl TryFrom<EventBody<'_>> for Property {
106	type Error = AtspiError;
107
108	fn try_from(mut body: EventBody<'_>) -> Result<Self, Self::Error> {
109		let property = body.kind();
110
111		match property {
112			"accessible-name" => Ok(Self::Name(
113				body.take_any_data()
114					.try_into()
115					.map_err(|_| AtspiError::ParseError("accessible-name"))?,
116			)),
117			"accessible-description" => Ok(Self::Description(
118				body.take_any_data()
119					.try_into()
120					.map_err(|_| AtspiError::ParseError("accessible-description"))?,
121			)),
122			"accessible-role" => Ok(Self::Role({
123				let role_int: u32 = body
124					.any_data()
125					.try_into()
126					.map_err(|_| AtspiError::ParseError("accessible-role"))?;
127				let role: crate::Role = crate::Role::try_from(role_int)
128					.map_err(|_| AtspiError::ParseError("accessible-role"))?;
129				role
130			})),
131			"accessible-parent" => Ok(Self::Parent(
132				body.take_any_data()
133					.try_into()
134					.map_err(|_| AtspiError::ParseError("accessible-parent"))?,
135			)),
136			"accessible-table-caption" => Ok(Self::TableCaption(
137				body.take_any_data()
138					.try_into()
139					.map_err(|_| AtspiError::ParseError("accessible-table-caption"))?,
140			)),
141			"table-column-description" => Ok(Self::TableColumnDescription(
142				body.take_any_data()
143					.try_into()
144					.map_err(|_| AtspiError::ParseError("table-column-description"))?,
145			)),
146			"table-column-header" => Ok(Self::TableColumnHeader(
147				body.take_any_data()
148					.try_into()
149					.map_err(|_| AtspiError::ParseError("table-column-header"))?,
150			)),
151			"table-row-description" => Ok(Self::TableRowDescription(
152				body.take_any_data()
153					.try_into()
154					.map_err(|_| AtspiError::ParseError("table-row-description"))?,
155			)),
156			"table-row-header" => Ok(Self::TableRowHeader(
157				body.take_any_data()
158					.try_into()
159					.map_err(|_| AtspiError::ParseError("table-row-header"))?,
160			)),
161			"table-summary" => Ok(Self::TableSummary(
162				body.take_any_data()
163					.try_into()
164					.map_err(|_| AtspiError::ParseError("table-summary"))?,
165			)),
166			_ => Ok(Self::Other((property.to_string(), body.take_any_data()))),
167		}
168	}
169}
170
171impl From<Property> for OwnedValue {
172	fn from(property: Property) -> Self {
173		let value = match property {
174			Property::Name(name) => Value::from(name),
175			Property::Description(description) => Value::from(description),
176			Property::Role(role) => Value::from(role as u32),
177			Property::Parent(parent) => Value::from(parent),
178			Property::TableCaption(table_caption) => Value::from(table_caption),
179			Property::TableColumnDescription(table_column_description) => {
180				Value::from(table_column_description)
181			}
182			Property::TableColumnHeader(table_column_header) => Value::from(table_column_header),
183			Property::TableRowDescription(table_row_description) => {
184				Value::from(table_row_description)
185			}
186			Property::TableRowHeader(table_row_header) => Value::from(table_row_header),
187			Property::TableSummary(table_summary) => Value::from(table_summary),
188			Property::Other((_, value)) => value.into(),
189		};
190		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")
191	}
192}
193
194#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
195pub struct BoundsChangedEvent {
196	/// The [`crate::ObjectRef`] which the event applies to.
197	pub item: crate::events::ObjectRef,
198}
199
200impl_event_type_properties_for_event!(BoundsChangedEvent);
201
202#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
203pub struct LinkSelectedEvent {
204	/// The [`crate::ObjectRef`] which the event applies to.
205	pub item: crate::events::ObjectRef,
206}
207
208impl_event_type_properties_for_event!(LinkSelectedEvent);
209
210/// A state of an object has been modified.
211/// A [`State`] can be added or removed from any [`crate::ObjectRef`].
212#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
213pub struct StateChangedEvent {
214	/// The [`crate::ObjectRef`] which the event applies to.
215	pub item: crate::events::ObjectRef,
216	/// The state to be enabled/disabled.
217	pub state: State,
218	/// Whether the state was enabled or disabled.
219	#[serde(with = "i32_bool_conversion")]
220	pub enabled: bool,
221}
222
223impl_event_type_properties_for_event!(StateChangedEvent);
224
225mod i32_bool_conversion {
226	use serde::{Deserialize, Deserializer, Serializer};
227	/// Convert an integer flag to a boolean.
228	/// returns true if value is more than 0, otherwise false
229	pub fn deserialize<'de, D>(de: D) -> Result<bool, D::Error>
230	where
231		D: Deserializer<'de>,
232	{
233		let int: i32 = Deserialize::deserialize(de)?;
234		Ok(int > 0)
235	}
236
237	/// Convert a boolean flag to an integer.
238	/// returns 0 if false and 1 if true
239	// TODO: Will the world REALLY fall apart if we were not to use a reference here?
240	// In other words, see if &bool can be replaced with bool.
241	#[allow(clippy::trivially_copy_pass_by_ref)]
242	pub fn serialize<S>(b: &bool, ser: S) -> Result<S::Ok, S::Error>
243	where
244		S: Serializer,
245	{
246		let val: i32 = (*b).into();
247		ser.serialize_i32(val)
248	}
249}
250
251/// A child of an [`crate::ObjectRef`] has been added or removed.
252#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
253pub struct ChildrenChangedEvent {
254	/// The [`crate::ObjectRef`] which the event applies to.
255	pub item: crate::events::ObjectRef,
256	/// The [`crate::Operation`] being performed.
257	pub operation: crate::Operation,
258	/// Index to remove from/add to.
259	pub index_in_parent: i32,
260	/// A reference to the new child.
261	pub child: ObjectRef,
262}
263
264impl_event_type_properties_for_event!(ChildrenChangedEvent);
265
266#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
267pub struct VisibleDataChangedEvent {
268	/// The [`crate::ObjectRef`] which the event applies to.
269	pub item: crate::events::ObjectRef,
270}
271
272impl_event_type_properties_for_event!(VisibleDataChangedEvent);
273
274#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
275pub struct SelectionChangedEvent {
276	/// The [`crate::ObjectRef`] which the event applies to.
277	pub item: crate::events::ObjectRef,
278}
279
280impl_event_type_properties_for_event!(SelectionChangedEvent);
281
282#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
283pub struct ModelChangedEvent {
284	/// The [`crate::ObjectRef`] which the event applies to.
285	pub item: crate::events::ObjectRef,
286}
287
288impl_event_type_properties_for_event!(ModelChangedEvent);
289
290#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
291pub struct ActiveDescendantChangedEvent {
292	/// The [`crate::ObjectRef`] which the event applies to.
293	pub item: crate::events::ObjectRef,
294	pub child: ObjectRef,
295}
296
297impl_event_type_properties_for_event!(ActiveDescendantChangedEvent);
298
299#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
300pub struct AnnouncementEvent {
301	/// The [`crate::ObjectRef`] which the event applies to.
302	pub item: crate::events::ObjectRef,
303	/// Text of the announcement.
304	pub text: String,
305	/// Politeness level.
306	pub live: crate::Politeness,
307}
308
309impl_event_type_properties_for_event!(AnnouncementEvent);
310
311#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
312pub struct AttributesChangedEvent {
313	/// The [`crate::ObjectRef`] which the event applies to.
314	pub item: crate::events::ObjectRef,
315}
316
317impl_event_type_properties_for_event!(AttributesChangedEvent);
318
319/// A row has been added to a table.
320#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
321pub struct RowInsertedEvent {
322	/// The table which has had a row inserted.
323	pub item: crate::events::ObjectRef,
324}
325
326impl_event_type_properties_for_event!(RowInsertedEvent);
327
328/// A row has been moved within a table.
329#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
330pub struct RowReorderedEvent {
331	/// The table which has had a row re-ordered.
332	pub item: crate::events::ObjectRef,
333}
334
335impl_event_type_properties_for_event!(RowReorderedEvent);
336
337/// A row has been deleted from a table.
338#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
339pub struct RowDeletedEvent {
340	/// The table which has had a row removed.
341	pub item: crate::events::ObjectRef,
342}
343
344impl_event_type_properties_for_event!(RowDeletedEvent);
345
346/// A column has been added to a table.
347#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
348pub struct ColumnInsertedEvent {
349	/// The table which has had a column inserted.
350	pub item: crate::events::ObjectRef,
351}
352
353impl_event_type_properties_for_event!(ColumnInsertedEvent);
354
355/// A column has been re-ordered within a table.
356#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
357pub struct ColumnReorderedEvent {
358	/// The table which has had a column re-ordered.
359	pub item: crate::events::ObjectRef,
360}
361
362impl_event_type_properties_for_event!(ColumnReorderedEvent);
363
364/// A column has been removed from a table.
365#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
366pub struct ColumnDeletedEvent {
367	/// The table which has had a column removed.
368	pub item: crate::events::ObjectRef,
369}
370
371impl_event_type_properties_for_event!(ColumnDeletedEvent);
372
373#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
374pub struct TextBoundsChangedEvent {
375	/// The [`crate::ObjectRef`] which the event applies to.
376	pub item: crate::events::ObjectRef,
377}
378
379impl_event_type_properties_for_event!(TextBoundsChangedEvent);
380
381#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
382pub struct TextSelectionChangedEvent {
383	/// The [`crate::ObjectRef`] which the event applies to.
384	pub item: crate::events::ObjectRef,
385}
386
387impl_event_type_properties_for_event!(TextSelectionChangedEvent);
388
389/// Text has changed within an [`crate::ObjectRef`].
390#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
391pub struct TextChangedEvent {
392	/// The [`crate::ObjectRef`] which the event applies to.
393	pub item: crate::events::ObjectRef,
394	/// The [`crate::Operation`] being performed.
395	pub operation: crate::Operation,
396	/// starting index of the insertion/deletion
397	pub start_pos: i32,
398	/// length of the insertion/deletion
399	pub length: i32,
400	/// the text being inserted/deleted
401	pub text: String,
402}
403
404impl_event_type_properties_for_event!(TextChangedEvent);
405
406/// Signal that some attributes about the text (usually styling) have changed.
407/// This event does not encode _what_ has changed about the attributes, merely that they have
408/// changed.
409#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
410pub struct TextAttributesChangedEvent {
411	/// The [`crate::ObjectRef`] which the event applies to.
412	pub item: crate::events::ObjectRef,
413}
414
415impl_event_type_properties_for_event!(TextAttributesChangedEvent);
416
417/// The caret of the user also known as a cursor (not to be confused with mouse pointer) has changed position.
418#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
419pub struct TextCaretMovedEvent {
420	/// The object on which the caret has been moved on.
421	pub item: crate::events::ObjectRef,
422	/// New position of the caret.
423	pub position: i32,
424}
425
426impl_event_type_properties_for_event!(TextCaretMovedEvent);
427
428impl_member_interface_registry_string_and_match_rule_for_event!(
429	PropertyChangeEvent,
430	"PropertyChange",
431	"org.a11y.atspi.Event.Object",
432	"object:property-change",
433	"type='signal',interface='org.a11y.atspi.Event.Object',member='PropertyChange'"
434);
435
436#[cfg(feature = "zbus")]
437impl MessageConversion<'_> for PropertyChangeEvent {
438	type Body<'b> = EventBody<'b>;
439
440	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
441		let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
442		let property: String = body.take_kind();
443		let value: Property = body.try_into()?;
444		Ok(Self { item, property, value })
445	}
446
447	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
448		let item = header.try_into()?;
449		let body = msg.body();
450		Self::from_message_unchecked_parts(item, body)
451	}
452
453	fn body(&self) -> Self::Body<'_> {
454		let copy = self.clone();
455		EventBodyOwned::from(copy).into()
456	}
457}
458
459impl_member_interface_registry_string_and_match_rule_for_event!(
460	BoundsChangedEvent,
461	"BoundsChanged",
462	"org.a11y.atspi.Event.Object",
463	"object:bounds-changed",
464	"type='signal',interface='org.a11y.atspi.Event.Object',member='BoundsChanged'"
465);
466
467impl_member_interface_registry_string_and_match_rule_for_event!(
468	LinkSelectedEvent,
469	"LinkSelected",
470	"org.a11y.atspi.Event.Object",
471	"object:link-selected",
472	"type='signal',interface='org.a11y.atspi.Event.Object',member='LinkSelected'"
473);
474
475impl_member_interface_registry_string_and_match_rule_for_event!(
476	StateChangedEvent,
477	"StateChanged",
478	"org.a11y.atspi.Event.Object",
479	"object:state-changed",
480	"type='signal',interface='org.a11y.atspi.Event.Object',member='StateChanged'"
481);
482
483#[cfg(feature = "zbus")]
484impl MessageConversion<'_> for StateChangedEvent {
485	type Body<'a> = EventBody<'a>;
486
487	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
488		let body: Self::Body<'_> = body.deserialize_unchecked()?;
489		Ok(Self { item, state: body.kind().into(), enabled: body.detail1() > 0 })
490	}
491
492	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
493		let item = header.try_into()?;
494		let body = msg.body();
495		Self::from_message_unchecked_parts(item, body)
496	}
497
498	fn body(&self) -> Self::Body<'_> {
499		let copy = self.clone();
500		copy.into()
501	}
502}
503
504impl_member_interface_registry_string_and_match_rule_for_event!(
505	ChildrenChangedEvent,
506	"ChildrenChanged",
507	"org.a11y.atspi.Event.Object",
508	"object:children-changed",
509	"type='signal',interface='org.a11y.atspi.Event.Object',member='ChildrenChanged'"
510);
511
512#[cfg(feature = "zbus")]
513impl MessageConversion<'_> for ChildrenChangedEvent {
514	type Body<'a> = EventBody<'a>;
515
516	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
517		let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
518		Ok(Self {
519			item,
520			operation: body.kind().parse()?,
521			index_in_parent: body.detail1(),
522			child: body.take_any_data().try_into()?,
523		})
524	}
525
526	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
527		let item = header.try_into()?;
528		let body = msg.body();
529		Self::from_message_unchecked_parts(item, body)
530	}
531
532	fn body(&self) -> Self::Body<'_> {
533		EventBodyOwned::from(self.clone()).into()
534	}
535}
536
537impl_member_interface_registry_string_and_match_rule_for_event!(
538	VisibleDataChangedEvent,
539	"VisibleDataChanged",
540	"org.a11y.atspi.Event.Object",
541	"object:visible-data-changed",
542	"type='signal',interface='org.a11y.atspi.Event.Object',member='VisibleDataChanged'"
543);
544
545impl_member_interface_registry_string_and_match_rule_for_event!(
546	SelectionChangedEvent,
547	"SelectionChanged",
548	"org.a11y.atspi.Event.Object",
549	"object:selection-changed",
550	"type='signal',interface='org.a11y.atspi.Event.Object',member='SelectionChanged'"
551);
552
553impl_member_interface_registry_string_and_match_rule_for_event!(
554	ModelChangedEvent,
555	"ModelChanged",
556	"org.a11y.atspi.Event.Object",
557	"object:model-changed",
558	"type='signal',interface='org.a11y.atspi.Event.Object',member='ModelChanged'"
559);
560
561impl_member_interface_registry_string_and_match_rule_for_event!(
562	ActiveDescendantChangedEvent,
563	"ActiveDescendantChanged",
564	"org.a11y.atspi.Event.Object",
565	"object:active-descendant-changed",
566	"type='signal',interface='org.a11y.atspi.Event.Object',member='ActiveDescendantChanged'"
567);
568
569#[cfg(feature = "zbus")]
570impl MessageConversion<'_> for ActiveDescendantChangedEvent {
571	type Body<'a> = EventBody<'a>;
572
573	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
574		let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
575		Ok(Self { item, child: body.take_any_data().try_into()? })
576	}
577
578	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
579		let item = header.try_into()?;
580		let body = msg.body();
581		Self::from_message_unchecked_parts(item, body)
582	}
583
584	fn body(&self) -> Self::Body<'_> {
585		EventBodyOwned::from(self.clone()).into()
586	}
587}
588
589impl_member_interface_registry_string_and_match_rule_for_event!(
590	AnnouncementEvent,
591	"Announcement",
592	"org.a11y.atspi.Event.Object",
593	"object:announcement",
594	"type='signal',interface='org.a11y.atspi.Event.Object',member='Announcement'"
595);
596
597#[cfg(feature = "zbus")]
598impl MessageConversion<'_> for AnnouncementEvent {
599	type Body<'a> = EventBody<'a>;
600
601	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
602		let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
603		Ok(Self {
604			item,
605			text: body
606				.take_any_data()
607				.try_into()
608				.map_err(|_| AtspiError::Conversion("text"))?,
609			live: body.detail1().try_into()?,
610		})
611	}
612
613	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
614		let item = header.try_into()?;
615		let body = msg.body();
616		Self::from_message_unchecked_parts(item, body)
617	}
618
619	fn body(&self) -> Self::Body<'_> {
620		EventBodyOwned::from(self.clone()).into()
621	}
622}
623
624impl_member_interface_registry_string_and_match_rule_for_event!(
625	AttributesChangedEvent,
626	"AttributesChanged",
627	"org.a11y.atspi.Event.Object",
628	"object:attributes-changed",
629	"type='signal',interface='org.a11y.atspi.Event.Object',member='AttributesChanged'"
630);
631
632impl_member_interface_registry_string_and_match_rule_for_event!(
633	RowInsertedEvent,
634	"RowInserted",
635	"org.a11y.atspi.Event.Object",
636	"object:row-inserted",
637	"type='signal',interface='org.a11y.atspi.Event.Object',member='RowInserted'"
638);
639
640impl_member_interface_registry_string_and_match_rule_for_event!(
641	RowReorderedEvent,
642	"RowReordered",
643	"org.a11y.atspi.Event.Object",
644	"object:row-reordered",
645	"type='signal',interface='org.a11y.atspi.Event.Object',member='RowReordered'"
646);
647
648impl_member_interface_registry_string_and_match_rule_for_event!(
649	RowDeletedEvent,
650	"RowDeleted",
651	"org.a11y.atspi.Event.Object",
652	"object:row-deleted",
653	"type='signal',interface='org.a11y.atspi.Event.Object',member='RowDeleted'"
654);
655
656impl_member_interface_registry_string_and_match_rule_for_event!(
657	ColumnInsertedEvent,
658	"ColumnInserted",
659	"org.a11y.atspi.Event.Object",
660	"object:column-inserted",
661	"type='signal',interface='org.a11y.atspi.Event.Object',member='ColumnInserted'"
662);
663
664impl_member_interface_registry_string_and_match_rule_for_event!(
665	ColumnReorderedEvent,
666	"ColumnReordered",
667	"org.a11y.atspi.Event.Object",
668	"object:column-reordered",
669	"type='signal',interface='org.a11y.atspi.Event.Object',member='ColumnReordered'"
670);
671
672impl_member_interface_registry_string_and_match_rule_for_event!(
673	ColumnDeletedEvent,
674	"ColumnDeleted",
675	"org.a11y.atspi.Event.Object",
676	"object:column-deleted",
677	"type='signal',interface='org.a11y.atspi.Event.Object',member='ColumnDeleted'"
678);
679
680impl_member_interface_registry_string_and_match_rule_for_event!(
681	TextBoundsChangedEvent,
682	"TextBoundsChanged",
683	"org.a11y.atspi.Event.Object",
684	"object:text-bounds-changed",
685	"type='signal',interface='org.a11y.atspi.Event.Object',member='TextBoundsChanged'"
686);
687
688impl_member_interface_registry_string_and_match_rule_for_event!(
689	TextSelectionChangedEvent,
690	"TextSelectionChanged",
691	"org.a11y.atspi.Event.Object",
692	"object:text-selection-changed",
693	"type='signal',interface='org.a11y.atspi.Event.Object',member='TextSelectionChanged'"
694);
695
696impl_member_interface_registry_string_and_match_rule_for_event!(
697	TextChangedEvent,
698	"TextChanged",
699	"org.a11y.atspi.Event.Object",
700	"object:text-changed",
701	"type='signal',interface='org.a11y.atspi.Event.Object',member='TextChanged'"
702);
703
704#[cfg(feature = "zbus")]
705impl MessageConversion<'_> for TextChangedEvent {
706	type Body<'a> = EventBody<'a>;
707
708	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
709		let mut body = body.deserialize_unchecked::<Self::Body<'_>>()?;
710		Ok(Self {
711			item,
712			operation: body.kind().parse()?,
713			start_pos: body.detail1(),
714			length: body.detail2(),
715			text: body.take_any_data().try_into()?,
716		})
717	}
718
719	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
720		let item = header.try_into()?;
721		let body = msg.body();
722		Self::from_message_unchecked_parts(item, body)
723	}
724
725	fn body(&self) -> Self::Body<'_> {
726		EventBodyOwned::from(self.clone()).into()
727	}
728}
729
730impl_member_interface_registry_string_and_match_rule_for_event!(
731	TextAttributesChangedEvent,
732	"TextAttributesChanged",
733	"org.a11y.atspi.Event.Object",
734	"object:text-attributes-changed",
735	"type='signal',interface='org.a11y.atspi.Event.Object',member='TextAttributesChanged'"
736);
737
738impl_member_interface_registry_string_and_match_rule_for_event!(
739	TextCaretMovedEvent,
740	"TextCaretMoved",
741	"org.a11y.atspi.Event.Object",
742	"object:text-caret-moved",
743	"type='signal',interface='org.a11y.atspi.Event.Object',member='TextCaretMoved'"
744);
745
746#[cfg(feature = "zbus")]
747impl MessageConversion<'_> for TextCaretMovedEvent {
748	type Body<'a> = EventBody<'a>;
749
750	fn from_message_unchecked_parts(item: ObjectRef, body: DbusBody) -> Result<Self, AtspiError> {
751		let body = body.deserialize_unchecked::<Self::Body<'_>>()?;
752		Ok(Self { item, position: body.detail1() })
753	}
754
755	fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError> {
756		let item = header.try_into()?;
757		let body = msg.body();
758		Self::from_message_unchecked_parts(item, body)
759	}
760
761	fn body(&self) -> Self::Body<'_> {
762		EventBodyOwned::from(self.clone()).into()
763	}
764}
765
766event_test_cases!(PropertyChangeEvent);
767impl_to_dbus_message!(PropertyChangeEvent);
768impl_from_dbus_message!(PropertyChangeEvent);
769impl_event_properties!(PropertyChangeEvent);
770
771impl From<PropertyChangeEvent> for EventBodyOwned {
772	fn from(event: PropertyChangeEvent) -> Self {
773		EventBodyOwned { kind: event.property, any_data: event.value.into(), ..Default::default() }
774	}
775}
776
777impl From<&PropertyChangeEvent> for EventBodyOwned {
778	fn from(event: &PropertyChangeEvent) -> Self {
779		EventBodyOwned {
780			kind: event.property.to_string(),
781			any_data: event.value.clone().into(),
782			..Default::default()
783		}
784	}
785}
786
787impl From<PropertyChangeEvent> for EventBody<'_> {
788	fn from(event: PropertyChangeEvent) -> Self {
789		EventBodyOwned::from(event).into()
790	}
791}
792
793event_test_cases!(BoundsChangedEvent);
794impl_to_dbus_message!(BoundsChangedEvent);
795impl_from_dbus_message!(BoundsChangedEvent);
796impl_event_properties!(BoundsChangedEvent);
797impl_from_object_ref!(BoundsChangedEvent);
798
799event_test_cases!(LinkSelectedEvent);
800impl_to_dbus_message!(LinkSelectedEvent);
801impl_from_dbus_message!(LinkSelectedEvent);
802impl_event_properties!(LinkSelectedEvent);
803impl_from_object_ref!(LinkSelectedEvent);
804
805event_test_cases!(StateChangedEvent);
806impl_to_dbus_message!(StateChangedEvent);
807impl_from_dbus_message!(StateChangedEvent);
808impl_event_properties!(StateChangedEvent);
809
810impl From<StateChangedEvent> for EventBodyOwned {
811	fn from(event: StateChangedEvent) -> Self {
812		EventBodyOwned {
813			kind: event.state.to_string(),
814			detail1: event.enabled.into(),
815			..Default::default()
816		}
817	}
818}
819
820impl From<&StateChangedEvent> for EventBodyOwned {
821	fn from(event: &StateChangedEvent) -> Self {
822		EventBodyOwned {
823			kind: event.state.to_string(),
824			detail1: event.enabled.into(),
825			..Default::default()
826		}
827	}
828}
829
830impl From<StateChangedEvent> for EventBody<'_> {
831	fn from(event: StateChangedEvent) -> Self {
832		EventBodyOwned::from(event).into()
833	}
834}
835
836event_test_cases!(ChildrenChangedEvent);
837impl_to_dbus_message!(ChildrenChangedEvent);
838impl_from_dbus_message!(ChildrenChangedEvent);
839impl_event_properties!(ChildrenChangedEvent);
840
841impl From<ChildrenChangedEvent> for EventBodyOwned {
842	fn from(event: ChildrenChangedEvent) -> Self {
843		EventBodyOwned {
844			kind: event.operation.to_string(),
845			detail1: event.index_in_parent,
846
847			// `OwnedValue` is constructed from the `crate::ObjectRef`
848			// Only way to fail is to convert a `Fd` into an `OwnedValue`.
849			// Therefore, this is safe.
850			any_data: Value::from(event.child)
851				.try_into()
852				.expect("Failed to convert child to OwnedValue"),
853			..Default::default()
854		}
855	}
856}
857
858impl From<&ChildrenChangedEvent> for EventBodyOwned {
859	fn from(event: &ChildrenChangedEvent) -> Self {
860		EventBodyOwned {
861			kind: event.operation.to_string(),
862			detail1: event.index_in_parent,
863			detail2: i32::default(),
864			// `OwnedValue` is constructed from the `crate::ObjectRef`
865			// Only path to fail is to convert a `Fd` into an `OwnedValue`.
866			// Therefore, this is safe.
867			any_data: Value::from(event.child.clone())
868				.try_into()
869				.expect("ObjectRef should convert to OwnedValue without error"),
870			properties: super::event_body::Properties,
871		}
872	}
873}
874
875impl From<ChildrenChangedEvent> for EventBody<'_> {
876	fn from(event: ChildrenChangedEvent) -> Self {
877		EventBodyOwned::from(event).into()
878	}
879}
880
881event_test_cases!(VisibleDataChangedEvent);
882impl_to_dbus_message!(VisibleDataChangedEvent);
883impl_from_dbus_message!(VisibleDataChangedEvent);
884impl_event_properties!(VisibleDataChangedEvent);
885impl_from_object_ref!(VisibleDataChangedEvent);
886
887event_test_cases!(SelectionChangedEvent);
888impl_to_dbus_message!(SelectionChangedEvent);
889impl_from_dbus_message!(SelectionChangedEvent);
890impl_event_properties!(SelectionChangedEvent);
891impl_from_object_ref!(SelectionChangedEvent);
892
893event_test_cases!(ModelChangedEvent);
894impl_to_dbus_message!(ModelChangedEvent);
895impl_from_dbus_message!(ModelChangedEvent);
896impl_event_properties!(ModelChangedEvent);
897impl_from_object_ref!(ModelChangedEvent);
898
899event_test_cases!(ActiveDescendantChangedEvent);
900impl_to_dbus_message!(ActiveDescendantChangedEvent);
901impl_from_dbus_message!(ActiveDescendantChangedEvent);
902impl_event_properties!(ActiveDescendantChangedEvent);
903impl From<ActiveDescendantChangedEvent> for EventBodyOwned {
904	fn from(event: ActiveDescendantChangedEvent) -> Self {
905		EventBodyOwned {
906			// `OwnedValue` is constructed from the `crate::ObjectRef`
907			// Only way to fail is to convert a Fd into an `OwnedValue`.
908			// Therefore, this is safe.
909			any_data: Value::from(event.child)
910				.try_to_owned()
911				.expect("Failed to convert child to OwnedValue"),
912			..Default::default()
913		}
914	}
915}
916
917event_test_cases!(AnnouncementEvent);
918impl_to_dbus_message!(AnnouncementEvent);
919impl_from_dbus_message!(AnnouncementEvent);
920impl_event_properties!(AnnouncementEvent);
921impl From<AnnouncementEvent> for EventBodyOwned {
922	fn from(event: AnnouncementEvent) -> Self {
923		EventBodyOwned {
924			detail1: event.live as i32,
925			// `OwnedValue` is constructed from `String`
926			// Therefore, this is safe.
927			any_data: Value::from(event.text)
928				.try_to_owned()
929				.expect("Failed to convert text to OwnedValue"),
930			..Default::default()
931		}
932	}
933}
934
935event_test_cases!(AttributesChangedEvent);
936impl_to_dbus_message!(AttributesChangedEvent);
937impl_from_dbus_message!(AttributesChangedEvent);
938impl_event_properties!(AttributesChangedEvent);
939impl_from_object_ref!(AttributesChangedEvent);
940
941event_test_cases!(RowInsertedEvent);
942impl_to_dbus_message!(RowInsertedEvent);
943impl_from_dbus_message!(RowInsertedEvent);
944impl_event_properties!(RowInsertedEvent);
945impl_from_object_ref!(RowInsertedEvent);
946
947event_test_cases!(RowReorderedEvent);
948impl_to_dbus_message!(RowReorderedEvent);
949impl_from_dbus_message!(RowReorderedEvent);
950impl_event_properties!(RowReorderedEvent);
951impl_from_object_ref!(RowReorderedEvent);
952
953event_test_cases!(RowDeletedEvent);
954impl_to_dbus_message!(RowDeletedEvent);
955impl_from_dbus_message!(RowDeletedEvent);
956impl_event_properties!(RowDeletedEvent);
957impl_from_object_ref!(RowDeletedEvent);
958
959event_test_cases!(ColumnInsertedEvent);
960impl_to_dbus_message!(ColumnInsertedEvent);
961impl_from_dbus_message!(ColumnInsertedEvent);
962impl_event_properties!(ColumnInsertedEvent);
963impl_from_object_ref!(ColumnInsertedEvent);
964
965event_test_cases!(ColumnReorderedEvent);
966impl_to_dbus_message!(ColumnReorderedEvent);
967impl_from_dbus_message!(ColumnReorderedEvent);
968impl_event_properties!(ColumnReorderedEvent);
969impl_from_object_ref!(ColumnReorderedEvent);
970
971event_test_cases!(ColumnDeletedEvent);
972impl_to_dbus_message!(ColumnDeletedEvent);
973impl_from_dbus_message!(ColumnDeletedEvent);
974impl_event_properties!(ColumnDeletedEvent);
975impl_from_object_ref!(ColumnDeletedEvent);
976
977event_test_cases!(TextBoundsChangedEvent);
978impl_to_dbus_message!(TextBoundsChangedEvent);
979impl_from_dbus_message!(TextBoundsChangedEvent);
980impl_event_properties!(TextBoundsChangedEvent);
981impl_from_object_ref!(TextBoundsChangedEvent);
982
983event_test_cases!(TextSelectionChangedEvent);
984impl_to_dbus_message!(TextSelectionChangedEvent);
985impl_from_dbus_message!(TextSelectionChangedEvent);
986impl_event_properties!(TextSelectionChangedEvent);
987impl_from_object_ref!(TextSelectionChangedEvent);
988
989event_test_cases!(TextChangedEvent);
990
991assert_impl_all!(TextChangedEvent:Clone,std::fmt::Debug,serde::Serialize,serde::Deserialize<'static>,Default,PartialEq,Eq,std::hash::Hash,crate::EventProperties,crate::EventTypeProperties);
992#[cfg(feature = "zbus")]
993assert_impl_all!(zbus::Message:TryFrom<TextChangedEvent>);
994
995impl_to_dbus_message!(TextChangedEvent);
996impl_from_dbus_message!(TextChangedEvent);
997impl_event_properties!(TextChangedEvent);
998impl From<TextChangedEvent> for EventBodyOwned {
999	fn from(event: TextChangedEvent) -> Self {
1000		EventBodyOwned {
1001			kind: event.operation.to_string(),
1002			detail1: event.start_pos,
1003			detail2: event.length,
1004			// `OwnedValue` is constructed from a `String`
1005			// Therefore, this is safe.
1006			any_data: Value::from(event.text)
1007				.try_to_owned()
1008				.expect("Failed to convert child to OwnedValue"),
1009			..Default::default()
1010		}
1011	}
1012}
1013
1014event_test_cases!(TextAttributesChangedEvent);
1015impl_to_dbus_message!(TextAttributesChangedEvent);
1016impl_from_dbus_message!(TextAttributesChangedEvent);
1017impl_event_properties!(TextAttributesChangedEvent);
1018impl_from_object_ref!(TextAttributesChangedEvent);
1019
1020event_test_cases!(TextCaretMovedEvent);
1021impl_to_dbus_message!(TextCaretMovedEvent);
1022impl_from_dbus_message!(TextCaretMovedEvent);
1023impl_event_properties!(TextCaretMovedEvent);
1024impl From<TextCaretMovedEvent> for EventBodyOwned {
1025	fn from(event: TextCaretMovedEvent) -> Self {
1026		EventBodyOwned { detail1: event.position, ..Default::default() }
1027	}
1028}
1029
1030impl_msg_conversion_ext_for_target_type!(PropertyChangeEvent);
1031impl_msg_conversion_ext_for_target_type!(BoundsChangedEvent);
1032impl_msg_conversion_ext_for_target_type!(LinkSelectedEvent);
1033impl_msg_conversion_ext_for_target_type!(StateChangedEvent);
1034impl_msg_conversion_ext_for_target_type!(ChildrenChangedEvent);
1035impl_msg_conversion_ext_for_target_type!(VisibleDataChangedEvent);
1036impl_msg_conversion_ext_for_target_type!(SelectionChangedEvent);
1037impl_msg_conversion_ext_for_target_type!(ModelChangedEvent);
1038impl_msg_conversion_ext_for_target_type!(ActiveDescendantChangedEvent);
1039impl_msg_conversion_ext_for_target_type!(AnnouncementEvent);
1040impl_msg_conversion_ext_for_target_type!(AttributesChangedEvent);
1041impl_msg_conversion_ext_for_target_type!(RowInsertedEvent);
1042impl_msg_conversion_ext_for_target_type!(RowReorderedEvent);
1043impl_msg_conversion_ext_for_target_type!(RowDeletedEvent);
1044impl_msg_conversion_ext_for_target_type!(ColumnInsertedEvent);
1045impl_msg_conversion_ext_for_target_type!(ColumnReorderedEvent);
1046impl_msg_conversion_ext_for_target_type!(ColumnDeletedEvent);
1047impl_msg_conversion_ext_for_target_type!(TextBoundsChangedEvent);
1048impl_msg_conversion_ext_for_target_type!(TextSelectionChangedEvent);
1049impl_msg_conversion_ext_for_target_type!(TextChangedEvent);
1050impl_msg_conversion_ext_for_target_type!(TextAttributesChangedEvent);
1051impl_msg_conversion_ext_for_target_type!(TextCaretMovedEvent);
1052
1053impl_msg_conversion_for_types_built_from_object_ref!(BoundsChangedEvent);
1054impl_msg_conversion_for_types_built_from_object_ref!(LinkSelectedEvent);
1055impl_msg_conversion_for_types_built_from_object_ref!(VisibleDataChangedEvent);
1056impl_msg_conversion_for_types_built_from_object_ref!(SelectionChangedEvent);
1057impl_msg_conversion_for_types_built_from_object_ref!(ModelChangedEvent);
1058impl_msg_conversion_for_types_built_from_object_ref!(AttributesChangedEvent);
1059impl_msg_conversion_for_types_built_from_object_ref!(RowInsertedEvent);
1060impl_msg_conversion_for_types_built_from_object_ref!(RowReorderedEvent);
1061impl_msg_conversion_for_types_built_from_object_ref!(RowDeletedEvent);
1062impl_msg_conversion_for_types_built_from_object_ref!(ColumnInsertedEvent);
1063impl_msg_conversion_for_types_built_from_object_ref!(ColumnReorderedEvent);
1064impl_msg_conversion_for_types_built_from_object_ref!(ColumnDeletedEvent);
1065impl_msg_conversion_for_types_built_from_object_ref!(TextBoundsChangedEvent);
1066impl_msg_conversion_for_types_built_from_object_ref!(TextSelectionChangedEvent);
1067impl_msg_conversion_for_types_built_from_object_ref!(TextAttributesChangedEvent);