atspi_common/events/
object.rs

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/// The `org.a11y.atspi.Event.Object:PropertyChange` event.
32#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
33pub struct PropertyChangeEvent {
34	/// The [`crate::ObjectRef`] which the event applies to.
35	pub item: crate::events::ObjectRef,
36	// TODO: this is not necessary since the string is encoded in the `Property` type.
37	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
50// Do not derive Eq if not all fields implement Eq
51impl Eq for PropertyChangeEvent {}
52
53// TODO: Looks like a false positive Clippy lint
54// Derive me.
55#[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/// Any accessibility related property on an [`crate::ObjectRef`].
63/// This is used only in the [`PropertyChangeEvent`]; this event gets triggered if a role or accessible
64/// description of an item changes.
65#[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	/// The [`crate::ObjectRef`] which the event applies to.
300	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	/// The [`crate::ObjectRef`] which the event applies to.
308	pub item: crate::events::ObjectRef,
309}
310
311impl_event_type_properties_for_event!(LinkSelectedEvent);
312
313/// A state of an object has been modified.
314/// A [`State`] can be added or removed from any [`crate::ObjectRef`].
315#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
316pub struct StateChangedEvent {
317	/// The [`crate::ObjectRef`] which the event applies to.
318	pub item: crate::events::ObjectRef,
319	/// The state to be enabled/disabled.
320	pub state: State,
321	/// Whether the state was enabled or disabled.
322	#[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	/// Convert an integer flag to a boolean.
331	/// returns true if value is more than 0, otherwise false
332	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	/// Convert a boolean flag to an integer.
341	/// returns 0 if false and 1 if true
342	// TODO: Will the world REALLY fall apart if we were not to use a reference here?
343	// In other words, see if &bool can be replaced with bool.
344	#[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/// A child of an [`crate::ObjectRef`] has been added or removed.
355#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
356pub struct ChildrenChangedEvent {
357	/// The [`crate::ObjectRef`] which the event applies to.
358	pub item: crate::events::ObjectRef,
359	/// The [`crate::Operation`] being performed.
360	pub operation: crate::Operation,
361	/// Index to remove from/add to.
362	pub index_in_parent: i32,
363	/// A reference to the new child.
364	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	/// The [`crate::ObjectRef`] which the event applies to.
372	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	/// The [`crate::ObjectRef`] which the event applies to.
380	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	/// The [`crate::ObjectRef`] which the event applies to.
388	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	/// The [`crate::ObjectRef`] which the event applies to.
396	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	/// The [`crate::ObjectRef`] which the event applies to.
405	pub item: crate::events::ObjectRef,
406	/// Text of the announcement.
407	pub text: String,
408	/// Politeness level.
409	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	/// The [`crate::ObjectRef`] which the event applies to.
417	pub item: crate::events::ObjectRef,
418}
419
420impl_event_type_properties_for_event!(AttributesChangedEvent);
421
422/// A row has been added to a table.
423#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
424pub struct RowInsertedEvent {
425	/// The table which has had a row inserted.
426	pub item: crate::events::ObjectRef,
427}
428
429impl_event_type_properties_for_event!(RowInsertedEvent);
430
431/// A row has been moved within a table.
432#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
433pub struct RowReorderedEvent {
434	/// The table which has had a row re-ordered.
435	pub item: crate::events::ObjectRef,
436}
437
438impl_event_type_properties_for_event!(RowReorderedEvent);
439
440/// A row has been deleted from a table.
441#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
442pub struct RowDeletedEvent {
443	/// The table which has had a row removed.
444	pub item: crate::events::ObjectRef,
445}
446
447impl_event_type_properties_for_event!(RowDeletedEvent);
448
449/// A column has been added to a table.
450#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
451pub struct ColumnInsertedEvent {
452	/// The table which has had a column inserted.
453	pub item: crate::events::ObjectRef,
454}
455
456impl_event_type_properties_for_event!(ColumnInsertedEvent);
457
458/// A column has been re-ordered within a table.
459#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
460pub struct ColumnReorderedEvent {
461	/// The table which has had a column re-ordered.
462	pub item: crate::events::ObjectRef,
463}
464
465impl_event_type_properties_for_event!(ColumnReorderedEvent);
466
467/// A column has been removed from a table.
468#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
469pub struct ColumnDeletedEvent {
470	/// The table which has had a column removed.
471	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	/// The [`crate::ObjectRef`] which the event applies to.
479	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	/// The [`crate::ObjectRef`] which the event applies to.
487	pub item: crate::events::ObjectRef,
488}
489
490impl_event_type_properties_for_event!(TextSelectionChangedEvent);
491
492/// Text has changed within an [`crate::ObjectRef`].
493#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
494pub struct TextChangedEvent {
495	/// The [`crate::ObjectRef`] which the event applies to.
496	pub item: crate::events::ObjectRef,
497	/// The [`crate::Operation`] being performed.
498	pub operation: crate::Operation,
499	/// starting index of the insertion/deletion
500	pub start_pos: i32,
501	/// length of the insertion/deletion
502	pub length: i32,
503	/// the text being inserted/deleted
504	pub text: String,
505}
506
507impl_event_type_properties_for_event!(TextChangedEvent);
508
509/// Signal that some attributes about the text (usually styling) have changed.
510/// This event does not encode _what_ has changed about the attributes, merely that they have
511/// changed.
512#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
513pub struct TextAttributesChangedEvent {
514	/// The [`crate::ObjectRef`] which the event applies to.
515	pub item: crate::events::ObjectRef,
516}
517
518impl_event_type_properties_for_event!(TextAttributesChangedEvent);
519
520/// The caret of the user also known as a cursor (not to be confused with mouse pointer) has changed position.
521#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, Eq, Hash, Default)]
522pub struct TextCaretMovedEvent {
523	/// The object on which the caret has been moved on.
524	pub item: crate::events::ObjectRef,
525	/// New position of the caret.
526	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			// `OwnedValue` is constructed from the `crate::ObjectRef`
951			// Only way to fail is to convert a `Fd` into an `OwnedValue`.
952			// Therefore, this is safe.
953			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			// `OwnedValue` is constructed from the `crate::ObjectRef`
968			// Only path to fail is to convert a `Fd` into an `OwnedValue`.
969			// Therefore, this is safe.
970			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			// `OwnedValue` is constructed from the `crate::ObjectRef`
1010			// Only way to fail is to convert a Fd into an `OwnedValue`.
1011			// Therefore, this is safe.
1012			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			// `OwnedValue` is constructed from `String`
1029			// Therefore, this is safe.
1030			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			// `OwnedValue` is constructed from a `String`
1108			// Therefore, this is safe.
1109			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);