1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 // rustdoc-stripper-ignore-next
4 //! `IMPL` Object wrapper implementation and `Object` binding.
5
6 use std ::{cmp , fmt , hash , marker ::PhantomData , mem , mem ::ManuallyDrop , ops , pin ::Pin , ptr };
7
8 use crate ::{
9 closure ::TryFromClosureReturnValue ,
10 ffi , gobject_ffi ,
11 prelude ::*,
12 quark ::Quark ,
13 subclass ::{prelude ::*, SignalId , SignalQuery },
14 thread_guard ::thread_id ,
15 translate ::*,
16 value ::FromValue ,
17 Closure , PtrSlice , RustClosure , SignalHandlerId , Type , Value ,
18 };
19
20 // rustdoc-stripper-ignore-next
21 /// Implemented by types representing `glib::Object` and subclasses of it.
22 pub unsafe trait ObjectType :
23 UnsafeFrom <ObjectRef >
24 + Into <ObjectRef >
25 + StaticType
26 + fmt ::Debug
27 + Clone
28 + PartialEq
29 + Eq
30 + PartialOrd
31 + Ord
32 + hash ::Hash
33 + crate ::value ::ValueType
34 + ToValue
35 + crate ::value ::ToValueOptional
36 + crate ::value ::FromValueOptional <'static>
37 + for <'a> dyn ToGlibPtr <'a, * mut <Self as ObjectType >::GlibType >
38 + IntoGlibPtr <* mut <Self as ObjectType >::GlibType >
39 + 'static
40 {
41 // rustdoc-stripper-ignore-next
42 /// type of the FFI Instance structure.
43 type GlibType : 'static;
44 // rustdoc-stripper-ignore-next
45 /// type of the FFI Class structure.
46 type GlibClassType : 'static;
47
48 fn as_object_ref (&self) -> &ObjectRef ;
49 fn as_ptr (&self) -> * mut Self::GlibType ;
50
51 unsafe fn from_glib_ptr_borrow (ptr : &* mut Self::GlibType ) -> &Self;
52 }
53
54 // rustdoc-stripper-ignore-next
55 /// Declares the "is a" relationship.
56 ///
57 /// `Self` is said to implement `T`.
58 ///
59 /// For instance, since originally `GtkWidget` is a subclass of `GObject` and
60 /// implements the `GtkBuildable` interface, `gtk::Widget` implements
61 /// `IsA<glib::Object>` and `IsA<gtk::Buildable>`.
62 ///
63 ///
64 /// The trait can only be implemented if the appropriate `ToGlibPtr`
65 /// implementations exist.
66 pub unsafe trait IsA <T: ObjectType >:
67 ObjectType + Into <T> + AsRef <T> + std ::borrow ::Borrow <T>
68 {
69 }
70
71 // rustdoc-stripper-ignore-next
72 /// Upcasting and downcasting support.
73 ///
74 /// Provides conversions up and down the class hierarchy tree.
75 pub trait Cast : ObjectType {
76 // rustdoc-stripper-ignore-next
77 /// Upcasts an object to a superclass or interface `T`.
78 ///
79 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always
80 /// known at compile-time, whether a specific object implements an interface or not, in which case
81 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which
82 /// is checking the types at runtime.
83 ///
84 /// # Example
85 ///
86 /// ```ignore
87 /// let button = gtk ::Button ::new ();
88 /// let widget = button .upcast ::<gtk ::Widget >();
89 /// ```
90 #[inline ]
91 fn upcast <T: ObjectType >(self) -> T
92 where
93 Self: IsA <T>,
94 {
95 unsafe { self.unsafe_cast () }
96 }
97
98 // rustdoc-stripper-ignore-next
99 /// Upcasts an object to a reference of its superclass or interface `T`.
100 ///
101 /// *NOTE*: This statically checks at compile-time if casting is possible. It is not always
102 /// known at compile-time, whether a specific object implements an interface or not, in which case
103 /// `upcast` would fail to compile. `dynamic_cast` can be used in these circumstances, which
104 /// is checking the types at runtime.
105 ///
106 /// # Example
107 ///
108 /// ```ignore
109 /// let button = gtk ::Button ::new ();
110 /// let widget = button .upcast_ref ::<gtk ::Widget >();
111 /// ```
112 #[inline ]
113 fn upcast_ref <T: ObjectType >(&self) -> &T
114 where
115 Self: IsA <T>,
116 {
117 unsafe { self.unsafe_cast_ref () }
118 }
119
120 // rustdoc-stripper-ignore-next
121 /// Tries to downcast to a subclass or interface implementor `T`.
122 ///
123 /// Returns `Ok(T)` if the object is an instance of `T` and `Err(self)`
124 /// otherwise.
125 ///
126 /// *NOTE*: This will check at compile-time if `T` is lower down the
127 /// inheritance tree of `Self`, but also check at runtime if downcasting
128 /// is indeed possible.
129 ///
130 /// # Example
131 ///
132 /// ```ignore
133 /// let button = gtk ::Button ::new ();
134 /// let widget = button .upcast ::<gtk ::Widget >();
135 /// assert !(widget.downcast::<gtk::Button>().is_ok());
136 /// ```
137 #[inline ]
138 fn downcast <T: ObjectType >(self) -> Result <T, Self>
139 where
140 Self: MayDowncastTo <T>,
141 {
142 if self.is ::<T>() {
143 Ok (unsafe { self.unsafe_cast () })
144 } else {
145 Err (self)
146 }
147 }
148
149 // rustdoc-stripper-ignore-next
150 /// Tries to downcast to a reference of its subclass or interface implementor `T`.
151 ///
152 /// Returns `Some(T)` if the object is an instance of `T` and `None`
153 /// otherwise.
154 ///
155 /// *NOTE*: This will check at compile-time if `T` is lower down the
156 /// inheritance tree of `Self`, but also check at runtime if downcasting
157 /// is indeed possible.
158 ///
159 /// # Example
160 ///
161 /// ```ignore
162 /// let button = gtk ::Button ::new ();
163 /// let widget = button .upcast ::<gtk ::Widget >();
164 /// assert !(widget.downcast_ref::<gtk::Button>().is_some());
165 /// ```
166 #[inline ]
167 fn downcast_ref <T: ObjectType >(&self) -> Option <&T>
168 where
169 Self: MayDowncastTo <T>,
170 {
171 if self.is ::<T>() {
172 Some (unsafe { self.unsafe_cast_ref () })
173 } else {
174 None
175 }
176 }
177
178 // rustdoc-stripper-ignore-next
179 /// Tries to cast to an object of type `T`. This handles upcasting, downcasting
180 /// and casting between interface and interface implementors. All checks are performed at
181 /// runtime, while `upcast` will do many checks at compile-time already. `downcast` will
182 /// perform the same checks at runtime as `dynamic_cast`, but will also ensure some amount of
183 /// compile-time safety.
184 ///
185 /// It is not always known at compile-time, whether a specific object implements an interface or
186 /// not, and checking has to be performed at runtime.
187 ///
188 /// Returns `Ok(T)` if the object is an instance of `T` and `Err(self)`
189 /// otherwise.
190 ///
191 /// # Example
192 ///
193 /// ```ignore
194 /// let button = gtk ::Button ::new ();
195 /// let widget = button .dynamic_cast ::<gtk ::Widget >();
196 /// assert !(widget.is_ok());
197 /// let widget = widget .unwrap ();
198 /// assert !(widget.dynamic_cast::<gtk::Button>().is_ok());
199 /// ```
200 #[inline ]
201 fn dynamic_cast <T: ObjectType >(self) -> Result <T, Self> {
202 if !self.is ::<T>() {
203 Err (self)
204 } else {
205 Ok (unsafe { self.unsafe_cast () })
206 }
207 }
208
209 // rustdoc-stripper-ignore-next
210 /// Tries to cast to reference to an object of type `T`. This handles upcasting, downcasting
211 /// and casting between interface and interface implementors. All checks are performed at
212 /// runtime, while `downcast` and `upcast` will do many checks at compile-time already.
213 ///
214 /// It is not always known at compile-time, whether a specific object implements an interface or
215 /// not, and checking has to be performed at runtime.
216 ///
217 /// Returns `Some(T)` if the object is an instance of `T` and `None`
218 /// otherwise.
219 ///
220 /// # Example
221 ///
222 /// ```ignore
223 /// let button = gtk ::Button ::new ();
224 /// let widget = button .dynamic_cast_ref ::<gtk ::Widget >();
225 /// assert !(widget.is_some());
226 /// let widget = widget .unwrap ();
227 /// assert !(widget.dynamic_cast_ref::<gtk::Button>().is_some());
228 /// ```
229 #[inline ]
230 fn dynamic_cast_ref <T: ObjectType >(&self) -> Option <&T> {
231 if !self.is ::<T>() {
232 None
233 } else {
234 // This cast is safe because all our wrapper types have the
235 // same representation except for the name and the phantom data
236 // type. IsA<> is an unsafe trait that must only be implemented
237 // if this is a valid wrapper type
238 Some (unsafe { self.unsafe_cast_ref () })
239 }
240 }
241
242 // rustdoc-stripper-ignore-next
243 /// Casts to `T` unconditionally.
244 ///
245 /// # Panics
246 ///
247 /// Panics if compiled with `debug_assertions` and the instance doesn't implement `T`.
248 ///
249 /// # Safety
250 ///
251 /// If not running with `debug_assertions` enabled, the caller is responsible
252 /// for ensuring that the instance implements `T`
253 #[track_caller ]
254 #[inline ]
255 unsafe fn unsafe_cast <T: ObjectType >(self) -> T {
256 debug_assert !(self.is ::<T>());
257 T::unsafe_from (self.into ())
258 }
259
260 // rustdoc-stripper-ignore-next
261 /// Casts to `&T` unconditionally.
262 ///
263 /// # Panics
264 ///
265 /// Panics if compiled with `debug_assertions` and the instance doesn't implement `T`.
266 ///
267 /// # Safety
268 ///
269 /// If not running with `debug_assertions` enabled, the caller is responsible
270 /// for ensuring that the instance implements `T`
271 #[track_caller ]
272 #[inline ]
273 unsafe fn unsafe_cast_ref <T: ObjectType >(&self) -> &T {
274 debug_assert !(self.is ::<T>());
275 // This cast is safe because all our wrapper types have the
276 // same representation except for the name and the phantom data
277 // type. IsA<> is an unsafe trait that must only be implemented
278 // if this is a valid wrapper type
279 &*(self as * const Self as * const T)
280 }
281 }
282
283 impl <T: ObjectType > Cast for T {}
284
285 // rustdoc-stripper-ignore-next
286 /// Convenience trait mirroring `Cast`, implemented on `Option<Object>` types.
287 ///
288 /// # Warning
289 /// Inevitably this trait will discard information about a downcast failure:
290 /// you don't know if the object was not of the expected type, or if it was `None`.
291 /// If you need to handle the downcast error, use `Cast` over a `glib::Object`.
292 ///
293 /// # Example
294 /// ```ignore
295 /// let widget : Option <Widget > = list_item.child ();
296 ///
297 /// // Without using `CastNone`
298 /// let label = widget .unwrap ().downcast ::<gtk ::Label >().unwrap ();
299 ///
300 /// // Using `CastNone` we can avoid the first `unwrap()` call
301 /// let label = widget .and_downcast ::<gtk ::Label >().unwrap ();
302 /// ````
303 pub trait CastNone : Sized {
304 type Inner ;
305 fn and_downcast <T: ObjectType >(self) -> Option <T>
306 where
307 Self::Inner : MayDowncastTo <T>;
308 fn and_downcast_ref <T: ObjectType >(&self) -> Option <&T>
309 where
310 Self::Inner : MayDowncastTo <T>;
311 fn and_upcast <T: ObjectType >(self) -> Option <T>
312 where
313 Self::Inner : IsA <T>;
314 fn and_upcast_ref <T: ObjectType >(&self) -> Option <&T>
315 where
316 Self::Inner : IsA <T>;
317 fn and_dynamic_cast <T: ObjectType >(self) -> Result <T, Self>;
318 fn and_dynamic_cast_ref <T: ObjectType >(&self) -> Option <&T>;
319 }
320 impl <I: ObjectType + Sized > CastNone for Option <I> {
321 type Inner = I;
322
323 #[inline ]
324 fn and_downcast <T: ObjectType >(self) -> Option <T>
325 where
326 Self::Inner : MayDowncastTo <T>,
327 {
328 self.and_then (|i | i .downcast ().ok ())
329 }
330
331 #[inline ]
332 fn and_downcast_ref <T: ObjectType >(&self) -> Option <&T>
333 where
334 Self::Inner : MayDowncastTo <T>,
335 {
336 self.as_ref ().and_then (|i | i .downcast_ref ())
337 }
338
339 #[inline ]
340 fn and_upcast <T: ObjectType >(self) -> Option <T>
341 where
342 Self::Inner : IsA <T>,
343 {
344 self.map (|i | i .upcast ())
345 }
346
347 #[inline ]
348 fn and_upcast_ref <T: ObjectType >(&self) -> Option <&T>
349 where
350 Self::Inner : IsA <T>,
351 {
352 self.as_ref ().map (|i | i .upcast_ref ())
353 }
354
355 #[inline ]
356 fn and_dynamic_cast <T: ObjectType >(self) -> Result <T, Self> {
357 self.ok_or (None )
358 .and_then (|i | i .dynamic_cast ().map_err (|e | Some (e )))
359 }
360
361 #[inline ]
362 fn and_dynamic_cast_ref <T: ObjectType >(&self) -> Option <&T> {
363 self.as_ref ().and_then (|i | i .dynamic_cast_ref ())
364 }
365 }
366
367 // rustdoc-stripper-ignore-next
368 /// Marker trait for the statically known possibility of downcasting from `Self` to `T`.
369 pub trait MayDowncastTo <T> {}
370
371 impl <Super: IsA <Super>, Sub: IsA <Super>> MayDowncastTo <Sub> for Super {}
372
373 // Manual implementation of glib_shared_wrapper! because of special cases
374 #[repr (transparent)]
375 pub struct ObjectRef {
376 inner : ptr ::NonNull <gobject_ffi ::GObject >,
377 }
378
379 impl Clone for ObjectRef {
380 #[inline ]
381 fn clone (&self) -> Self {
382 unsafe {
383 Self {
384 inner : ptr ::NonNull ::new_unchecked (ptr: gobject_ffi ::g_object_ref (self.inner .as_ptr ())),
385 }
386 }
387 }
388 }
389
390 impl Drop for ObjectRef {
391 #[inline ]
392 fn drop (&mut self) {
393 unsafe {
394 gobject_ffi ::g_object_unref (self.inner .as_ptr ());
395 }
396 }
397 }
398
399 impl fmt ::Debug for ObjectRef {
400 fn fmt (&self, f : &mut fmt ::Formatter ) -> fmt ::Result {
401 let type_ : Type = unsafe {
402 let klass : *const Class = (*self.inner .as_ptr ()).g_type_instance .g_class as * const ObjectClass ;
403 (*klass ).type_ ()
404 };
405
406 f &mut DebugStruct<'_, '_> .debug_struct ("ObjectRef" )
407 .field ("inner" , &self.inner )
408 .field (name: "type" , &type_ )
409 .finish ()
410 }
411 }
412
413 impl PartialOrd for ObjectRef {
414 #[inline ]
415 fn partial_cmp (&self, other : &Self) -> Option <cmp ::Ordering > {
416 Some (self.cmp (other ))
417 }
418 }
419
420 impl Ord for ObjectRef {
421 #[inline ]
422 fn cmp (&self, other : &Self) -> cmp ::Ordering {
423 self.inner .cmp (&other .inner )
424 }
425 }
426
427 impl PartialEq for ObjectRef {
428 #[inline ]
429 fn eq (&self, other : &Self) -> bool {
430 self.inner == other .inner
431 }
432 }
433
434 impl Eq for ObjectRef {}
435
436 impl hash ::Hash for ObjectRef {
437 #[inline ]
438 fn hash <H>(&self, state : &mut H)
439 where
440 H: hash ::Hasher ,
441 {
442 self.inner .hash (state )
443 }
444 }
445
446 #[doc (hidden)]
447 impl GlibPtrDefault for ObjectRef {
448 type GlibType = * mut gobject_ffi ::GObject ;
449 }
450
451 #[doc (hidden)]
452 impl <'a> ToGlibPtr <'a, * mut gobject_ffi ::GObject > for ObjectRef {
453 type Storage = PhantomData <&'a ObjectRef >;
454
455 #[inline ]
456 fn to_glib_none (&'a self) -> Stash <'a, * mut gobject_ffi ::GObject , Self> {
457 Stash (self.inner .as_ptr (), PhantomData )
458 }
459
460 #[inline ]
461 fn to_glib_full (&self) -> * mut gobject_ffi ::GObject {
462 unsafe { gobject_ffi ::g_object_ref (self.inner .as_ptr ()) }
463 }
464 }
465
466 #[doc (hidden)]
467 impl FromGlibPtrNone <* mut gobject_ffi ::GObject > for ObjectRef {
468 #[inline ]
469 unsafe fn from_glib_none (ptr : * mut gobject_ffi ::GObject ) -> Self {
470 debug_assert !(!ptr .is_null ());
471 debug_assert_ne !((*ptr ).ref_count , 0 );
472
473 // Attention: This takes ownership of floating references!
474 Self {
475 inner : ptr ::NonNull ::new_unchecked (ptr: gobject_ffi ::g_object_ref_sink (object: ptr )),
476 }
477 }
478 }
479
480 #[doc (hidden)]
481 impl FromGlibPtrNone <* const gobject_ffi ::GObject > for ObjectRef {
482 #[inline ]
483 unsafe fn from_glib_none (ptr : * const gobject_ffi ::GObject ) -> Self {
484 // Attention: This takes ownership of floating references!
485 from_glib_none (ptr as * mut gobject_ffi ::GObject )
486 }
487 }
488
489 #[doc (hidden)]
490 impl FromGlibPtrFull <* mut gobject_ffi ::GObject > for ObjectRef {
491 #[inline ]
492 unsafe fn from_glib_full (ptr : * mut gobject_ffi ::GObject ) -> Self {
493 debug_assert !(!ptr .is_null ());
494 debug_assert_ne !((*ptr ).ref_count , 0 );
495
496 Self {
497 inner : ptr ::NonNull ::new_unchecked (ptr ),
498 }
499 }
500 }
501
502 #[doc (hidden)]
503 impl FromGlibPtrBorrow <* mut gobject_ffi ::GObject > for ObjectRef {
504 #[inline ]
505 unsafe fn from_glib_borrow (ptr : * mut gobject_ffi ::GObject ) -> Borrowed <Self> {
506 debug_assert !(!ptr .is_null ());
507 debug_assert_ne !((*ptr ).ref_count , 0 );
508
509 Borrowed ::new (Self {
510 inner : ptr ::NonNull ::new_unchecked (ptr ),
511 })
512 }
513 }
514
515 #[doc (hidden)]
516 impl FromGlibPtrBorrow <* const gobject_ffi ::GObject > for ObjectRef {
517 #[inline ]
518 unsafe fn from_glib_borrow (ptr : * const gobject_ffi ::GObject ) -> Borrowed <Self> {
519 from_glib_borrow (ptr as * mut gobject_ffi ::GObject )
520 }
521 }
522
523 #[repr (transparent)]
524 pub struct TypedObjectRef <T, P> {
525 inner : ObjectRef ,
526 imp : PhantomData <T>,
527 parent : PhantomData <P>,
528 }
529
530 impl <T, P> TypedObjectRef <T, P> {
531 #[inline ]
532 pub unsafe fn new (obj : ObjectRef ) -> Self {
533 Self {
534 inner : obj ,
535 imp : PhantomData ,
536 parent : PhantomData ,
537 }
538 }
539
540 #[inline ]
541 pub fn into_inner (self) -> ObjectRef {
542 self.inner
543 }
544 }
545
546 impl <T, P> Clone for TypedObjectRef <T, P> {
547 #[inline ]
548 fn clone (&self) -> Self {
549 Self {
550 inner : self.inner .clone (),
551 imp : PhantomData ,
552 parent : PhantomData ,
553 }
554 }
555 }
556
557 impl <T, P> ops ::Deref for TypedObjectRef <T, P> {
558 type Target = ObjectRef ;
559
560 #[inline ]
561 fn deref (&self) -> &Self::Target {
562 &self.inner
563 }
564 }
565
566 impl <T, P> fmt ::Debug for TypedObjectRef <T, P> {
567 fn fmt (&self, f : &mut fmt ::Formatter ) -> fmt ::Result {
568 let type_ : Type = unsafe {
569 let klass : *const Class = (*self.inner .inner .as_ptr ()).g_type_instance .g_class as * const ObjectClass ;
570 (*klass ).type_ ()
571 };
572
573 f &mut DebugStruct<'_, '_> .debug_struct ("TypedObjectRef" )
574 .field ("inner" , &self.inner .inner )
575 .field (name: "type" , &type_ )
576 .finish ()
577 }
578 }
579
580 impl <T, P> PartialOrd for TypedObjectRef <T, P> {
581 #[inline ]
582 fn partial_cmp (&self, other : &Self) -> Option <cmp ::Ordering > {
583 Some (self.cmp (other ))
584 }
585 }
586
587 impl <T, P> Ord for TypedObjectRef <T, P> {
588 #[inline ]
589 fn cmp (&self, other : &Self) -> cmp ::Ordering {
590 self.inner .cmp (&other .inner )
591 }
592 }
593
594 impl <T, P> PartialEq for TypedObjectRef <T, P> {
595 #[inline ]
596 fn eq (&self, other : &Self) -> bool {
597 self.inner == other .inner
598 }
599 }
600
601 impl <T, P> Eq for TypedObjectRef <T, P> {}
602
603 impl <T, P> hash ::Hash for TypedObjectRef <T, P> {
604 #[inline ]
605 fn hash <H>(&self, state : &mut H)
606 where
607 H: hash ::Hasher ,
608 {
609 self.inner .hash (state )
610 }
611 }
612
613 unsafe impl <T: Send + Sync , P: Send + Sync > Send for TypedObjectRef <T, P> {}
614 unsafe impl <T: Send + Sync , P: Send + Sync > Sync for TypedObjectRef <T, P> {}
615
616 // rustdoc-stripper-ignore-next
617 /// ObjectType implementations for Object types. See `wrapper!`.
618 #[macro_export ]
619 macro_rules ! glib_object_wrapper {
620 (@generic_impl [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $impl_type:ty, $parent_type:ty, $ffi_name:ty, $ffi_class_name:ty, @type_ $get_type_expr:expr) => {
621 $(#[$attr])*
622 #[doc = " \n \n GLib type: GObject with reference counted clone semantics." ]
623 #[repr(transparent)]
624 $visibility struct $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? {
625 inner: $crate::object::TypedObjectRef<$impl_type, $parent_type>,
626 phantom: std::marker::PhantomData<($($($generic),+)?)>,
627 }
628
629 // Always implement Clone, Hash, PartialEq, Eq, PartialOrd, Ord, and Debug for object types.
630 // Due to inheritance and up/downcasting we must implement these by pointer or otherwise they
631 // would potentially give different results for the same object depending on the type we
632 // currently know for it.
633 // Implement them manually rather than generating #[derive] macros since so that when generics
634 // are specified, these traits are not required.
635
636 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::clone::Clone for $name $(<$($generic),+>)? {
637 #[doc = "Makes a clone of this shared reference. \n \n This increments the strong reference count of the object. Dropping the object will decrement it again." ]
638 #[inline]
639 fn clone(&self ) -> Self {
640 Self {
641 inner: std::clone::Clone::clone(&self .inner),
642 phantom: std::marker::PhantomData,
643 }
644 }
645 }
646
647 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::hash::Hash for $name $(<$($generic),+>)? {
648 #[doc = "Hashes the memory address of this object." ]
649 #[inline]
650 fn hash<H>(&self , state: &mut H)
651 where
652 H: std::hash::Hasher
653 {
654 std::hash::Hash::hash(&self .inner, state);
655 }
656 }
657
658 impl <OT: $crate::object::ObjectType $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> std::cmp::PartialEq<OT> for $name $(<$($generic),+>)? {
659 #[doc = "Equality for two GObjects. \n \n Two GObjects are equal if their memory addresses are equal." ]
660 #[inline]
661 fn eq(&self , other: &OT) -> bool {
662 std::cmp::PartialEq::eq(&*self .inner, $crate::object::ObjectType::as_object_ref(other))
663 }
664 }
665
666 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::cmp::Eq for $name $(<$($generic),+>)? {}
667
668 impl <OT: $crate::object::ObjectType $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> std::cmp::PartialOrd<OT> for $name $(<$($generic),+>)? {
669 #[doc = "Partial comparison for two GObjects. \n \n Compares the memory addresses of the provided objects." ]
670 #[inline]
671 fn partial_cmp(&self , other: &OT) -> Option<std::cmp::Ordering> {
672 std::cmp::PartialOrd::partial_cmp(&*self .inner, $crate::object::ObjectType::as_object_ref(other))
673 }
674 }
675
676 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::cmp::Ord for $name $(<$($generic),+>)? {
677 #[doc = "Comparison for two GObjects. \n \n Compares the memory addresses of the provided objects." ]
678 #[inline]
679 fn cmp(&self , other: &Self ) -> std::cmp::Ordering {
680 std::cmp::Ord::cmp(&*self .inner, $crate::object::ObjectType::as_object_ref(other))
681 }
682 }
683
684
685 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::fmt::Debug for $name $(<$($generic),+>)? {
686 fn fmt(&self , f: &mut std::fmt::Formatter) -> std::fmt::Result {
687 f.debug_struct(stringify!($name)).field("inner" , &self .inner).finish()
688 }
689 }
690
691 #[doc(hidden)]
692 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? From<$name $(<$($generic),+>)?> for $crate::object::ObjectRef {
693 #[inline]
694 fn from(s: $name $(<$($generic),+>)?) -> $crate::object::ObjectRef {
695 s.inner.into_inner()
696 }
697 }
698
699 #[doc(hidden)]
700 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::UnsafeFrom<$crate::object::ObjectRef> for $name $(<$($generic),+>)? {
701 #[inline]
702 unsafe fn unsafe_from(t: $crate::object::ObjectRef) -> Self {
703 $name {
704 inner: $crate::object::TypedObjectRef::new(t),
705 phantom: std::marker::PhantomData,
706 }
707 }
708 }
709
710 #[doc(hidden)]
711 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::GlibPtrDefault for $name $(<$($generic),+>)? {
712 type GlibType = *mut $ffi_name;
713 }
714
715 #[doc(hidden)]
716 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::TransparentPtrType for $name $(<$($generic),+>)? {}
717
718 #[doc(hidden)]
719 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::ObjectType for $name $(<$($generic),+>)? {
720 type GlibType = $ffi_name;
721 type GlibClassType = $ffi_class_name;
722
723 #[inline]
724 fn as_object_ref(&self ) -> &$crate::object::ObjectRef {
725 &self .inner
726 }
727
728 #[inline]
729 fn as_ptr(&self ) -> *mut Self ::GlibType {
730 unsafe { *(self as *const Self as *const *const $ffi_name) as *mut $ffi_name }
731 }
732
733 #[inline]
734 unsafe fn from_glib_ptr_borrow(ptr: &*mut Self ::GlibType) -> &Self {
735 debug_assert_eq!(
736 std::mem::size_of::<Self >(),
737 std::mem::size_of::<$crate::ffi::gpointer>()
738 );
739 debug_assert!(!ptr.is_null());
740 debug_assert_ne!((*(*ptr as *const $crate::gobject_ffi::GObject)).ref_count, 0 );
741 &*(ptr as *const *mut $ffi_name as *const Self )
742 }
743 }
744
745 #[doc(hidden)]
746 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? AsRef<$crate::object::ObjectRef> for $name $(<$($generic),+>)? {
747 #[inline]
748 fn as_ref(&self ) -> &$crate::object::ObjectRef {
749 &self .inner
750 }
751 }
752
753 #[doc(hidden)]
754 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? AsRef<Self > for $name $(<$($generic),+>)? {
755 #[inline]
756 fn as_ref(&self ) -> &Self {
757 self
758 }
759 }
760
761 #[doc(hidden)]
762 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::IsA<Self > for $name $(<$($generic),+>)? { }
763
764 #[doc(hidden)]
765 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::subclass::types::FromObject for $name $(<$($generic),+>)? {
766 type FromObjectType = Self ;
767
768 #[inline]
769 fn from_object(obj: &Self ::FromObjectType) -> &Self {
770 obj
771 }
772 }
773
774 #[doc(hidden)]
775 impl <'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibPtr<'a, *const $ffi_name> for $name $(<$($generic),+>)? {
776 type Storage = <$crate::object::ObjectRef as
777 $crate::translate::ToGlibPtr<'a, *mut $crate::gobject_ffi::GObject>>::Storage;
778
779 #[inline]
780 fn to_glib_none(&'a self ) -> $crate::translate::Stash<'a, *const $ffi_name, Self > {
781 let stash = $crate::translate::ToGlibPtr::to_glib_none(&*self .inner);
782 $crate::translate::Stash(stash.0 as *const _, stash.1 )
783 }
784
785 #[inline]
786 fn to_glib_full(&self ) -> *const $ffi_name {
787 $crate::translate::ToGlibPtr::to_glib_full(&*self .inner) as *const _
788 }
789 }
790
791 #[doc(hidden)]
792 impl <'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibPtr<'a, *mut $ffi_name> for $name $(<$($generic),+>)? {
793 type Storage = <$crate::object::ObjectRef as
794 $crate::translate::ToGlibPtr<'a, *mut $crate::gobject_ffi::GObject>>::Storage;
795
796 #[inline]
797 fn to_glib_none(&'a self ) -> $crate::translate::Stash<'a, *mut $ffi_name, Self > {
798 let stash = $crate::translate::ToGlibPtr::to_glib_none(&*self .inner);
799 $crate::translate::Stash(stash.0 as *mut _, stash.1 )
800 }
801
802 #[inline]
803 fn to_glib_full(&self ) -> *mut $ffi_name {
804 $crate::translate::ToGlibPtr::to_glib_full(&*self .inner) as *mut _
805 }
806 }
807
808 #[doc(hidden)]
809 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::IntoGlibPtr<*mut $ffi_name> for $name $(<$($generic),+>)? {
810 #[inline]
811 unsafe fn into_glib_ptr(self ) -> *mut $ffi_name {
812 let s = std::mem::ManuallyDrop::new(self );
813 $crate::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&*s).0 as *mut _
814 }
815 }
816
817 #[doc(hidden)]
818 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::IntoGlibPtr<*const $ffi_name> for $name $(<$($generic),+>)? {
819 #[inline]
820 unsafe fn into_glib_ptr(self ) -> *const $ffi_name {
821 let s = std::mem::ManuallyDrop::new(self );
822 $crate::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&*s).0 as *const _
823 }
824 }
825
826 #[doc(hidden)]
827 impl <'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibContainerFromSlice<'a, *mut *mut $ffi_name> for $name $(<$($generic),+>)? {
828 type Storage = (std::marker::PhantomData<&'a [Self ]>, Option<Vec<*mut $ffi_name>>);
829
830 fn to_glib_none_from_slice(t: &'a [Self ]) -> (*mut *mut $ffi_name, Self ::Storage) {
831 let mut v_ptr = Vec::with_capacity(t.len() + 1 );
832 unsafe {
833 let ptr = v_ptr.as_mut_ptr();
834 std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, ptr, t.len());
835 std::ptr::write(ptr.add(t.len()), std::ptr::null_mut());
836 v_ptr.set_len(t.len() + 1 );
837 }
838
839 (v_ptr.as_ptr() as *mut *mut $ffi_name, (std::marker::PhantomData, Some(v_ptr)))
840 }
841
842 fn to_glib_container_from_slice(t: &'a [Self ]) -> (*mut *mut $ffi_name, Self ::Storage) {
843 let v_ptr = unsafe {
844 let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1 )) as *mut *mut $ffi_name;
845
846 std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, v_ptr, t.len());
847 std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
848
849 v_ptr
850 };
851
852 (v_ptr, (std::marker::PhantomData, None))
853 }
854
855 fn to_glib_full_from_slice(t: &[Self ]) -> *mut *mut $ffi_name {
856 unsafe {
857 let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1 )) as *mut *mut $ffi_name;
858
859 for (i, s) in t.iter().enumerate() {
860 std::ptr::write(v_ptr.add(i), $crate::translate::ToGlibPtr::to_glib_full(s));
861 }
862 std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
863
864 v_ptr
865 }
866 }
867 }
868
869 #[doc(hidden)]
870 impl <'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibContainerFromSlice<'a, *const *mut $ffi_name> for $name $(<$($generic),+>)? {
871 type Storage = (std::marker::PhantomData<&'a [Self ]>, Option<Vec<*mut $ffi_name>>);
872
873 fn to_glib_none_from_slice(t: &'a [Self ]) -> (*const *mut $ffi_name, Self ::Storage) {
874 let (ptr, stash) = $crate::translate::ToGlibContainerFromSlice::<'a, *mut *mut $ffi_name>::to_glib_none_from_slice(t);
875 (ptr as *const *mut $ffi_name, stash)
876 }
877
878 fn to_glib_container_from_slice(_: &'a [Self ]) -> (*const *mut $ffi_name, Self ::Storage) {
879 // Can't have consumer free a *const pointer
880 unimplemented!()
881 }
882
883 fn to_glib_full_from_slice(_: &[Self ]) -> *const *mut $ffi_name {
884 // Can't have consumer free a *const pointer
885 unimplemented!()
886 }
887 }
888
889 #[doc(hidden)]
890 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrNone<*mut $ffi_name> for $name $(<$($generic),+>)? {
891 #[inline]
892 #[allow(clippy::cast_ptr_alignment)]
893 unsafe fn from_glib_none(ptr: *mut $ffi_name) -> Self {
894 debug_assert!(!ptr.is_null());
895 debug_assert!($crate::types::instance_of::<Self >(ptr as *const _));
896 $name {
897 inner: $crate::object::TypedObjectRef::new($crate::translate::from_glib_none(ptr as *mut _)),
898 phantom: std::marker::PhantomData,
899 }
900 }
901 }
902
903 #[doc(hidden)]
904 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrNone<*const $ffi_name> for $name $(<$($generic),+>)? {
905 #[inline]
906 #[allow(clippy::cast_ptr_alignment)]
907 unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self {
908 debug_assert!(!ptr.is_null());
909 debug_assert!($crate::types::instance_of::<Self >(ptr as *const _));
910 $name {
911 inner: $crate::object::TypedObjectRef::new($crate::translate::from_glib_none(ptr as *mut _)),
912 phantom: std::marker::PhantomData,
913 }
914 }
915 }
916
917 #[doc(hidden)]
918 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrFull<*mut $ffi_name> for $name $(<$($generic),+>)? {
919 #[inline]
920 #[allow(clippy::cast_ptr_alignment)]
921 unsafe fn from_glib_full(ptr: *mut $ffi_name) -> Self {
922 debug_assert!(!ptr.is_null());
923 debug_assert!($crate::types::instance_of::<Self >(ptr as *const _));
924 $name {
925 inner: $crate::object::TypedObjectRef::new($crate::translate::from_glib_full(ptr as *mut _)),
926 phantom: std::marker::PhantomData,
927 }
928 }
929 }
930
931 #[doc(hidden)]
932 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrBorrow<*mut $ffi_name> for $name $(<$($generic),+>)? {
933 #[inline]
934 #[allow(clippy::cast_ptr_alignment)]
935 unsafe fn from_glib_borrow(ptr: *mut $ffi_name) -> $crate::translate::Borrowed<Self > {
936 debug_assert!(!ptr.is_null());
937 debug_assert!($crate::types::instance_of::<Self >(ptr as *const _));
938 $crate::translate::Borrowed::new(
939 $name {
940 inner: $crate::object::TypedObjectRef::new($crate::translate::from_glib_borrow::<_, $crate::object::ObjectRef>(ptr as *mut _).into_inner()),
941 phantom: std::marker::PhantomData,
942 }
943 )
944 }
945 }
946
947 #[doc(hidden)]
948 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrBorrow<*const $ffi_name> for $name $(<$($generic),+>)? {
949 #[inline]
950 #[allow(clippy::cast_ptr_alignment)]
951 unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> $crate::translate::Borrowed<Self > {
952 $crate::translate::from_glib_borrow::<_, Self >(ptr as *mut $ffi_name)
953 }
954 }
955
956 #[doc(hidden)]
957 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name $(<$($generic),+>)? {
958 unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self > {
959 if num == 0 || ptr.is_null() {
960 return Vec::new();
961 }
962
963 let mut res = Vec::<Self >::with_capacity(num);
964 let res_ptr = res.as_mut_ptr();
965 for i in 0 ..num {
966 ::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(std::ptr::read(ptr.add(i))));
967 }
968 res.set_len(num);
969 res
970 }
971
972 unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self > {
973 let res = $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num);
974 $crate::ffi::g_free(ptr as *mut _);
975 res
976 }
977
978 unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self > {
979 if num == 0 || ptr.is_null() {
980 $crate::ffi::g_free(ptr as *mut _);
981 return Vec::new();
982 }
983
984 let mut res = Vec::with_capacity(num);
985 let res_ptr = res.as_mut_ptr();
986 ::std::ptr::copy_nonoverlapping(ptr as *mut Self , res_ptr, num);
987 res.set_len(num);
988 $crate::ffi::g_free(ptr as *mut _);
989 res
990 }
991 }
992
993 #[doc(hidden)]
994 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name $(<$($generic),+>)? {
995 unsafe fn from_glib_none_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self > {
996 $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr))
997 }
998
999 unsafe fn from_glib_container_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self > {
1000 $crate::translate::FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr))
1001 }
1002
1003 unsafe fn from_glib_full_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self > {
1004 $crate::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr))
1005 }
1006 }
1007
1008 #[doc(hidden)]
1009 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name $(<$($generic),+>)? {
1010 unsafe fn from_glib_none_num_as_vec(ptr: *const *mut $ffi_name, num: usize) -> Vec<Self > {
1011 $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num)
1012 }
1013
1014 unsafe fn from_glib_container_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self > {
1015 // Can't free a *const
1016 unimplemented!()
1017 }
1018
1019 unsafe fn from_glib_full_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self > {
1020 // Can't free a *const
1021 unimplemented!()
1022 }
1023 }
1024
1025 #[doc(hidden)]
1026 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name $(<$($generic),+>)? {
1027 unsafe fn from_glib_none_as_vec(ptr: *const *mut $ffi_name) -> Vec<Self > {
1028 $crate::translate::FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _)
1029 }
1030
1031 unsafe fn from_glib_container_as_vec(_: *const *mut $ffi_name) -> Vec<Self > {
1032 // Can't free a *const
1033 unimplemented!()
1034 }
1035
1036 unsafe fn from_glib_full_as_vec(_: *const *mut $ffi_name) -> Vec<Self > {
1037 // Can't free a *const
1038 unimplemented!()
1039 }
1040 }
1041
1042 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::StaticType for $name $(<$($generic),+>)? {
1043 #[inline]
1044 fn static_type() -> $crate::types::Type {
1045 #[allow(unused_unsafe)]
1046 #[allow(clippy::macro_metavars_in_unsafe)]
1047 unsafe { $crate::translate::from_glib($get_type_expr) }
1048 }
1049 }
1050
1051 #[doc(hidden)]
1052 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ValueType for $name $(<$($generic),+>)? {
1053 type Type = $name $(<$($generic),+>)?;
1054 }
1055
1056 #[doc(hidden)]
1057 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ValueTypeOptional for $name $(<$($generic),+>)? { }
1058
1059 #[doc(hidden)]
1060 unsafe impl <'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::value::FromValue<'a> for $name $(<$($generic),+>)? {
1061 type Checker = $crate::object::ObjectValueTypeChecker<Self >;
1062
1063 #[inline]
1064 unsafe fn from_value(value: &'a $crate::Value) -> Self {
1065 let ptr = $crate::gobject_ffi::g_value_dup_object($crate::translate::ToGlibPtr::to_glib_none(value).0 );
1066 debug_assert!(!ptr.is_null());
1067 debug_assert_ne!((*ptr).ref_count, 0 );
1068 <Self as $crate::translate::FromGlibPtrFull<*mut $ffi_name>>::from_glib_full(ptr as *mut $ffi_name)
1069 }
1070 }
1071
1072 #[doc(hidden)]
1073 unsafe impl <'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::value::FromValue<'a> for &'a $name $(<$($generic),+>)? {
1074 type Checker = $crate::object::ObjectValueTypeChecker<Self >;
1075
1076 #[inline]
1077 unsafe fn from_value(value: &'a $crate::Value) -> Self {
1078 let value = &*(value as *const $crate::Value as *const $crate::gobject_ffi::GValue);
1079 <$name $(<$($generic),+>)? as $crate::object::ObjectType>::from_glib_ptr_borrow(&*(&value.data[0 ].v_pointer as *const $crate::ffi::gpointer as *const *mut $ffi_name))
1080 }
1081 }
1082
1083 #[doc(hidden)]
1084 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ToValue for $name $(<$($generic),+>)? {
1085 #[inline]
1086 fn to_value(&self ) -> $crate::Value {
1087 unsafe {
1088 let mut value = $crate::Value::from_type_unchecked(<Self as $crate::prelude::StaticType>::static_type());
1089 $crate::gobject_ffi::g_value_take_object(
1090 $crate::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0 ,
1091 $crate::translate::ToGlibPtr::<*mut $ffi_name>::to_glib_full(self ) as *mut _,
1092 );
1093 value
1094 }
1095 }
1096
1097 #[inline]
1098 fn value_type(&self ) -> $crate::Type {
1099 <Self as $crate::prelude::StaticType>::static_type()
1100 }
1101 }
1102
1103 #[doc(hidden)]
1104 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? ::std::convert::From<$name $(<$($generic),+>)?> for $crate::Value {
1105 #[inline]
1106 fn from(o: $name $(<$($generic),+>)?) -> Self {
1107 unsafe {
1108 let mut value = $crate::Value::from_type_unchecked(<$name $(<$($generic),+>)? as $crate::prelude::StaticType>::static_type());
1109 $crate::gobject_ffi::g_value_take_object(
1110 $crate::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0 ,
1111 $crate::translate::IntoGlibPtr::<*mut $ffi_name>::into_glib_ptr(o) as *mut _,
1112 );
1113 value
1114 }
1115 }
1116 }
1117
1118 #[doc(hidden)]
1119 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ToValueOptional for $name $(<$($generic),+>)? {
1120 #[inline]
1121 fn to_value_optional(s: Option<&Self >) -> $crate::Value {
1122 let mut value = $crate::Value::for_value_type::<Self >();
1123 unsafe {
1124 $crate::gobject_ffi::g_value_take_object(
1125 $crate::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0 ,
1126 $crate::translate::ToGlibPtr::<*mut $ffi_name>::to_glib_full(&s) as *mut _,
1127 );
1128 }
1129
1130 value
1131 }
1132 }
1133
1134 $crate::glib_object_wrapper!(@weak_impl $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?);
1135
1136 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::HasParamSpec for $name $(<$($generic),+>)? {
1137 type ParamSpec = $crate::ParamSpecObject;
1138 type SetValue = Self ;
1139 type BuilderFn = fn (&str) -> $crate::ParamSpecObjectBuilder<Self >;
1140
1141 fn param_spec_builder() -> Self ::BuilderFn {
1142 |name| Self ::ParamSpec::builder(name)
1143 }
1144 }
1145 };
1146
1147 (@weak_impl $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?) => {
1148 #[doc(hidden)]
1149 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::clone::Downgrade for $name $(<$($generic),+>)? {
1150 type Weak = $crate::object::WeakRef<Self >;
1151
1152 #[inline]
1153 fn downgrade(&self ) -> Self ::Weak {
1154 <Self as $crate::object::ObjectExt>::downgrade(&self )
1155 }
1156 }
1157 };
1158
1159 (@munch_impls $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, ) => { };
1160
1161 (@munch_impls $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $super_name:path) => {
1162 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::IsA<$super_name> for $name $(<$($generic),+>)? { }
1163
1164 #[doc(hidden)]
1165 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? From<$name $(<$($generic),+>)?> for $super_name {
1166 #[inline]
1167 fn from(v: $name $(<$($generic),+>)?) -> Self {
1168 <$name $(::<$($generic),+>)? as $crate::prelude::Cast>::upcast(v)
1169 }
1170 }
1171
1172 #[doc(hidden)]
1173 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? AsRef<$super_name> for $name $(<$($generic),+>)? {
1174 #[inline]
1175 fn as_ref(&self ) -> &$super_name {
1176 $crate::object::Cast::upcast_ref(self )
1177 }
1178 }
1179
1180 #[doc(hidden)]
1181 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::borrow::Borrow<$super_name> for $name $(<$($generic),+>)? {
1182 #[inline]
1183 fn borrow(&self ) -> &$super_name {
1184 $crate::object::Cast::upcast_ref(self )
1185 }
1186 }
1187 };
1188
1189 (@munch_impls $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $super_name:path, $($implements:tt)*) => {
1190 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $super_name);
1191 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $($implements)*);
1192 };
1193
1194 // If there is no parent class, i.e. only glib::Object
1195 (@munch_first_impl $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, ) => {
1196 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, );
1197 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::ParentClassIs for $name $(<$($generic),+>)? {
1198 type Parent = $crate::object::Object;
1199 }
1200 };
1201
1202 // If there is only one parent class
1203 (@munch_first_impl $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $super_name:path) => {
1204 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $super_name);
1205 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::ParentClassIs for $name $(<$($generic),+>)? {
1206 type Parent = $super_name;
1207 }
1208 };
1209
1210 // If there is more than one parent class
1211 (@munch_first_impl $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $super_name:path, $($implements:tt)*) => {
1212 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $super_name);
1213 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::ParentClassIs for $name $(<$($generic),+>)? {
1214 type Parent = $super_name;
1215 }
1216 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $($implements)*);
1217 };
1218
1219 // This case is only for glib::Object itself below. All other cases have glib::Object in its
1220 // parent class list
1221 (@object [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $impl_type:ty, $parent_type:ty, $ffi_name:ty, @ffi_class $ffi_class_name:ty, @type_ $get_type_expr:expr) => {
1222 $crate::glib_object_wrapper!(
1223 @generic_impl [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $impl_type, $parent_type, $ffi_name, $ffi_class_name,
1224 @type_ $get_type_expr);
1225
1226 #[doc(hidden)]
1227 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::IsClass for $name $(<$($generic),+>)? { }
1228 };
1229
1230 (@object [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $impl_type:ty, $parent_type:ty, $ffi_name:ty,
1231 @type_ $get_type_expr:expr, @extends [$($extends:tt)*], @implements [$($implements:tt)*]) => {
1232 $crate::glib_object_wrapper!(
1233 @object [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $impl_type, $parent_type, $ffi_name, @ffi_class std::os::raw::c_void,
1234 @type_ $get_type_expr, @extends [$($extends)*], @implements [$($implements)*]
1235 );
1236 };
1237
1238 (@object [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $impl_type:ty, $parent_type:ty, $ffi_name:ty, @ffi_class $ffi_class_name:ty,
1239 @type_ $get_type_expr:expr, @extends [$($extends:tt)*], @implements [$($implements:tt)*]) => {
1240 $crate::glib_object_wrapper!(
1241 @generic_impl [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $impl_type, $parent_type, $ffi_name, $ffi_class_name,
1242 @type_ $get_type_expr
1243 );
1244
1245 $crate::glib_object_wrapper!(@munch_first_impl $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $($extends)*);
1246
1247 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $($implements)*);
1248
1249 #[doc(hidden)]
1250 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? AsRef<$crate::object::Object> for $name $(<$($generic),+>)? {
1251 #[inline]
1252 fn as_ref(&self ) -> &$crate::object::Object {
1253 $crate::object::Cast::upcast_ref(self )
1254 }
1255 }
1256
1257 #[doc(hidden)]
1258 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::borrow::Borrow<$crate::object::Object> for $name $(<$($generic),+>)? {
1259 #[inline]
1260 fn borrow(&self ) -> &$crate::object::Object {
1261 $crate::object::Cast::upcast_ref(self )
1262 }
1263 }
1264
1265 #[doc(hidden)]
1266 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? From<$name $(<$($generic),+>)?> for $crate::object::Object {
1267 #[inline]
1268 fn from(v: $name $(<$($generic),+>)?) -> Self {
1269 <$name $(::<$($generic),+>)? as $crate::prelude::Cast>::upcast(v)
1270 }
1271 }
1272
1273 #[doc(hidden)]
1274 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::IsA<$crate::object::Object> for $name $(<$($generic),+>)? { }
1275
1276 #[doc(hidden)]
1277 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::IsClass for $name $(<$($generic),+>)? { }
1278 };
1279
1280 // FIXME: Workaround for `glib::Object` not being `Send+Sync` but subclasses of it being both
1281 // if the impl struct is.
1282 (@object_subclass [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $subclass:ty,
1283 @extends [], @implements [$($implements:tt)*]) => {
1284 $crate::glib_object_wrapper!(
1285 @object [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?,
1286 $subclass, (),
1287 <$subclass as $crate::subclass::types::ObjectSubclass>::Instance,
1288 @ffi_class <$subclass as $crate::subclass::types::ObjectSubclass>::Class,
1289 @type_ $crate::translate::IntoGlib::into_glib(<$subclass as $crate::subclass::types::ObjectSubclassType>::type_()),
1290 @extends [], @implements [$($implements)*]
1291 );
1292
1293 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::ObjectSubclassIs for $name $(<$($generic),+>)? {
1294 type Subclass = $subclass;
1295 }
1296 };
1297
1298 (@object_subclass [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $subclass:ty,
1299 @extends [$($extends:tt)+], @implements [$($implements:tt)*]) => {
1300 $crate::glib_object_wrapper!(
1301 @object [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?,
1302 $subclass, <$subclass as $crate::subclass::types::ObjectSubclass>::ParentType,
1303 <$subclass as $crate::subclass::types::ObjectSubclass>::Instance,
1304 @ffi_class <$subclass as $crate::subclass::types::ObjectSubclass>::Class,
1305 @type_ $crate::translate::IntoGlib::into_glib(<$subclass as $crate::subclass::types::ObjectSubclassType>::type_()),
1306 @extends [$($extends)*], @implements [$($implements)*]
1307 );
1308
1309 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::ObjectSubclassIs for $name $(<$($generic),+>)? {
1310 type Subclass = $subclass;
1311 }
1312 };
1313
1314 (@interface [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $impl_type:ty, $ffi_name:ty,
1315 @type_ $get_type_expr:expr, @requires [$($requires:tt)*]) => {
1316 $crate::glib_object_wrapper!(
1317 @interface [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $impl_type, $ffi_name, @ffi_class std::os::raw::c_void,
1318 @type_ $get_type_expr, @requires [$($requires)*]
1319 );
1320 };
1321
1322 (@object_interface [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $iface:ty,
1323 @type_ $get_type_expr:expr, @requires [$($requires:tt)*]) => {
1324 $crate::glib_object_wrapper!(
1325 @interface [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $iface, <$iface as $crate::subclass::interface::ObjectInterface>::Instance,
1326 @ffi_class <$iface as $crate::subclass::interface::ObjectInterface>::Interface,
1327 @type_ $get_type_expr, @requires [$($requires)*]
1328 );
1329 };
1330
1331 (@interface [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $impl_type:ty, $ffi_name:ty, @ffi_class $ffi_class_name:ty,
1332 @type_ $get_type_expr:expr, @requires [$($requires:tt)*]) => {
1333 $crate::glib_object_wrapper!(
1334 @generic_impl [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $impl_type, (), $ffi_name, $ffi_class_name,
1335 @type_ $get_type_expr
1336 );
1337 $crate::glib_object_wrapper!(@munch_impls $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $($requires)*);
1338
1339 #[doc(hidden)]
1340 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? AsRef<$crate::object::Object> for $name $(<$($generic),+>)? {
1341 #[inline]
1342 fn as_ref(&self ) -> &$crate::object::Object {
1343 $crate::object::Cast::upcast_ref(self )
1344 }
1345 }
1346
1347 #[doc(hidden)]
1348 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::borrow::Borrow<$crate::object::Object> for $name $(<$($generic),+>)? {
1349 #[inline]
1350 fn borrow(&self ) -> &$crate::object::Object {
1351 $crate::object::Cast::upcast_ref(self )
1352 }
1353 }
1354
1355 #[doc(hidden)]
1356 impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? From<$name $(<$($generic),+>)?> for $crate::object::Object {
1357 #[inline]
1358 fn from(v: $name $(<$($generic),+>)?) -> Self {
1359 <$name $(::<$($generic),+>)? as $crate::prelude::Cast>::upcast(v)
1360 }
1361 }
1362
1363 #[doc(hidden)]
1364 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::IsA<$crate::object::Object> for $name $(<$($generic),+>)? { }
1365
1366 #[doc(hidden)]
1367 unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::object::IsInterface for $name $(<$($generic),+>)? { }
1368 };
1369 }
1370
1371 glib_object_wrapper !(@object
1372 [doc = "The base class in the object hierarchy." ]
1373 pub Object , * mut std ::os ::raw ::c_void , (), gobject_ffi ::GObject , @ffi_class gobject_ffi ::GObjectClass , @type_ gobject_ffi ::g_object_get_type ()
1374 );
1375 pub type ObjectClass = Class <Object >;
1376
1377 impl Object {
1378 pub const NONE: Option <&'static Object > = None ;
1379
1380 // rustdoc-stripper-ignore-next
1381 /// Create a new instance of an object with the default property values.
1382 ///
1383 /// # Panics
1384 ///
1385 /// This panics if the object is not instantiable.
1386 #[track_caller ]
1387 #[allow (clippy::new_ret_no_self)]
1388 pub fn new <T: IsA <Object > + IsClass >() -> T {
1389 let object = Object ::with_type (T::static_type ());
1390 unsafe { object .unsafe_cast () }
1391 }
1392
1393 // rustdoc-stripper-ignore-next
1394 /// Create a new instance of an object with the default property values.
1395 ///
1396 /// # Panics
1397 ///
1398 /// This panics if the object is not instantiable.
1399 #[track_caller ]
1400 pub fn with_type (type_ : Type ) -> Object {
1401 Object ::with_mut_values (type_ , &mut [])
1402 }
1403
1404 // rustdoc-stripper-ignore-next
1405 /// Create a new instance of an object of the given type with the given properties as mutable
1406 /// values.
1407 ///
1408 /// # Panics
1409 ///
1410 /// This panics if the object is not instantiable, doesn't have all the given properties or
1411 /// property values of the wrong type are provided.
1412 #[track_caller ]
1413 pub fn with_mut_values (type_ : Type , properties : &mut [(&str , Value )]) -> Object {
1414 #[cfg (feature = "gio" )]
1415 unsafe {
1416 let iface_type = from_glib (gio_sys ::g_initable_get_type ());
1417 if type_ .is_a (iface_type ) {
1418 panic !("Can't instantiate type ' {type_ }' implementing `gio::Initable`. Use `gio::Initable::new()`" );
1419 }
1420 let iface_type = from_glib (gio_sys ::g_async_initable_get_type ());
1421 if type_ .is_a (iface_type ) {
1422 panic !("Can't instantiate type ' {type_ }' implementing `gio::AsyncInitable`. Use `gio::AsyncInitable::new()`" );
1423 }
1424 }
1425
1426 unsafe { Object ::new_internal (type_ , properties ) }
1427 }
1428
1429 // rustdoc-stripper-ignore-next
1430 /// Create a new instance of an object of the given type with the given properties.
1431 ///
1432 /// # Panics
1433 ///
1434 /// This panics if the object is not instantiable, doesn't have all the given properties or
1435 /// property values of the wrong type are provided.
1436 ///
1437 /// Unlike the other constructors this does not panic if the object is implementing
1438 /// `gio::Initable` or `gio::AsyncInitable` and it might be unsafe to use the returned object
1439 /// without using the API of those interfaces first.
1440 #[track_caller ]
1441 pub unsafe fn new_internal (type_ : Type , properties : &mut [(&str , Value )]) -> Object {
1442 if !type_ .is_a (Object ::static_type ()) {
1443 panic !("Can't instantiate non-GObject type ' {type_ }'" );
1444 }
1445
1446 if gobject_ffi ::g_type_test_flags (
1447 type_ .into_glib (),
1448 gobject_ffi ::G_TYPE_FLAG_INSTANTIATABLE,
1449 ) == ffi ::GFALSE
1450 {
1451 panic !("Can't instantiate type ' {type_ }'" );
1452 }
1453
1454 if gobject_ffi ::g_type_test_flags (type_ .into_glib (), gobject_ffi ::G_TYPE_FLAG_ABSTRACT)
1455 != ffi ::GFALSE
1456 {
1457 panic !("Can't instantiate abstract type ' {type_ }'" );
1458 }
1459
1460 let mut property_names = smallvec ::SmallVec ::<[_; 16 ]>::with_capacity (properties .len ());
1461 let mut property_values = smallvec ::SmallVec ::<[_; 16 ]>::with_capacity (properties .len ());
1462
1463 if !properties .is_empty () {
1464 let klass = ObjectClass ::from_type (type_ )
1465 .unwrap_or_else (|| panic !("Can't retrieve class for type ' {type_ }'" ));
1466
1467 for (idx , (name , value )) in properties .iter_mut ().enumerate () {
1468 let pspec = klass
1469 .find_property (name )
1470 .unwrap_or_else (|| panic !("Can't find property ' {name }' for type ' {type_ }'" ));
1471
1472 if (pspec .flags ().contains (crate ::ParamFlags ::CONSTRUCT)
1473 || pspec .flags ().contains (crate ::ParamFlags ::CONSTRUCT_ONLY))
1474 && property_names [0 ..idx ]
1475 .iter ()
1476 .any (|other_name | pspec .name ().as_ptr () == *other_name )
1477 {
1478 panic !("Can't set construct property ' {name }' for type ' {type_ }' twice" );
1479 }
1480
1481 // FIXME: With GLib 2.74 and GParamSpecClass::value_is_valid() it is possible to
1482 // not require mutable values here except for when LAX_VALIDATION is provided and a
1483 // change is needed, or a GObject value needs it's GType changed.
1484 validate_property_type (type_ , true , &pspec , value );
1485
1486 property_names .push (pspec .name ().as_ptr ());
1487 property_values .push (*value .to_glib_none ().0 );
1488 }
1489 }
1490
1491 let ptr = gobject_ffi ::g_object_new_with_properties (
1492 type_ .into_glib (),
1493 properties .len () as u32 ,
1494 mut_override (property_names .as_ptr () as * const * const _),
1495 property_values .as_ptr (),
1496 );
1497
1498 if ptr .is_null () {
1499 panic !("Can't instantiate object for type ' {type_ }'" );
1500 } else if type_ .is_a (InitiallyUnowned ::static_type ()) {
1501 // Attention: This takes ownership of the floating reference
1502 from_glib_none (ptr )
1503 } else {
1504 from_glib_full (ptr )
1505 }
1506 }
1507
1508 // rustdoc-stripper-ignore-next
1509 /// Create a new object builder for a specific type.
1510 pub fn builder <'a, O: IsA <Object > + IsClass >() -> ObjectBuilder <'a, O> {
1511 ObjectBuilder ::new (O::static_type ())
1512 }
1513
1514 // rustdoc-stripper-ignore-next
1515 /// Create a new object builder for a specific type.
1516 pub fn builder_with_type <'a>(type_ : Type ) -> ObjectBuilder <'a, Object > {
1517 ObjectBuilder ::new (type_ )
1518 }
1519 }
1520
1521 #[must_use = "builder doesn't do anything unless built" ]
1522 pub struct ObjectBuilder <'a, O> {
1523 type_ : Type ,
1524 properties : smallvec ::SmallVec <[(&'a str , Value ); 16 ]>,
1525 phantom : PhantomData <O>,
1526 }
1527
1528 impl <'a, O: IsA <Object > + IsClass > ObjectBuilder <'a, O> {
1529 #[inline ]
1530 fn new (type_ : Type ) -> Self {
1531 ObjectBuilder {
1532 type_ ,
1533 properties : smallvec ::SmallVec ::new (),
1534 phantom : PhantomData ,
1535 }
1536 }
1537
1538 // rustdoc-stripper-ignore-next
1539 /// Gets the type of this builder.
1540 #[inline ]
1541 pub fn type_ (&self) -> Type {
1542 self.type_
1543 }
1544
1545 // rustdoc-stripper-ignore-next
1546 /// Sets property `name` to the given value `value`.
1547 ///
1548 /// Overrides any default or previously defined value for `name`.
1549 pub fn property (self, name : &'a str , value : impl Into <Value >) -> Self {
1550 let ObjectBuilder {
1551 type_ ,
1552 mut properties ,
1553 ..
1554 } = self;
1555 properties .push ((name , value .into ()));
1556
1557 ObjectBuilder {
1558 type_ ,
1559 properties ,
1560 phantom : PhantomData ,
1561 }
1562 }
1563
1564 // rustdoc-stripper-ignore-next
1565 /// Sets property `name` to the given inner value if the `predicate` evaluates to `true`.
1566 ///
1567 /// This has no effect if the `predicate` evaluates to `false`,
1568 /// i.e. default or previous value for `name` is kept.
1569 #[inline ]
1570 pub fn property_if (self, name : &'a str , value : impl Into <Value >, predicate : bool ) -> Self {
1571 if predicate {
1572 self.property (name , value )
1573 } else {
1574 self
1575 }
1576 }
1577
1578 // rustdoc-stripper-ignore-next
1579 /// Sets property `name` to the given inner value if `value` is `Some`.
1580 ///
1581 /// This has no effect if the value is `None`, i.e. default or previous value for `name` is kept.
1582 #[inline ]
1583 pub fn property_if_some (self, name : &'a str , value : Option <impl Into <Value >>) -> Self {
1584 if let Some (value ) = value {
1585 self.property (name , value )
1586 } else {
1587 self
1588 }
1589 }
1590
1591 // rustdoc-stripper-ignore-next
1592 /// Sets property `name` using the given `ValueType` `V` built from `iter`'s the `Item`s.
1593 ///
1594 /// Overrides any default or previously defined value for `name`.
1595 #[inline ]
1596 pub fn property_from_iter <V: ValueType + Into <Value > + FromIterator <Value >>(
1597 self,
1598 name : &'a str ,
1599 iter : impl IntoIterator <Item = impl Into <Value >>,
1600 ) -> Self {
1601 let iter = iter .into_iter ().map (|item | item .into ());
1602 self.property (name , V::from_iter (iter ))
1603 }
1604
1605 // rustdoc-stripper-ignore-next
1606 /// Sets property `name` using the given `ValueType` `V` built from `iter`'s Item`s,
1607 /// if `iter` is not empty.
1608 ///
1609 /// This has no effect if `iter` is empty, i.e. previous property value for `name` is unchanged.
1610 #[inline ]
1611 pub fn property_if_not_empty <V: ValueType + Into <Value > + FromIterator <Value >>(
1612 self,
1613 name : &'a str ,
1614 iter : impl IntoIterator <Item = impl Into <Value >>,
1615 ) -> Self {
1616 let mut iter = iter .into_iter ().peekable ();
1617 if iter .peek ().is_some () {
1618 let iter = iter .map (|item | item .into ());
1619 self.property (name , V::from_iter (iter ))
1620 } else {
1621 self
1622 }
1623 }
1624
1625 // rustdoc-stripper-ignore-next
1626 /// Build the object with the provided properties.
1627 ///
1628 /// # Panics
1629 ///
1630 /// This panics if the object is not instantiable, doesn't have all the given properties or
1631 /// property values of the wrong type are provided.
1632 #[track_caller ]
1633 #[inline ]
1634 pub fn build (mut self) -> O {
1635 let object = Object ::with_mut_values (self.type_ , &mut self.properties );
1636 unsafe { object .unsafe_cast ::<O>() }
1637 }
1638 }
1639
1640 #[must_use = "if unused the property notifications will immediately be thawed" ]
1641 pub struct PropertyNotificationFreezeGuard (ObjectRef );
1642
1643 impl Drop for PropertyNotificationFreezeGuard {
1644 #[doc (alias = "g_object_thaw_notify" )]
1645 #[inline ]
1646 fn drop (&mut self) {
1647 unsafe { gobject_ffi ::g_object_thaw_notify (self.0 .to_glib_none ().0 ) }
1648 }
1649 }
1650
1651 pub trait ObjectExt : ObjectType {
1652 // rustdoc-stripper-ignore-next
1653 /// Returns `true` if the object is an instance of (can be cast to) `T`.
1654 fn is <T: StaticType >(&self) -> bool ;
1655
1656 // rustdoc-stripper-ignore-next
1657 /// Returns the type of the object.
1658 #[doc (alias = "get_type" )]
1659 fn type_ (&self) -> Type ;
1660
1661 // rustdoc-stripper-ignore-next
1662 /// Returns the [`ObjectClass`] of the object.
1663 ///
1664 /// This is equivalent to calling `obj.class().upcast_ref::<ObjectClass>()`.
1665 #[doc (alias = "get_object_class" )]
1666 fn object_class (&self) -> &ObjectClass ;
1667
1668 /// Returns the class of the object.
1669 #[doc (alias = "get_class" )]
1670 fn class (&self) -> &Class <Self>
1671 where
1672 Self: IsClass ;
1673
1674 // rustdoc-stripper-ignore-next
1675 /// Returns the class of the object in the given type `T`.
1676 ///
1677 /// `None` is returned if the object is not a subclass of `T`.
1678 #[doc (alias = "get_class_of" )]
1679 fn class_of <T: IsClass >(&self) -> Option <&Class <T>>;
1680
1681 // rustdoc-stripper-ignore-next
1682 /// Returns the interface `T` of the object.
1683 ///
1684 /// `None` is returned if the object does not implement the interface `T`.
1685 #[doc (alias = "get_interface" )]
1686 fn interface <T: IsInterface >(&self) -> Option <InterfaceRef <T>>;
1687
1688 // rustdoc-stripper-ignore-next
1689 /// Sets the property `property_name` of the object to value `value`.
1690 ///
1691 /// # Panics
1692 ///
1693 /// If the property does not exist, if the type of the property is different than
1694 /// the provided value, or if the property is not writable.
1695 #[doc (alias = "g_object_set_property" )]
1696 fn set_property (&self, property_name : &str , value : impl Into <Value >);
1697
1698 // rustdoc-stripper-ignore-next
1699 /// Sets the property `property_name` of the object to value `value`.
1700 ///
1701 /// # Panics
1702 ///
1703 /// If the property does not exist, the type of the property is different than the
1704 /// provided value, or if the property is not writable.
1705 #[doc (alias = "g_object_set_property" )]
1706 fn set_property_from_value (&self, property_name : &str , value : &Value );
1707
1708 // rustdoc-stripper-ignore-next
1709 /// Sets multiple properties of the object at once.
1710 ///
1711 /// # Panics
1712 ///
1713 /// This does not set any properties if one or more properties don't exist, values of the wrong
1714 /// type are provided, or if any of the properties is not writable.
1715 #[doc (alias = "g_object_set" )]
1716 fn set_properties (&self, property_values : &[(&str , &dyn ToValue )]);
1717
1718 // rustdoc-stripper-ignore-next
1719 /// Sets multiple properties of the object at once.
1720 ///
1721 /// # Panics
1722 ///
1723 /// This does not set any properties if one or more properties don't exist, values of the wrong
1724 /// type are provided, or if any of the properties is not writable.
1725 #[doc (alias = "g_object_set" )]
1726 fn set_properties_from_value (&self, property_values : &[(&str , Value )]);
1727
1728 // rustdoc-stripper-ignore-next
1729 /// Gets the property `property_name` of the object and cast it to the type V.
1730 ///
1731 /// # Panics
1732 ///
1733 /// If the property doesn't exist or is not readable or of a different type than V.
1734 #[doc (alias = "get_property" )]
1735 #[doc (alias = "g_object_get_property" )]
1736 fn property <V: for <'b> FromValue <'b> + 'static>(&self, property_name : &str ) -> V;
1737
1738 // rustdoc-stripper-ignore-next
1739 /// Gets the property `property_name` of the object.
1740 ///
1741 /// # Panics
1742 ///
1743 /// If the property does not exist or is not writable.
1744 #[doc (alias = "get_property" )]
1745 #[doc (alias = "g_object_get_property" )]
1746 fn property_value (&self, property_name : &str ) -> Value ;
1747
1748 // rustdoc-stripper-ignore-next
1749 /// Check if the object has a property `property_name` of the given `type_`.
1750 ///
1751 /// If no type is provided then only the existence of the property is checked.
1752 fn has_property (&self, property_name : &str , type_ : Option <Type >) -> bool ;
1753
1754 // rustdoc-stripper-ignore-next
1755 /// Get the type of the property `property_name` of this object.
1756 ///
1757 /// This returns `None` if the property does not exist.
1758 #[doc (alias = "get_property_type" )]
1759 fn property_type (&self, property_name : &str ) -> Option <Type >;
1760
1761 // rustdoc-stripper-ignore-next
1762 /// Get the [`ParamSpec`](crate::ParamSpec) of the property `property_name` of this object.
1763 fn find_property (&self, property_name : &str ) -> Option <crate ::ParamSpec >;
1764
1765 // rustdoc-stripper-ignore-next
1766 /// Return all [`ParamSpec`](crate::ParamSpec) of the properties of this object.
1767 fn list_properties (&self) -> PtrSlice <crate ::ParamSpec >;
1768
1769 // rustdoc-stripper-ignore-next
1770 /// Freeze all property notifications until the return guard object is dropped.
1771 ///
1772 /// This prevents the `notify` signal for all properties of this object to be emitted.
1773 #[doc (alias = "g_object_freeze_notify" )]
1774 fn freeze_notify (&self) -> PropertyNotificationFreezeGuard ;
1775
1776 // rustdoc-stripper-ignore-next
1777 /// Set arbitrary data on this object with the given `key`.
1778 ///
1779 /// # Safety
1780 ///
1781 /// This function doesn't store type information
1782 unsafe fn set_qdata <QD: 'static>(&self, key : Quark , value : QD);
1783
1784 // rustdoc-stripper-ignore-next
1785 /// Return previously set arbitrary data of this object with the given `key`.
1786 ///
1787 /// # Safety
1788 ///
1789 /// The returned pointer can become invalid by a call to
1790 /// `set_qdata`, `steal_qdata`, `set_data` or `steal_data`.
1791 ///
1792 /// The caller is responsible for ensuring the returned value is of a suitable type
1793 #[doc (alias = "get_qdata" )]
1794 unsafe fn qdata <QD: 'static>(&self, key : Quark ) -> Option <ptr ::NonNull <QD>>;
1795
1796 // rustdoc-stripper-ignore-next
1797 /// Retrieve previously set arbitrary data of this object with the given `key`.
1798 ///
1799 /// The data is not set on the object anymore afterwards.
1800 ///
1801 /// # Safety
1802 ///
1803 /// The caller is responsible for ensuring the returned value is of a suitable type
1804 unsafe fn steal_qdata <QD: 'static>(&self, key : Quark ) -> Option <QD>;
1805
1806 // rustdoc-stripper-ignore-next
1807 /// Set arbitrary data on this object with the given `key`.
1808 ///
1809 /// # Safety
1810 ///
1811 /// This function doesn't store type information
1812 unsafe fn set_data <QD: 'static>(&self, key : &str , value : QD);
1813
1814 // rustdoc-stripper-ignore-next
1815 /// Return previously set arbitrary data of this object with the given `key`.
1816 ///
1817 /// # Safety
1818 ///
1819 /// The returned pointer can become invalid by a call to
1820 /// `set_qdata`, `steal_qdata`, `set_data` or `steal_data`.
1821 ///
1822 /// The caller is responsible for ensuring the returned value is of a suitable type
1823 #[doc (alias = "get_data" )]
1824 unsafe fn data <QD: 'static>(&self, key : &str ) -> Option <ptr ::NonNull <QD>>;
1825
1826 // rustdoc-stripper-ignore-next
1827 /// Retrieve previously set arbitrary data of this object with the given `key`.
1828 ///
1829 /// The data is not set on the object anymore afterwards.
1830 ///
1831 /// # Safety
1832 ///
1833 /// The caller is responsible for ensuring the returned value is of a suitable type
1834 unsafe fn steal_data <QD: 'static>(&self, key : &str ) -> Option <QD>;
1835
1836 // rustdoc-stripper-ignore-next
1837 /// Block a given signal handler.
1838 ///
1839 /// It will not be called again during signal emissions until it is unblocked.
1840 #[doc (alias = "g_signal_handler_block" )]
1841 fn block_signal (&self, handler_id : &SignalHandlerId );
1842
1843 // rustdoc-stripper-ignore-next
1844 /// Unblock a given signal handler.
1845 #[doc (alias = "g_signal_handler_unblock" )]
1846 fn unblock_signal (&self, handler_id : &SignalHandlerId );
1847
1848 // rustdoc-stripper-ignore-next
1849 /// Stop emission of the currently emitted signal.
1850 #[doc (alias = "g_signal_stop_emission" )]
1851 fn stop_signal_emission (&self, signal_id : SignalId , detail : Option <Quark >);
1852
1853 // rustdoc-stripper-ignore-next
1854 /// Stop emission of the currently emitted signal by the (possibly detailed) signal name.
1855 #[doc (alias = "g_signal_stop_emission_by_name" )]
1856 fn stop_signal_emission_by_name (&self, signal_name : &str );
1857
1858 // rustdoc-stripper-ignore-next
1859 /// Connect to the signal `signal_name` on this object.
1860 ///
1861 /// If `after` is set to `true` then the callback will be called after the default class
1862 /// handler of the signal is emitted, otherwise before.
1863 ///
1864 /// # Panics
1865 ///
1866 /// If the signal does not exist.
1867 fn connect <F>(&self, signal_name : &str , after : bool , callback : F) -> SignalHandlerId
1868 where
1869 F: Fn (&[Value ]) -> Option <Value > + Send + Sync + 'static;
1870
1871 // rustdoc-stripper-ignore-next
1872 /// Connect to the signal `signal_id` on this object.
1873 ///
1874 /// If `after` is set to `true` then the callback will be called after the default class
1875 /// handler of the signal is emitted, otherwise before.
1876 ///
1877 /// Same as [`Self::connect`] but takes a `SignalId` instead of a signal name.
1878 ///
1879 /// # Panics
1880 ///
1881 /// If the signal does not exist.
1882 fn connect_id <F>(
1883 &self,
1884 signal_id : SignalId ,
1885 details : Option <Quark >,
1886 after : bool ,
1887 callback : F,
1888 ) -> SignalHandlerId
1889 where
1890 F: Fn (&[Value ]) -> Option <Value > + Send + Sync + 'static;
1891
1892 // rustdoc-stripper-ignore-next
1893 /// Connect to the signal `signal_name` on this object.
1894 ///
1895 /// If `after` is set to `true` then the callback will be called after the default class
1896 /// handler of the signal is emitted, otherwise before.
1897 ///
1898 /// Same as [`Self::connect`] but takes a non-`Send+Sync` closure. If the signal is emitted from a
1899 /// different thread than it was connected to then the signal emission will panic.
1900 ///
1901 /// # Panics
1902 ///
1903 /// If the signal does not exist.
1904 fn connect_local <F>(&self, signal_name : &str , after : bool , callback : F) -> SignalHandlerId
1905 where
1906 F: Fn (&[Value ]) -> Option <Value > + 'static;
1907
1908 // rustdoc-stripper-ignore-next
1909 /// Connect to the signal `signal_id` on this object.
1910 ///
1911 /// If `after` is set to `true` then the callback will be called after the default class
1912 /// handler of the signal is emitted, otherwise before.
1913 ///
1914 /// Same as [`Self::connect_id`] but takes a non-`Send+Sync` closure. If the signal is emitted from a
1915 /// different thread than it was connected to then the signal emission will panic.
1916 ///
1917 /// # Panics
1918 ///
1919 /// This panics if the signal does not exist.
1920 fn connect_local_id <F>(
1921 &self,
1922 signal_id : SignalId ,
1923 details : Option <Quark >,
1924 after : bool ,
1925 callback : F,
1926 ) -> SignalHandlerId
1927 where
1928 F: Fn (&[Value ]) -> Option <Value > + 'static;
1929
1930 // rustdoc-stripper-ignore-next
1931 /// Connect to the signal `signal_name` on this object.
1932 ///
1933 /// If `after` is set to `true` then the callback will be called after the default class
1934 /// handler of the signal is emitted, otherwise before.
1935 ///
1936 /// Same as [`Self::connect`] but takes a non-`Send+Sync` and non-`'static'` closure. No runtime checks
1937 /// are performed for ensuring that the closure is called correctly.
1938 ///
1939 /// # Safety
1940 ///
1941 /// The provided closure must be valid until the signal handler is disconnected, and it must
1942 /// be allowed to call the closure from the threads the signal is emitted from.
1943 ///
1944 /// # Panics
1945 ///
1946 /// If the signal does not exist.
1947 unsafe fn connect_unsafe <F>(
1948 &self,
1949 signal_name : &str ,
1950 after : bool ,
1951 callback : F,
1952 ) -> SignalHandlerId
1953 where
1954 F: Fn (&[Value ]) -> Option <Value >;
1955
1956 // rustdoc-stripper-ignore-next
1957 /// Connect to the signal `signal_id` on this object.
1958 ///
1959 /// If `after` is set to `true` then the callback will be called after the default class
1960 /// handler of the signal is emitted, otherwise before.
1961 ///
1962 ///
1963 /// Same as [`Self::connect_id`] but takes a non-`Send+Sync` and non-`'static'` closure. No runtime checks
1964 /// are performed for ensuring that the closure is called correctly.
1965 ///
1966 /// # Safety
1967 ///
1968 /// The provided closure must be valid until the signal handler is disconnected, and it must
1969 /// be allowed to call the closure from the threads the signal is emitted from.
1970 ///
1971 /// # Panics
1972 ///
1973 /// If the signal does not exist.
1974 unsafe fn connect_unsafe_id <F>(
1975 &self,
1976 signal_id : SignalId ,
1977 details : Option <Quark >,
1978 after : bool ,
1979 callback : F,
1980 ) -> SignalHandlerId
1981 where
1982 F: Fn (&[Value ]) -> Option <Value >;
1983
1984 // rustdoc-stripper-ignore-next
1985 /// Connect a closure to the signal `signal_name` on this object.
1986 ///
1987 /// If `after` is set to `true` then the callback will be called after the default class
1988 /// handler of the signal is emitted, otherwise before.
1989 ///
1990 /// This panics if the signal does not exist.
1991 ///
1992 /// A recurring case is connecting a handler which will be automatically disconnected
1993 /// when an object it refers to is destroyed, as it happens with `g_signal_connect_object`
1994 /// in C. This can be achieved with a closure that watches an object: see the documentation
1995 /// of the [`closure!`](crate::closure!) macro for more details.
1996 ///
1997 /// Same as [`Self::connect`] but takes a [`Closure`] instead of a `Fn`.
1998 #[doc (alias = "g_signal_connect_closure" )]
1999 #[doc (alias = "g_signal_connect_object" )]
2000 fn connect_closure (
2001 &self,
2002 signal_name : &str ,
2003 after : bool ,
2004 closure : RustClosure ,
2005 ) -> SignalHandlerId ;
2006
2007 // rustdoc-stripper-ignore-next
2008 /// Connect a closure to the signal `signal_id` on this object.
2009 ///
2010 /// If `after` is set to `true` then the callback will be called after the default class
2011 /// handler of the signal is emitted, otherwise before.
2012 ///
2013 /// This panics if the signal does not exist.
2014 ///
2015 /// Same as [`Self::connect_closure`] but takes a
2016 /// [`SignalId`] instead of a signal name.
2017 #[doc (alias = "g_signal_connect_closure_by_id" )]
2018 fn connect_closure_id (
2019 &self,
2020 signal_id : SignalId ,
2021 details : Option <Quark >,
2022 after : bool ,
2023 closure : RustClosure ,
2024 ) -> SignalHandlerId ;
2025
2026 // rustdoc-stripper-ignore-next
2027 /// Limits the lifetime of `closure` to the lifetime of the object. When
2028 /// the object's reference count drops to zero, the closure will be
2029 /// invalidated. An invalidated closure will ignore any calls to
2030 /// [`invoke_with_values`](crate::closure::Closure::invoke_with_values) , or
2031 /// [`invoke`](crate::closure::RustClosure::invoke) when using Rust closures.
2032 #[doc (alias = "g_object_watch_closure" )]
2033 fn watch_closure (&self, closure : &impl AsRef <Closure >);
2034
2035 // rustdoc-stripper-ignore-next
2036 /// Emit signal by signal id.
2037 ///
2038 /// If the signal has a return value then this is returned here.
2039 ///
2040 /// # Panics
2041 ///
2042 /// If the wrong number of arguments is provided, or arguments of the wrong types
2043 /// were provided.
2044 #[doc (alias = "g_signal_emitv" )]
2045 fn emit <R: TryFromClosureReturnValue >(&self, signal_id : SignalId , args : &[&dyn ToValue ]) -> R;
2046
2047 // rustdoc-stripper-ignore-next
2048 /// Same as [`Self::emit`] but takes `Value` for the arguments.
2049 fn emit_with_values (&self, signal_id : SignalId , args : &[Value ]) -> Option <Value >;
2050
2051 // rustdoc-stripper-ignore-next
2052 /// Emit signal by its name.
2053 ///
2054 /// If the signal has a return value then this is returned here.
2055 ///
2056 /// # Panics
2057 ///
2058 /// If the signal does not exist, the wrong number of arguments is provided, or
2059 /// arguments of the wrong types were provided.
2060 #[doc (alias = "g_signal_emit_by_name" )]
2061 fn emit_by_name <R: TryFromClosureReturnValue >(
2062 &self,
2063 signal_name : &str ,
2064 args : &[&dyn ToValue ],
2065 ) -> R;
2066
2067 // rustdoc-stripper-ignore-next
2068 /// Emit signal by its name.
2069 ///
2070 /// If the signal has a return value then this is returned here.
2071 ///
2072 /// # Panics
2073 ///
2074 /// If the signal does not exist, the wrong number of arguments is provided, or
2075 /// arguments of the wrong types were provided.
2076 fn emit_by_name_with_values (&self, signal_name : &str , args : &[Value ]) -> Option <Value >;
2077
2078 // rustdoc-stripper-ignore-next
2079 /// Emit signal by its name with details.
2080 ///
2081 /// If the signal has a return value then this is returned here.
2082 ///
2083 /// # Panics
2084 ///
2085 /// If the wrong number of arguments is provided, or arguments of the wrong types
2086 /// were provided.
2087 fn emit_by_name_with_details <R: TryFromClosureReturnValue >(
2088 &self,
2089 signal_name : &str ,
2090 details : Quark ,
2091 args : &[&dyn ToValue ],
2092 ) -> R;
2093
2094 // rustdoc-stripper-ignore-next
2095 /// Emit signal by its name with details.
2096 ///
2097 /// If the signal has a return value then this is returned here.
2098 ///
2099 /// # Panics
2100 ///
2101 /// If the wrong number of arguments is provided, or arguments of the wrong types
2102 /// were provided.
2103 fn emit_by_name_with_details_and_values (
2104 &self,
2105 signal_name : &str ,
2106 details : Quark ,
2107 args : &[Value ],
2108 ) -> Option <Value >;
2109
2110 // rustdoc-stripper-ignore-next
2111 /// Emit signal by signal id with details.
2112 ///
2113 /// If the signal has a return value then this is returned here.
2114 ///
2115 /// # Panics
2116 ///
2117 /// If the wrong number of arguments is provided, or arguments of the wrong types
2118 /// were provided.
2119 fn emit_with_details <R: TryFromClosureReturnValue >(
2120 &self,
2121 signal_id : SignalId ,
2122 details : Quark ,
2123 args : &[&dyn ToValue ],
2124 ) -> R;
2125
2126 // rustdoc-stripper-ignore-next
2127 /// Emit signal by signal id with details.
2128 ///
2129 /// If the signal has a return value then this is returned here.
2130 ///
2131 /// # Panics
2132 ///
2133 /// If the wrong number of arguments is provided, or arguments of the wrong types
2134 /// were provided.
2135 fn emit_with_details_and_values (
2136 &self,
2137 signal_id : SignalId ,
2138 details : Quark ,
2139 args : &[Value ],
2140 ) -> Option <Value >;
2141
2142 // rustdoc-stripper-ignore-next
2143 /// Disconnect a previously connected signal handler.
2144 #[doc (alias = "g_signal_handler_disconnect" )]
2145 fn disconnect (&self, handler_id : SignalHandlerId );
2146
2147 // rustdoc-stripper-ignore-next
2148 /// Connect to the `notify` signal of the object.
2149 ///
2150 /// This is emitted whenever a property is changed. If `name` is provided then the signal
2151 /// handler is only called for this specific property.
2152 fn connect_notify <F: Fn (&Self, &crate ::ParamSpec ) + Send + Sync + 'static>(
2153 &self,
2154 name : Option <&str >,
2155 f : F,
2156 ) -> SignalHandlerId ;
2157
2158 // rustdoc-stripper-ignore-next
2159 /// Connect to the `notify` signal of the object.
2160 ///
2161 /// This is emitted whenever a property is changed. If `name` is provided then the signal
2162 /// handler is only called for this specific property.
2163 ///
2164 /// This is like `connect_notify` but doesn't require a `Send+Sync` closure. Signal emission
2165 /// will panic if the signal is emitted from the wrong thread.
2166 fn connect_notify_local <F: Fn (&Self, &crate ::ParamSpec ) + 'static>(
2167 &self,
2168 name : Option <&str >,
2169 f : F,
2170 ) -> SignalHandlerId ;
2171
2172 // rustdoc-stripper-ignore-next
2173 /// Connect to the `notify` signal of the object.
2174 ///
2175 /// This is emitted whenever a property is changed. If `name` is provided then the signal
2176 /// handler is only called for this specific property.
2177 ///
2178 /// This is like `connect_notify` but doesn't require a `Send+Sync` or `'static` closure. No
2179 /// runtime checks for wrongly calling the closure are performed.
2180 ///
2181 /// # Safety
2182 ///
2183 /// The provided closure must be valid until the signal handler is disconnected, and it must
2184 /// be allowed to call the closure from the threads the signal is emitted from.
2185 unsafe fn connect_notify_unsafe <F: Fn (&Self, &crate ::ParamSpec )>(
2186 &self,
2187 name : Option <&str >,
2188 f : F,
2189 ) -> SignalHandlerId ;
2190
2191 // rustdoc-stripper-ignore-next
2192 /// Notify that the given property has changed its value.
2193 ///
2194 /// This emits the `notify` signal.
2195 #[doc (alias = "g_object_notify" )]
2196 fn notify (&self, property_name : &str );
2197
2198 // rustdoc-stripper-ignore-next
2199 /// Notify that the given property has changed its value.
2200 ///
2201 /// This emits the `notify` signal.
2202 #[doc (alias = "g_object_notify_by_pspec" )]
2203 fn notify_by_pspec (&self, pspec : &crate ::ParamSpec );
2204
2205 // rustdoc-stripper-ignore-next
2206 /// Downgrade this object to a weak reference.
2207 fn downgrade (&self) -> WeakRef <Self>;
2208
2209 // rustdoc-stripper-ignore-next
2210 /// Add a callback to be notified when the Object is disposed.
2211 #[doc (alias = "g_object_weak_ref" )]
2212 #[doc (alias = "connect_drop" )]
2213 fn add_weak_ref_notify <F: FnOnce () + Send + 'static>(&self, f : F) -> WeakRefNotify <Self>;
2214
2215 // rustdoc-stripper-ignore-next
2216 /// Add a callback to be notified when the Object is disposed.
2217 ///
2218 /// This is like [`add_weak_ref_notify`][`ObjectExt::add_weak_ref_notify`] but doesn't require the closure to be [`Send`] .
2219 /// Object dispose will panic if the object is disposed from the wrong thread.
2220 #[doc (alias = "g_object_weak_ref" )]
2221 #[doc (alias = "connect_drop" )]
2222 fn add_weak_ref_notify_local <F: FnOnce () + 'static>(&self, f : F) -> WeakRefNotify <Self>;
2223
2224 // rustdoc-stripper-ignore-next
2225 /// Bind property `source_property` on this object to the `target_property` on the `target` object.
2226 ///
2227 /// This allows keeping the properties of both objects in sync.
2228 ///
2229 /// The binding can be unidirectional or bidirectional and optionally it is possible to
2230 /// transform the property values before they're passed to the other object.
2231 fn bind_property <'a, 'f, 't, O: ObjectType >(
2232 &'a self,
2233 source_property : &'a str ,
2234 target : &'a O,
2235 target_property : &'a str ,
2236 ) -> BindingBuilder <'a, 'f, 't>;
2237
2238 // rustdoc-stripper-ignore-next
2239 /// Returns the strong reference count of this object.
2240 fn ref_count (&self) -> u32 ;
2241
2242 // rustdoc-stripper-ignore-next
2243 /// Runs the dispose mechanism of the object.
2244 ///
2245 /// This will dispose of any references the object has to other objects, and among other things
2246 /// will disconnect all signal handlers.
2247 ///
2248 /// # Safety
2249 ///
2250 /// Theoretically this is safe to run and afterwards the object is simply in a non-functional
2251 /// state, however many object implementations in C end up with memory safety issues if the
2252 /// object is used after disposal.
2253 #[doc (alias = "g_object_run_dispose" )]
2254 unsafe fn run_dispose (&self);
2255 }
2256
2257 impl <T: ObjectType > ObjectExt for T {
2258 #[inline ]
2259 fn is <U: StaticType >(&self) -> bool {
2260 self.type_ ().is_a (U::static_type ())
2261 }
2262
2263 #[inline ]
2264 fn type_ (&self) -> Type {
2265 self.object_class ().type_ ()
2266 }
2267
2268 #[inline ]
2269 fn object_class (&self) -> &ObjectClass {
2270 unsafe {
2271 let obj : * mut gobject_ffi ::GObject = self.as_object_ref ().to_glib_none ().0 ;
2272 let klass = (*obj ).g_type_instance .g_class as * const ObjectClass ;
2273 &*klass
2274 }
2275 }
2276
2277 #[inline ]
2278 fn class (&self) -> &Class <Self>
2279 where
2280 Self: IsClass ,
2281 {
2282 unsafe {
2283 let obj : * mut gobject_ffi ::GObject = self.as_object_ref ().to_glib_none ().0 ;
2284 let klass = (*obj ).g_type_instance .g_class as * const Class <Self>;
2285 &*klass
2286 }
2287 }
2288
2289 #[inline ]
2290 fn class_of <U: IsClass >(&self) -> Option <&Class <U>> {
2291 if !self.is ::<U>() {
2292 return None ;
2293 }
2294
2295 unsafe {
2296 let obj : * mut gobject_ffi ::GObject = self.as_object_ref ().to_glib_none ().0 ;
2297 let klass = (*obj ).g_type_instance .g_class as * const Class <U>;
2298 Some (&*klass )
2299 }
2300 }
2301
2302 #[inline ]
2303 fn interface <U: IsInterface >(&self) -> Option <InterfaceRef <U>> {
2304 Interface ::from_class (self.object_class ())
2305 }
2306
2307 #[track_caller ]
2308 fn set_property (&self, property_name : &str , value : impl Into <Value >) {
2309 let pspec = self.find_property (property_name ).unwrap_or_else (|| {
2310 panic !(
2311 "property ' {property_name }' of type ' {}' not found" ,
2312 self.type_ ()
2313 )
2314 });
2315
2316 let mut property_value = value .into ();
2317 validate_property_type (self.type_ (), false , &pspec , &mut property_value );
2318 unsafe {
2319 gobject_ffi ::g_object_set_property (
2320 self.as_object_ref ().to_glib_none ().0 ,
2321 pspec .name ().as_ptr () as * const _,
2322 property_value .to_glib_none ().0 ,
2323 );
2324 }
2325 }
2326
2327 #[track_caller ]
2328 fn set_property_from_value (&self, property_name : &str , value : &Value ) {
2329 let pspec = match self.find_property (property_name ) {
2330 Some (pspec ) => pspec ,
2331 None => {
2332 panic !(
2333 "property ' {property_name }' of type ' {}' not found" ,
2334 self.type_ ()
2335 );
2336 }
2337 };
2338
2339 // FIXME: With GLib 2.74 and GParamSpecClass::value_is_valid() it is possible to
2340 // not require mutable values here except for when LAX_VALIDATION is provided and a
2341 // change is needed, or a GObject value needs it's GType changed.
2342 let mut property_value = value .clone ();
2343 validate_property_type (self.type_ (), false , &pspec , &mut property_value );
2344 unsafe {
2345 gobject_ffi ::g_object_set_property (
2346 self.as_object_ref ().to_glib_none ().0 ,
2347 pspec .name ().as_ptr () as * const _,
2348 property_value .to_glib_none ().0 ,
2349 );
2350 }
2351 }
2352
2353 #[track_caller ]
2354 fn set_properties (&self, property_values : &[(&str , &dyn ToValue )]) {
2355 let params = property_values
2356 .iter ()
2357 .map (|&(name , value )| {
2358 let pspec = self.find_property (name ).unwrap_or_else (|| {
2359 panic !("Can't find property ' {name }' for type ' {}'" , self.type_ ());
2360 });
2361
2362 let mut value = value .to_value ();
2363 validate_property_type (self.type_ (), false , &pspec , &mut value );
2364 (pspec .name ().as_ptr (), value )
2365 })
2366 .collect ::<smallvec ::SmallVec <[_; 10 ]>>();
2367
2368 let _guard = self.freeze_notify ();
2369 for (name , value ) in params {
2370 unsafe {
2371 gobject_ffi ::g_object_set_property (
2372 self.as_object_ref ().to_glib_none ().0 ,
2373 name as * const _,
2374 value .to_glib_none ().0 ,
2375 );
2376 }
2377 }
2378 }
2379
2380 #[track_caller ]
2381 fn set_properties_from_value (&self, property_values : &[(&str , Value )]) {
2382 let params = property_values
2383 .iter ()
2384 .map (|(name , value )| {
2385 let pspec = self.find_property (name ).unwrap_or_else (|| {
2386 panic !("Can't find property ' {name }' for type ' {}'" , self.type_ ());
2387 });
2388
2389 let mut value = value .clone ();
2390 validate_property_type (self.type_ (), false , &pspec , &mut value );
2391 (pspec .name ().as_ptr (), value )
2392 })
2393 .collect ::<smallvec ::SmallVec <[_; 10 ]>>();
2394
2395 let _guard = self.freeze_notify ();
2396 for (name , value ) in params {
2397 unsafe {
2398 gobject_ffi ::g_object_set_property (
2399 self.as_object_ref ().to_glib_none ().0 ,
2400 name as * const _,
2401 value .to_glib_none ().0 ,
2402 );
2403 }
2404 }
2405 }
2406
2407 #[track_caller ]
2408 fn property <V: for <'b> FromValue <'b> + 'static>(&self, property_name : &str ) -> V {
2409 let prop = self.property_value (property_name );
2410 let v = prop
2411 .get_owned ::<V>()
2412 .unwrap_or_else (|e | panic !("Failed to get cast value to a different type {e }" ));
2413
2414 v
2415 }
2416
2417 #[track_caller ]
2418 fn property_value (&self, property_name : &str ) -> Value {
2419 let pspec = self.find_property (property_name ).unwrap_or_else (|| {
2420 panic !(
2421 "property ' {property_name }' of type ' {}' not found" ,
2422 self.type_ ()
2423 )
2424 });
2425
2426 if !pspec .flags ().contains (crate ::ParamFlags ::READABLE) {
2427 panic !(
2428 "property ' {property_name }' of type ' {}' is not readable" ,
2429 self.type_ ()
2430 );
2431 }
2432
2433 unsafe {
2434 let mut value = Value ::from_type_unchecked (pspec .value_type ());
2435 gobject_ffi ::g_object_get_property (
2436 self.as_object_ref ().to_glib_none ().0 ,
2437 pspec .name ().as_ptr () as * const _,
2438 value .to_glib_none_mut ().0 ,
2439 );
2440
2441 // This can't really happen unless something goes wrong inside GObject
2442 if !value .type_ ().is_valid () {
2443 panic !(
2444 "Failed to get property value for property ' {property_name }' of type ' {}'" ,
2445 self.type_ ()
2446 )
2447 }
2448
2449 value
2450 }
2451 }
2452
2453 fn has_property (&self, property_name : &str , type_ : Option <Type >) -> bool {
2454 self.object_class ().has_property (property_name , type_ )
2455 }
2456
2457 fn property_type (&self, property_name : &str ) -> Option <Type > {
2458 self.object_class ().property_type (property_name )
2459 }
2460
2461 fn find_property (&self, property_name : &str ) -> Option <crate ::ParamSpec > {
2462 self.object_class ().find_property (property_name )
2463 }
2464
2465 fn list_properties (&self) -> PtrSlice <crate ::ParamSpec > {
2466 self.object_class ().list_properties ()
2467 }
2468
2469 #[inline ]
2470 fn freeze_notify (&self) -> PropertyNotificationFreezeGuard {
2471 unsafe { gobject_ffi ::g_object_freeze_notify (self.as_object_ref ().to_glib_none ().0 ) };
2472 PropertyNotificationFreezeGuard (self.as_object_ref ().clone ())
2473 }
2474
2475 unsafe fn set_qdata <QD: 'static>(&self, key : Quark , value : QD) {
2476 unsafe extern "C" fn drop_value <QD>(ptr : ffi ::gpointer ) {
2477 debug_assert !(!ptr .is_null ());
2478 let value : Box <QD> = Box ::from_raw (ptr as * mut QD);
2479 drop (value )
2480 }
2481
2482 let ptr = Box ::into_raw (Box ::new (value )) as ffi ::gpointer ;
2483 gobject_ffi ::g_object_set_qdata_full (
2484 self.as_object_ref ().to_glib_none ().0 ,
2485 key .into_glib (),
2486 ptr ,
2487 Some (drop_value ::<QD>),
2488 );
2489 }
2490
2491 unsafe fn qdata <QD: 'static>(&self, key : Quark ) -> Option <ptr ::NonNull <QD>> {
2492 ptr ::NonNull ::new (gobject_ffi ::g_object_get_qdata (
2493 self.as_object_ref ().to_glib_none ().0 ,
2494 key .into_glib (),
2495 ) as * mut QD)
2496 }
2497
2498 unsafe fn steal_qdata <QD: 'static>(&self, key : Quark ) -> Option <QD> {
2499 let ptr = gobject_ffi ::g_object_steal_qdata (
2500 self.as_object_ref ().to_glib_none ().0 ,
2501 key .into_glib (),
2502 );
2503 if ptr .is_null () {
2504 None
2505 } else {
2506 let value : Box <QD> = Box ::from_raw (ptr as * mut QD);
2507 Some (*value )
2508 }
2509 }
2510
2511 unsafe fn set_data <QD: 'static>(&self, key : &str , value : QD) {
2512 self.set_qdata ::<QD>(Quark ::from_str (key ), value )
2513 }
2514
2515 unsafe fn data <QD: 'static>(&self, key : &str ) -> Option <ptr ::NonNull <QD>> {
2516 self.qdata ::<QD>(Quark ::from_str (key ))
2517 }
2518
2519 unsafe fn steal_data <QD: 'static>(&self, key : &str ) -> Option <QD> {
2520 self.steal_qdata ::<QD>(Quark ::from_str (key ))
2521 }
2522
2523 fn block_signal (&self, handler_id : &SignalHandlerId ) {
2524 unsafe {
2525 gobject_ffi ::g_signal_handler_block (
2526 self.as_object_ref ().to_glib_none ().0 ,
2527 handler_id .as_raw (),
2528 );
2529 }
2530 }
2531
2532 fn unblock_signal (&self, handler_id : &SignalHandlerId ) {
2533 unsafe {
2534 gobject_ffi ::g_signal_handler_unblock (
2535 self.as_object_ref ().to_glib_none ().0 ,
2536 handler_id .as_raw (),
2537 );
2538 }
2539 }
2540
2541 fn stop_signal_emission (&self, signal_id : SignalId , detail : Option <Quark >) {
2542 unsafe {
2543 gobject_ffi ::g_signal_stop_emission (
2544 self.as_object_ref ().to_glib_none ().0 ,
2545 signal_id .into_glib (),
2546 detail .into_glib (),
2547 );
2548 }
2549 }
2550
2551 fn stop_signal_emission_by_name (&self, signal_name : &str ) {
2552 unsafe {
2553 signal_name .run_with_gstr (|signal_name | {
2554 gobject_ffi ::g_signal_stop_emission_by_name (
2555 self.as_object_ref ().to_glib_none ().0 ,
2556 signal_name .as_ptr (),
2557 )
2558 });
2559 }
2560 }
2561
2562 #[track_caller ]
2563 fn connect <F>(&self, signal_name : &str , after : bool , callback : F) -> SignalHandlerId
2564 where
2565 F: Fn (&[Value ]) -> Option <Value > + Send + Sync + 'static,
2566 {
2567 unsafe { self.connect_unsafe (signal_name , after , callback ) }
2568 }
2569
2570 #[track_caller ]
2571 fn connect_id <F>(
2572 &self,
2573 signal_id : SignalId ,
2574 details : Option <Quark >,
2575 after : bool ,
2576 callback : F,
2577 ) -> SignalHandlerId
2578 where
2579 F: Fn (&[Value ]) -> Option <Value > + Send + Sync + 'static,
2580 {
2581 unsafe { self.connect_unsafe_id (signal_id , details , after , callback ) }
2582 }
2583
2584 #[track_caller ]
2585 fn connect_local <F>(&self, signal_name : &str , after : bool , callback : F) -> SignalHandlerId
2586 where
2587 F: Fn (&[Value ]) -> Option <Value > + 'static,
2588 {
2589 let callback = crate ::thread_guard ::ThreadGuard ::new (callback );
2590
2591 unsafe {
2592 self.connect_unsafe (signal_name , after , move |values | {
2593 (callback .get_ref ())(values )
2594 })
2595 }
2596 }
2597
2598 #[track_caller ]
2599 fn connect_local_id <F>(
2600 &self,
2601 signal_id : SignalId ,
2602 details : Option <Quark >,
2603 after : bool ,
2604 callback : F,
2605 ) -> SignalHandlerId
2606 where
2607 F: Fn (&[Value ]) -> Option <Value > + 'static,
2608 {
2609 let callback = crate ::thread_guard ::ThreadGuard ::new (callback );
2610
2611 unsafe {
2612 self.connect_unsafe_id (signal_id , details , after , move |values | {
2613 (callback .get_ref ())(values )
2614 })
2615 }
2616 }
2617
2618 #[track_caller ]
2619 unsafe fn connect_unsafe <F>(
2620 &self,
2621 signal_name : &str ,
2622 after : bool ,
2623 callback : F,
2624 ) -> SignalHandlerId
2625 where
2626 F: Fn (&[Value ]) -> Option <Value >,
2627 {
2628 let type_ = self.type_ ();
2629 let (signal_id , details ) = SignalId ::parse_name (signal_name , type_ , true )
2630 .unwrap_or_else (|| panic !("Signal ' {signal_name }' of type ' {type_ }' not found" ));
2631 self.connect_unsafe_id (signal_id , details , after , callback )
2632 }
2633
2634 #[track_caller ]
2635 unsafe fn connect_unsafe_id <F>(
2636 &self,
2637 signal_id : SignalId ,
2638 details : Option <Quark >,
2639 after : bool ,
2640 callback : F,
2641 ) -> SignalHandlerId
2642 where
2643 F: Fn (&[Value ]) -> Option <Value >,
2644 {
2645 let signal_query = signal_id .query ();
2646 let type_ = self.type_ ();
2647 let return_type : Type = signal_query .return_type ().into ();
2648 let signal_name = signal_id .name ();
2649 let signal_query_type = signal_query .type_ ();
2650
2651 let closure = if return_type == Type ::UNIT {
2652 Closure ::new_unsafe (move |values | {
2653 let ret = callback (values );
2654 if let Some (ret ) = ret {
2655 panic !(
2656 "Signal ' {signal_name }' of type ' {type_ }' required no return value but got value of type ' {}'" ,
2657 ret .type_ ()
2658 );
2659 }
2660 None
2661 })
2662 } else {
2663 Closure ::new_unsafe (move |values | {
2664 let mut ret = callback (values ).unwrap_or_else (|| {
2665 panic !(
2666 "Signal ' {signal_name }' of type ' {type_ }' required return value of type ' {}' but got None" ,
2667 return_type .name ()
2668 );
2669 });
2670 let valid_type : bool = from_glib (gobject_ffi ::g_type_check_value_holds (
2671 mut_override (ret .to_glib_none ().0 ),
2672 return_type .into_glib (),
2673 ));
2674
2675 if valid_type {
2676 return Some (ret );
2677 }
2678
2679 if let Err (got ) = coerce_object_type (&mut ret , return_type ) {
2680 panic !(
2681 "Signal ' {signal_name }' of type ' {type_ }' required return value of type ' {return_type }' but got ' {got }'" ,
2682 );
2683 };
2684 Some (ret )
2685 })
2686 };
2687
2688 assert !(
2689 type_ .is_a (signal_query_type ),
2690 "Signal ' {signal_name }' of type ' {type_ }' but got type ' {signal_query_type }'" ,
2691 );
2692
2693 let handler = gobject_ffi ::g_signal_connect_closure_by_id (
2694 self.as_object_ref ().to_glib_none ().0 ,
2695 signal_id .into_glib (),
2696 details .into_glib (),
2697 closure .as_ref ().to_glib_none ().0 ,
2698 after .into_glib (),
2699 );
2700
2701 if handler == 0 {
2702 panic !("Failed to connect to signal ' {signal_name }' of type ' {type_ }'" ,);
2703 }
2704
2705 from_glib (handler )
2706 }
2707
2708 #[track_caller ]
2709 fn connect_closure (
2710 &self,
2711 signal_name : &str ,
2712 after : bool ,
2713 closure : RustClosure ,
2714 ) -> SignalHandlerId {
2715 let type_ = self.type_ ();
2716 let (signal_id , details ) = SignalId ::parse_name (signal_name , type_ , true )
2717 .unwrap_or_else (|| panic !("Signal ' {signal_name }' of type ' {type_ }' not found" ));
2718 self.connect_closure_id (signal_id , details , after , closure )
2719 }
2720
2721 #[track_caller ]
2722 fn connect_closure_id (
2723 &self,
2724 signal_id : SignalId ,
2725 details : Option <Quark >,
2726 after : bool ,
2727 closure : RustClosure ,
2728 ) -> SignalHandlerId {
2729 let signal_query = signal_id .query ();
2730 let type_ = self.type_ ();
2731 let signal_name = signal_id .name ();
2732
2733 let signal_query_type = signal_query .type_ ();
2734 assert !(
2735 type_ .is_a (signal_query_type ),
2736 "Signal ' {signal_name }' of type ' {type_ }' but got type ' {signal_query_type }'" ,
2737 );
2738
2739 unsafe {
2740 let handler = gobject_ffi ::g_signal_connect_closure_by_id (
2741 self.as_object_ref ().to_glib_none ().0 ,
2742 signal_id .into_glib (),
2743 details .into_glib (),
2744 closure .as_ref ().to_glib_none ().0 ,
2745 after .into_glib (),
2746 );
2747
2748 if handler == 0 {
2749 panic !("Failed to connect to signal ' {signal_name }' of type ' {type_ }'" ,);
2750 }
2751
2752 from_glib (handler )
2753 }
2754 }
2755
2756 #[inline ]
2757 fn watch_closure (&self, closure : &impl AsRef <Closure >) {
2758 let closure = closure .as_ref ();
2759 unsafe {
2760 gobject_ffi ::g_object_watch_closure (
2761 self.as_object_ref ().to_glib_none ().0 ,
2762 closure .to_glib_none ().0 ,
2763 );
2764 }
2765 }
2766
2767 #[track_caller ]
2768 fn emit <R: TryFromClosureReturnValue >(&self, signal_id : SignalId , args : &[&dyn ToValue ]) -> R {
2769 let signal_query = signal_id .query ();
2770 unsafe {
2771 let type_ = self.type_ ();
2772
2773 let self_v = {
2774 let mut v = Value ::uninitialized ();
2775 gobject_ffi ::g_value_init (v .to_glib_none_mut ().0 , self.type_ ().into_glib ());
2776 gobject_ffi ::g_value_set_object (
2777 v .to_glib_none_mut ().0 ,
2778 self.as_object_ref ().to_glib_none ().0 ,
2779 );
2780 v
2781 };
2782
2783 let mut args = Iterator ::chain (
2784 std ::iter ::once (self_v ),
2785 args .iter ().copied ().map (ToValue ::to_value ),
2786 )
2787 .collect ::<smallvec ::SmallVec <[_; 10 ]>>();
2788
2789 validate_signal_arguments (type_ , &signal_query , &mut args [1 ..]);
2790
2791 let mut return_value = if signal_query .return_type () != Type ::UNIT {
2792 Value ::from_type_unchecked (signal_query .return_type ().into ())
2793 } else {
2794 Value ::uninitialized ()
2795 };
2796 let return_value_ptr = if signal_query .return_type () != Type ::UNIT {
2797 return_value .to_glib_none_mut ().0
2798 } else {
2799 ptr ::null_mut ()
2800 };
2801
2802 gobject_ffi ::g_signal_emitv (
2803 mut_override (args .as_ptr ()) as * mut gobject_ffi ::GValue ,
2804 signal_id .into_glib (),
2805 0 ,
2806 return_value_ptr ,
2807 );
2808
2809 R::try_from_closure_return_value (
2810 Some (return_value ).filter (|r | r .type_ ().is_valid () && r .type_ () != Type ::UNIT),
2811 )
2812 .unwrap ()
2813 }
2814 }
2815
2816 #[track_caller ]
2817 fn emit_with_values (&self, signal_id : SignalId , args : &[Value ]) -> Option <Value > {
2818 unsafe {
2819 let type_ = self.type_ ();
2820
2821 let signal_query = signal_id .query ();
2822
2823 let self_v = {
2824 let mut v = Value ::uninitialized ();
2825 gobject_ffi ::g_value_init (v .to_glib_none_mut ().0 , self.type_ ().into_glib ());
2826 gobject_ffi ::g_value_set_object (
2827 v .to_glib_none_mut ().0 ,
2828 self.as_object_ref ().to_glib_none ().0 ,
2829 );
2830 v
2831 };
2832
2833 let mut args = Iterator ::chain (std ::iter ::once (self_v ), args .iter ().cloned ())
2834 .collect ::<smallvec ::SmallVec <[_; 10 ]>>();
2835
2836 validate_signal_arguments (type_ , &signal_query , &mut args [1 ..]);
2837
2838 let mut return_value = if signal_query .return_type () != Type ::UNIT {
2839 Value ::from_type_unchecked (signal_query .return_type ().into ())
2840 } else {
2841 Value ::uninitialized ()
2842 };
2843 let return_value_ptr = if signal_query .return_type () != Type ::UNIT {
2844 return_value .to_glib_none_mut ().0
2845 } else {
2846 ptr ::null_mut ()
2847 };
2848
2849 gobject_ffi ::g_signal_emitv (
2850 mut_override (args .as_ptr ()) as * mut gobject_ffi ::GValue ,
2851 signal_id .into_glib (),
2852 0 ,
2853 return_value_ptr ,
2854 );
2855
2856 Some (return_value ).filter (|r | r .type_ ().is_valid () && r .type_ () != Type ::UNIT)
2857 }
2858 }
2859
2860 #[track_caller ]
2861 fn emit_by_name <R: TryFromClosureReturnValue >(
2862 &self,
2863 signal_name : &str ,
2864 args : &[&dyn ToValue ],
2865 ) -> R {
2866 let type_ = self.type_ ();
2867 let signal_id = SignalId ::lookup (signal_name , type_ ).unwrap_or_else (|| {
2868 panic !("Signal ' {signal_name }' of type ' {type_ }' not found" );
2869 });
2870 self.emit (signal_id , args )
2871 }
2872
2873 #[track_caller ]
2874 fn emit_by_name_with_values (&self, signal_name : &str , args : &[Value ]) -> Option <Value > {
2875 let type_ = self.type_ ();
2876 let signal_id = SignalId ::lookup (signal_name , type_ ).unwrap_or_else (|| {
2877 panic !("Signal ' {signal_name }' of type ' {type_ }' not found" );
2878 });
2879 self.emit_with_values (signal_id , args )
2880 }
2881
2882 #[track_caller ]
2883 fn emit_by_name_with_details <R: TryFromClosureReturnValue >(
2884 &self,
2885 signal_name : &str ,
2886 details : Quark ,
2887 args : &[&dyn ToValue ],
2888 ) -> R {
2889 let type_ = self.type_ ();
2890 let signal_id = SignalId ::lookup (signal_name , type_ )
2891 .unwrap_or_else (|| panic !("Signal ' {signal_name }' of type ' {type_ }' not found" ));
2892 self.emit_with_details (signal_id , details , args )
2893 }
2894
2895 #[track_caller ]
2896 fn emit_by_name_with_details_and_values (
2897 &self,
2898 signal_name : &str ,
2899 details : Quark ,
2900 args : &[Value ],
2901 ) -> Option <Value > {
2902 let type_ = self.type_ ();
2903 let signal_id = SignalId ::lookup (signal_name , type_ )
2904 .unwrap_or_else (|| panic !("Signal ' {signal_name }' of type ' {type_ }' not found" ));
2905 self.emit_with_details_and_values (signal_id , details , args )
2906 }
2907
2908 #[track_caller ]
2909 fn emit_with_details <R: TryFromClosureReturnValue >(
2910 &self,
2911 signal_id : SignalId ,
2912 details : Quark ,
2913 args : &[&dyn ToValue ],
2914 ) -> R {
2915 let signal_query = signal_id .query ();
2916 assert !(signal_query .flags ().contains (crate ::SignalFlags ::DETAILED));
2917
2918 unsafe {
2919 let type_ = self.type_ ();
2920
2921 let self_v = {
2922 let mut v = Value ::uninitialized ();
2923 gobject_ffi ::g_value_init (v .to_glib_none_mut ().0 , self.type_ ().into_glib ());
2924 gobject_ffi ::g_value_set_object (
2925 v .to_glib_none_mut ().0 ,
2926 self.as_object_ref ().to_glib_none ().0 ,
2927 );
2928 v
2929 };
2930
2931 let mut args = Iterator ::chain (
2932 std ::iter ::once (self_v ),
2933 args .iter ().copied ().map (ToValue ::to_value ),
2934 )
2935 .collect ::<smallvec ::SmallVec <[_; 10 ]>>();
2936
2937 validate_signal_arguments (type_ , &signal_query , &mut args [1 ..]);
2938
2939 let mut return_value = if signal_query .return_type () != Type ::UNIT {
2940 Value ::from_type_unchecked (signal_query .return_type ().into ())
2941 } else {
2942 Value ::uninitialized ()
2943 };
2944 let return_value_ptr = if signal_query .return_type () != Type ::UNIT {
2945 return_value .to_glib_none_mut ().0
2946 } else {
2947 ptr ::null_mut ()
2948 };
2949
2950 gobject_ffi ::g_signal_emitv (
2951 mut_override (args .as_ptr ()) as * mut gobject_ffi ::GValue ,
2952 signal_id .into_glib (),
2953 details .into_glib (),
2954 return_value_ptr ,
2955 );
2956
2957 R::try_from_closure_return_value (
2958 Some (return_value ).filter (|r | r .type_ ().is_valid () && r .type_ () != Type ::UNIT),
2959 )
2960 .unwrap ()
2961 }
2962 }
2963
2964 #[track_caller ]
2965 fn emit_with_details_and_values (
2966 &self,
2967 signal_id : SignalId ,
2968 details : Quark ,
2969 args : &[Value ],
2970 ) -> Option <Value > {
2971 let signal_query = signal_id .query ();
2972 assert !(signal_query .flags ().contains (crate ::SignalFlags ::DETAILED));
2973
2974 unsafe {
2975 let type_ = self.type_ ();
2976
2977 let self_v = {
2978 let mut v = Value ::uninitialized ();
2979 gobject_ffi ::g_value_init (v .to_glib_none_mut ().0 , self.type_ ().into_glib ());
2980 gobject_ffi ::g_value_set_object (
2981 v .to_glib_none_mut ().0 ,
2982 self.as_object_ref ().to_glib_none ().0 ,
2983 );
2984 v
2985 };
2986
2987 let mut args = Iterator ::chain (std ::iter ::once (self_v ), args .iter ().cloned ())
2988 .collect ::<smallvec ::SmallVec <[_; 10 ]>>();
2989
2990 validate_signal_arguments (type_ , &signal_query , &mut args [1 ..]);
2991
2992 let mut return_value = if signal_query .return_type () != Type ::UNIT {
2993 Value ::from_type_unchecked (signal_query .return_type ().into ())
2994 } else {
2995 Value ::uninitialized ()
2996 };
2997 let return_value_ptr = if signal_query .return_type () != Type ::UNIT {
2998 return_value .to_glib_none_mut ().0
2999 } else {
3000 ptr ::null_mut ()
3001 };
3002
3003 gobject_ffi ::g_signal_emitv (
3004 mut_override (args .as_ptr ()) as * mut gobject_ffi ::GValue ,
3005 signal_id .into_glib (),
3006 details .into_glib (),
3007 return_value_ptr ,
3008 );
3009
3010 Some (return_value ).filter (|r | r .type_ ().is_valid () && r .type_ () != Type ::UNIT)
3011 }
3012 }
3013
3014 #[inline ]
3015 fn disconnect (&self, handler_id : SignalHandlerId ) {
3016 unsafe {
3017 gobject_ffi ::g_signal_handler_disconnect (
3018 self.as_object_ref ().to_glib_none ().0 ,
3019 handler_id .as_raw (),
3020 );
3021 }
3022 }
3023
3024 fn connect_notify <F: Fn (&Self, &crate ::ParamSpec ) + Send + Sync + 'static>(
3025 &self,
3026 name : Option <&str >,
3027 f : F,
3028 ) -> SignalHandlerId {
3029 unsafe { self.connect_notify_unsafe (name , f ) }
3030 }
3031
3032 fn connect_notify_local <F: Fn (&Self, &crate ::ParamSpec ) + 'static>(
3033 &self,
3034 name : Option <&str >,
3035 f : F,
3036 ) -> SignalHandlerId {
3037 let f = crate ::thread_guard ::ThreadGuard ::new (f );
3038
3039 unsafe {
3040 self.connect_notify_unsafe (name , move |s , pspec | {
3041 (f .get_ref ())(s , pspec );
3042 })
3043 }
3044 }
3045
3046 unsafe fn connect_notify_unsafe <F: Fn (&Self, &crate ::ParamSpec )>(
3047 &self,
3048 name : Option <&str >,
3049 f : F,
3050 ) -> SignalHandlerId {
3051 unsafe extern "C" fn notify_trampoline <P, F: Fn (&P, &crate ::ParamSpec )>(
3052 this : * mut gobject_ffi ::GObject ,
3053 param_spec : * mut gobject_ffi ::GParamSpec ,
3054 f : ffi ::gpointer ,
3055 ) where
3056 P: ObjectType ,
3057 {
3058 let f : &F = &*(f as * const F);
3059 f (
3060 Object ::from_glib_borrow (this ).unsafe_cast_ref (),
3061 &from_glib_borrow (param_spec ),
3062 )
3063 }
3064
3065 let signal_name = if let Some (name ) = name {
3066 format !("notify:: {name }\0 " )
3067 } else {
3068 "notify \0 " .into ()
3069 };
3070
3071 let f : Box <F> = Box ::new (f );
3072 crate ::signal ::connect_raw (
3073 self.as_object_ref ().to_glib_none ().0 ,
3074 signal_name .as_ptr () as * const _,
3075 Some (mem ::transmute ::<* const (), unsafe extern "C" fn ()>(
3076 notify_trampoline ::<Self, F> as * const (),
3077 )),
3078 Box ::into_raw (f ),
3079 )
3080 }
3081
3082 #[inline ]
3083 fn notify (&self, property_name : &str ) {
3084 unsafe {
3085 property_name .run_with_gstr (|property_name | {
3086 gobject_ffi ::g_object_notify (
3087 self.as_object_ref ().to_glib_none ().0 ,
3088 property_name .as_ptr (),
3089 )
3090 });
3091 }
3092 }
3093
3094 #[inline ]
3095 fn notify_by_pspec (&self, pspec : &crate ::ParamSpec ) {
3096 unsafe {
3097 gobject_ffi ::g_object_notify_by_pspec (
3098 self.as_object_ref ().to_glib_none ().0 ,
3099 pspec .to_glib_none ().0 ,
3100 );
3101 }
3102 }
3103
3104 #[inline ]
3105 fn downgrade (&self) -> WeakRef <T> {
3106 unsafe {
3107 let w = WeakRef (Box ::pin (mem ::zeroed ()), PhantomData );
3108 gobject_ffi ::g_weak_ref_init (
3109 mut_override (&*w .0 ),
3110 self.as_object_ref ().to_glib_none ().0 ,
3111 );
3112 w
3113 }
3114 }
3115
3116 fn add_weak_ref_notify <F: FnOnce () + Send + 'static>(&self, f : F) -> WeakRefNotify <T> {
3117 WeakRefNotify ::new (self, f )
3118 }
3119
3120 fn add_weak_ref_notify_local <F: FnOnce () + 'static>(&self, f : F) -> WeakRefNotify <T> {
3121 let callback = crate ::thread_guard ::ThreadGuard ::new (f );
3122
3123 WeakRefNotify ::new (self, move || callback .into_inner ()())
3124 }
3125
3126 fn bind_property <'a, 'f, 't, O: ObjectType >(
3127 &'a self,
3128 source_property : &'a str ,
3129 target : &'a O,
3130 target_property : &'a str ,
3131 ) -> BindingBuilder <'a, 'f, 't> {
3132 BindingBuilder ::new (self, source_property , target , target_property )
3133 }
3134
3135 #[inline ]
3136 fn ref_count (&self) -> u32 {
3137 let stash = self.as_object_ref ().to_glib_none ();
3138 let ptr : * mut gobject_ffi ::GObject = stash .0 ;
3139
3140 unsafe { ffi ::g_atomic_int_get (&(*ptr ).ref_count as * const u32 as * const i32 ) as u32 }
3141 }
3142
3143 #[inline ]
3144 unsafe fn run_dispose (&self) {
3145 gobject_ffi ::g_object_run_dispose (self.as_ptr () as * mut _);
3146 }
3147 }
3148
3149 // Helper struct to avoid creating an extra ref on objects inside closure watches. This is safe
3150 // because `watch_closure` ensures the object has a ref when the closure is called.
3151 #[doc (hidden)]
3152 pub struct WatchedObject <T: ObjectType >(ptr ::NonNull <T::GlibType >);
3153
3154 #[doc (hidden)]
3155 unsafe impl <T: ObjectType + Send + Sync > Send for WatchedObject <T> {}
3156
3157 #[doc (hidden)]
3158 unsafe impl <T: ObjectType + Send + Sync > Sync for WatchedObject <T> {}
3159
3160 #[doc (hidden)]
3161 impl <T: ObjectType > WatchedObject <T> {
3162 pub fn new (obj : &T) -> Self {
3163 Self(unsafe { ptr ::NonNull ::new_unchecked (obj .as_ptr ()) })
3164 }
3165 // rustdoc-stripper-ignore-next
3166 /// # Safety
3167 ///
3168 /// This should only be called from within a closure that was previously attached to `T` using
3169 /// `Watchable::watch_closure`.
3170 #[inline ]
3171 pub unsafe fn borrow (&self) -> Borrowed <T>
3172 where
3173 T: FromGlibPtrBorrow <* mut <T as ObjectType >::GlibType >,
3174 {
3175 from_glib_borrow (self.0 .as_ptr ())
3176 }
3177 }
3178
3179 #[doc (hidden)]
3180 pub trait Watchable <T: ObjectType > {
3181 fn watched_object (&self) -> WatchedObject <T>;
3182 fn watch_closure (&self, closure : &impl AsRef <Closure >);
3183 }
3184
3185 #[doc (hidden)]
3186 impl <T: ObjectType > Watchable <T> for T {
3187 fn watched_object (&self) -> WatchedObject <T> {
3188 WatchedObject ::new (self)
3189 }
3190 fn watch_closure (&self, closure : &impl AsRef <Closure >) {
3191 ObjectExt ::watch_closure (self, closure )
3192 }
3193 }
3194
3195 #[doc (hidden)]
3196 impl <T: ObjectType > Watchable <T> for BorrowedObject <'_, T> {
3197 fn watched_object (&self) -> WatchedObject <T> {
3198 WatchedObject ::new (self)
3199 }
3200 fn watch_closure (&self, closure : &impl AsRef <Closure >) {
3201 ObjectExt ::watch_closure (&**self, closure )
3202 }
3203 }
3204
3205 #[doc (hidden)]
3206 impl <T: ObjectType > Watchable <T> for &T {
3207 fn watched_object (&self) -> WatchedObject <T> {
3208 WatchedObject ::new (*self)
3209 }
3210 fn watch_closure (&self, closure : &impl AsRef <Closure >) {
3211 ObjectExt ::watch_closure (*self, closure )
3212 }
3213 }
3214
3215 // Validate that the given property value has an acceptable type for the given property pspec
3216 // and if necessary update the value
3217 #[track_caller ]
3218 fn validate_property_type (
3219 type_ : Type ,
3220 allow_construct_only : bool ,
3221 pspec : &crate ::ParamSpec ,
3222 property_value : &mut Value ,
3223 ) {
3224 if !pspec .flags ().contains (crate ::ParamFlags ::WRITABLE)
3225 || (!allow_construct_only && pspec .flags ().contains (crate ::ParamFlags ::CONSTRUCT_ONLY))
3226 {
3227 panic !(
3228 "property ' {}' of type ' {type_ }' is not writable" ,
3229 pspec .name (),
3230 );
3231 }
3232
3233 unsafe {
3234 // While GLib actually allows all types that can somehow be transformed
3235 // into the property type, we're more restrictive here to be consistent
3236 // with Rust's type rules. We only allow the exact same type, or if the
3237 // value type is a subtype of the property type
3238 let valid_type : bool = from_glib (gobject_ffi ::g_type_check_value_holds (
3239 mut_override (property_value .to_glib_none ().0 ),
3240 pspec .value_type ().into_glib (),
3241 ));
3242
3243 if !valid_type {
3244 if let Err (got ) = coerce_object_type (property_value , pspec .value_type ()) {
3245 panic !(
3246 "property ' {}' of type ' {type_ }' can't be set from the given type (expected: ' {}', got: ' {got }')" ,
3247 pspec .name (),
3248 pspec .value_type (),
3249 );
3250 }
3251 }
3252
3253 let changed : bool = from_glib (gobject_ffi ::g_param_value_validate (
3254 pspec .to_glib_none ().0 ,
3255 property_value .to_glib_none_mut ().0 ,
3256 ));
3257 let change_allowed = pspec .flags ().contains (crate ::ParamFlags ::LAX_VALIDATION);
3258 if changed && !change_allowed {
3259 panic !(
3260 "property ' {}' of type ' {type_ }' can't be set from given value, it is invalid or out of range" ,
3261 pspec .name (),
3262 );
3263 }
3264 }
3265 }
3266
3267 // If it's not directly a valid type but an object type, we check if the
3268 // actual type of the contained object is compatible and if so create
3269 // a properly typed Value (by mutating the existing Value).
3270 // This can happen if the type field in the Value is set to a more
3271 // generic type than the contained value.
3272 fn coerce_object_type (property_value : &mut Value , type_ : Type ) -> Result <(), Type > {
3273 // return early if type coercion is not possible
3274 match property_value .get ::<Option <Object >>() {
3275 Ok (Some (obj : Object )) if !(obj .type_ ().is_a (type_ )) => Err (obj .type_ ()),
3276 Ok (_) => {
3277 property_value .inner .g_type = type_ .into_glib ();
3278 Ok (())
3279 }
3280 Err (_) => Err (property_value .type_ ()),
3281 }
3282 }
3283
3284 #[track_caller ]
3285 fn validate_signal_arguments (type_ : Type , signal_query : &SignalQuery , args : &mut [Value ]) {
3286 let signal_name : &str = signal_query .signal_name ();
3287
3288 if signal_query .n_params () != args .len () as u32 {
3289 panic !(
3290 "Incompatible number of arguments for signal ' {signal_name }' of type ' {type_ }' (expected {}, got {})" ,
3291 signal_query .n_params (),
3292 args .len (),
3293 );
3294 }
3295
3296 let param_types : impl Iterator = Iterator ::zip (self: args .iter_mut (), other: signal_query .param_types ());
3297
3298 for (i : usize , (arg : &mut Value , param_type : &SignalType )) in param_types .enumerate () {
3299 let param_type : Type = (*param_type ).into ();
3300 if param_type != arg .type_ () {
3301 coerce_object_type (arg , param_type ).unwrap_or_else (|got : Type |
3302 panic !(
3303 "Incompatible argument type in argument {i } for signal ' {signal_name }' of type ' {type_ }' (expected {param_type }, got {got })" ,
3304 )
3305 );
3306 }
3307 }
3308 }
3309
3310 /// Trait for class methods on `Object` and subclasses of it.
3311 pub unsafe trait ObjectClassExt {
3312 // rustdoc-stripper-ignore-next
3313 /// Check if the object class has a property `property_name` of the given `type_`.
3314 ///
3315 /// If no type is provided then only the existence of the property is checked.
3316 fn has_property (&self, property_name : &str , type_ : Option <Type >) -> bool {
3317 let ptype = self.property_type (property_name );
3318
3319 match (ptype , type_ ) {
3320 (None , _) => false ,
3321 (Some (_), None ) => true ,
3322 (Some (ptype ), Some (type_ )) => ptype == type_ ,
3323 }
3324 }
3325
3326 // rustdoc-stripper-ignore-next
3327 /// Get the type of the property `property_name` of this object class.
3328 ///
3329 /// This returns `None` if the property does not exist.
3330 #[doc (alias = "get_property_type" )]
3331 fn property_type (&self, property_name : &str ) -> Option <Type > {
3332 self.find_property (property_name )
3333 .map (|pspec | pspec .value_type ())
3334 }
3335
3336 // rustdoc-stripper-ignore-next
3337 /// Get the [`ParamSpec`](crate::ParamSpec) of the property `property_name` of this object class.
3338 #[doc (alias = "g_object_class_find_property" )]
3339 fn find_property (&self, property_name : &str ) -> Option <crate ::ParamSpec > {
3340 unsafe {
3341 let klass = self as * const _ as * const gobject_ffi ::GObjectClass ;
3342
3343 property_name .run_with_gstr (|property_name | {
3344 from_glib_none (gobject_ffi ::g_object_class_find_property (
3345 klass as * mut _,
3346 property_name .as_ptr (),
3347 ))
3348 })
3349 }
3350 }
3351
3352 // rustdoc-stripper-ignore-next
3353 /// Return all [`ParamSpec`](crate::ParamSpec) of the properties of this object class.
3354 #[doc (alias = "g_object_class_list_properties" )]
3355 fn list_properties (&self) -> PtrSlice <crate ::ParamSpec > {
3356 unsafe {
3357 let klass = self as * const _ as * const gobject_ffi ::GObjectClass ;
3358
3359 let mut n_properties = 0 ;
3360
3361 let props =
3362 gobject_ffi ::g_object_class_list_properties (klass as * mut _, &mut n_properties );
3363 PtrSlice ::from_glib_container_num (props , n_properties as usize , true )
3364 }
3365 }
3366 }
3367
3368 unsafe impl <T: ObjectType + IsClass > ObjectClassExt for Class <T> {}
3369
3370 wrapper ! {
3371 #[doc (alias = "GInitiallyUnowned" )]
3372 pub struct InitiallyUnowned (Object<gobject_ffi ::GInitiallyUnowned , gobject_ffi ::GInitiallyUnownedClass >);
3373
3374 match fn {
3375 type_ => || gobject_ffi ::g_initially_unowned_get_type (),
3376 }
3377 }
3378
3379 // ManuallyDrop -> The lifetime of the data isn't bound to a Rust value but a GObject. Drop could free data too early.
3380 // Pin -> Make sure the pointer Box(1) passed to FFI is always valid and never reallocates.
3381 // Box(1) -> Pointer to Box(2), 64 bits large and compatible with FFI.
3382 // Box(2) -> Pointer to dyn FnOnce(), 128 bits large and incompatible with FFI (so Box(1) is passed instead).
3383 type WeakRefNotifyData = ManuallyDrop <Pin <Box <Box <dyn FnOnce () + 'static>>>>;
3384
3385 // rustdoc-stripper-ignore-next
3386 /// A handle to disconnect a weak ref notify closure.
3387 pub struct WeakRefNotify <T: ObjectType > {
3388 object : WeakRef <T>,
3389 data : WeakRefNotifyData ,
3390 }
3391
3392 unsafe extern "C" fn notify_func (data : ffi ::gpointer , _obj : * mut gobject_ffi ::GObject ) {
3393 // SAFETY: Call to FFI with pointers that must be valid due to Pin and lifetimes.
3394 // ManuallyDrop and Pin are elided because the pointer only points to Box<Box<dyn FnOnce()>>.
3395 let callback : Box <Box <dyn FnOnce ()>> = Box ::from_raw (data as * mut _);
3396
3397 // SAFETY: Function must have type FnOnce() due type checks in WeakRefNotify::new.
3398 // This callback can only be called once when the object is disposed, to the data can be dropped.
3399 (*callback )()
3400 }
3401
3402 impl <T: ObjectType > WeakRefNotify <T> {
3403 fn new <F: FnOnce () + 'static>(obj : &T, f : F) -> WeakRefNotify <T> {
3404 let data : WeakRefNotifyData = ManuallyDrop ::new (Box ::pin (Box ::new (f )));
3405 let data_ptr : * const Box <dyn FnOnce ()> = Pin ::as_ref (&data ).get_ref ();
3406
3407 unsafe {
3408 // SAFETY: Call to FFI with pointers that must be valid due to Pin and lifetimes.
3409 gobject_ffi ::g_object_weak_ref (
3410 obj .as_ptr () as * mut gobject_ffi ::GObject ,
3411 Some (notify_func ),
3412 data_ptr as * mut _,
3413 );
3414 }
3415
3416 let object = obj .downgrade ();
3417
3418 WeakRefNotify { object , data }
3419 }
3420
3421 // rustdoc-stripper-ignore-next
3422 /// Try to upgrade this weak reference to a strong reference.
3423 ///
3424 /// If the stored object was already destroyed then `None` is returned.
3425 pub fn upgrade (&self) -> Option <T> {
3426 self.object .upgrade ()
3427 }
3428
3429 #[doc (alias = "g_object_weak_unref" )]
3430 pub fn disconnect (mut self) {
3431 // Upgrade the object to make sure it's alive and the callback can't be called while it's disconnected.
3432 if let Some (obj ) = self.object .upgrade () {
3433 let data_ptr : * const Box <dyn FnOnce ()> = Pin ::as_ref (&self.data ).get_ref ();
3434
3435 unsafe {
3436 // SAFETY: Call to FFI with pointers that must be valid due to Pin and lifetimes.
3437 gobject_ffi ::g_object_weak_unref (
3438 obj .as_ptr () as * mut gobject_ffi ::GObject ,
3439 Some (notify_func ),
3440 data_ptr as * mut _,
3441 );
3442
3443 // SAFETY: The data can be dropped because references to GObject have been dropped too.
3444 // The callback can't be called before or after because it's disconnected and the object is still alive.
3445 // This function can't be called anymore either because it consumes self.
3446 ManuallyDrop ::drop (&mut self.data );
3447 }
3448 }
3449 }
3450 }
3451
3452 // rustdoc-stripper-ignore-next
3453 /// A weak reference to an object.
3454 #[derive (Debug)]
3455 #[doc (alias = "GWeakRef" )]
3456 pub struct WeakRef <T: ObjectType >(Pin <Box <gobject_ffi ::GWeakRef >>, PhantomData <* mut T>);
3457
3458 impl <T: ObjectType > WeakRef <T> {
3459 // rustdoc-stripper-ignore-next
3460 /// Create a new empty weak reference.
3461 ///
3462 /// `upgrade` will always return `None` until an object is set on it.
3463 #[inline ]
3464 pub fn new () -> WeakRef <T> {
3465 unsafe {
3466 let mut w = WeakRef (Box ::pin (mem ::zeroed ()), PhantomData );
3467 gobject_ffi ::g_weak_ref_init (
3468 Pin ::as_mut (&mut w .0 ).get_unchecked_mut (),
3469 ptr ::null_mut (),
3470 );
3471 w
3472 }
3473 }
3474
3475 // rustdoc-stripper-ignore-next
3476 /// Set this weak reference to the given object.
3477 #[doc (alias = "g_weak_ref_set" )]
3478 #[inline ]
3479 pub fn set (&self, obj : Option <&T>) {
3480 unsafe {
3481 gobject_ffi ::g_weak_ref_set (
3482 mut_override (Pin ::as_ref (&self.0 ).get_ref ()),
3483 obj .map_or (std ::ptr ::null_mut (), |obj | {
3484 obj .as_object_ref ().to_glib_none ().0
3485 }),
3486 );
3487 }
3488 }
3489
3490 // rustdoc-stripper-ignore-next
3491 /// Try to upgrade this weak reference to a strong reference.
3492 ///
3493 /// If the stored object was already destroyed or no object was set in this weak reference then
3494 /// `None` is returned.
3495 #[inline ]
3496 pub fn upgrade (&self) -> Option <T> {
3497 unsafe {
3498 let ptr = gobject_ffi ::g_weak_ref_get (mut_override (Pin ::as_ref (&self.0 ).get_ref ()));
3499 if ptr .is_null () {
3500 None
3501 } else {
3502 let obj : Object = from_glib_full (ptr );
3503 Some (T::unsafe_from (obj .into ()))
3504 }
3505 }
3506 }
3507 }
3508
3509 impl <T: ObjectType > Drop for WeakRef <T> {
3510 #[inline ]
3511 fn drop (&mut self) {
3512 unsafe {
3513 gobject_ffi ::g_weak_ref_clear (weak_ref: Pin ::as_mut (&mut self.0 ).get_unchecked_mut ());
3514 }
3515 }
3516 }
3517
3518 impl <T: ObjectType > Clone for WeakRef <T> {
3519 #[inline ]
3520 fn clone (&self) -> Self {
3521 unsafe {
3522 let o : Option = self.upgrade ();
3523
3524 let mut c : WeakRef = WeakRef (Box ::pin (mem ::zeroed ()), PhantomData );
3525 gobject_ffi ::g_weak_ref_init (
3526 weak_ref: Pin ::as_mut (&mut c .0 ).get_unchecked_mut (),
3527 object: o .to_glib_none ().0 as * mut gobject_ffi ::GObject ,
3528 );
3529
3530 c
3531 }
3532 }
3533 }
3534
3535 impl <T: ObjectType > Default for WeakRef <T> {
3536 #[inline ]
3537 fn default () -> Self {
3538 Self::new ()
3539 }
3540 }
3541
3542 unsafe impl <T: ObjectType + Sync + Sync > Sync for WeakRef <T> {}
3543 unsafe impl <T: ObjectType + Send + Sync > Send for WeakRef <T> {}
3544
3545 impl <T: ObjectType > PartialEq for WeakRef <T> {
3546 #[inline ]
3547 fn eq (&self, other : &Self) -> bool {
3548 unsafe { self.0 .priv_ .p == other .0 .priv_ .p }
3549 }
3550 }
3551
3552 impl <T: ObjectType > PartialEq <T> for WeakRef <T> {
3553 #[inline ]
3554 fn eq (&self, other : &T) -> bool {
3555 unsafe { self.0 .priv_ .p == other .as_ptr () as * mut std ::os ::raw ::c_void }
3556 }
3557 }
3558
3559 impl <T: ObjectType > PartialOrd for WeakRef <T> {
3560 #[inline ]
3561 fn partial_cmp (&self, other : &Self) -> Option <cmp ::Ordering > {
3562 unsafe { self.0 .priv_ .p .partial_cmp (&other .0 .priv_ .p ) }
3563 }
3564 }
3565
3566 // rustdoc-stripper-ignore-next
3567 /// A weak reference to the object it was created for that can be sent to
3568 /// different threads even for object types that don't implement `Send`.
3569 ///
3570 /// Trying to upgrade the weak reference from another thread than the one
3571 /// where it was created on will panic but dropping or cloning can be done
3572 /// safely from any thread.
3573 #[derive (Debug)]
3574 pub struct SendWeakRef <T: ObjectType >(WeakRef <T>, Option <usize >);
3575
3576 impl <T: ObjectType > SendWeakRef <T> {
3577 #[inline ]
3578 #[deprecated = "Use from() instead. See https://github.com/gtk-rs/gtk-rs-core/issues/1617" ]
3579 pub fn new () -> SendWeakRef <T> {
3580 SendWeakRef (WeakRef ::new (), None )
3581 }
3582
3583 #[inline ]
3584 pub fn into_weak_ref (self) -> WeakRef <T> {
3585 assert !(
3586 self.1 .is_none () || self.1 == Some (thread_id ()),
3587 "SendWeakRef dereferenced on a different thread" ,
3588 );
3589
3590 self.0
3591 }
3592 }
3593
3594 impl <T: ObjectType > ops ::Deref for SendWeakRef <T> {
3595 type Target = WeakRef <T>;
3596
3597 #[inline ]
3598 fn deref (&self) -> &WeakRef <T> {
3599 assert !(
3600 self.1 .is_none () || self.1 == Some (thread_id ()),
3601 "SendWeakRef dereferenced on a different thread"
3602 );
3603
3604 &self.0
3605 }
3606 }
3607
3608 // Deriving this gives the wrong trait bounds
3609 impl <T: ObjectType > Clone for SendWeakRef <T> {
3610 #[inline ]
3611 fn clone (&self) -> Self {
3612 Self(self.0 .clone (), self.1 )
3613 }
3614 }
3615
3616 impl <T: ObjectType > Default for SendWeakRef <T> {
3617 #[inline ]
3618 fn default () -> Self {
3619 #[allow (deprecated)]
3620 Self::new ()
3621 }
3622 }
3623
3624 impl <T: ObjectType > From <WeakRef <T>> for SendWeakRef <T> {
3625 #[inline ]
3626 fn from (v : WeakRef <T>) -> SendWeakRef <T> {
3627 SendWeakRef (v , Some (thread_id ()))
3628 }
3629 }
3630
3631 unsafe impl <T: ObjectType > Sync for SendWeakRef <T> {}
3632 unsafe impl <T: ObjectType > Send for SendWeakRef <T> {}
3633
3634 type TransformFn <'b> =
3635 Option <Box <dyn Fn (&'b crate ::Binding , &'b Value ) -> Option <Value > + Send + Sync + 'static>>;
3636
3637 // rustdoc-stripper-ignore-next
3638 /// Builder for object property bindings.
3639 #[must_use = "The builder must be built to be used" ]
3640 pub struct BindingBuilder <'a, 'f, 't> {
3641 source : &'a ObjectRef ,
3642 source_property : &'a str ,
3643 target : &'a ObjectRef ,
3644 target_property : &'a str ,
3645 flags : crate ::BindingFlags ,
3646 transform_from : TransformFn <'f>,
3647 transform_to : TransformFn <'t>,
3648 }
3649
3650 impl fmt ::Debug for BindingBuilder <'_, '_, '_> {
3651 fn fmt (&self, f : &mut fmt ::Formatter <'_>) -> fmt ::Result {
3652 f &mut DebugStruct<'_, '_> .debug_struct ("BindingBuilder" )
3653 .field ("source" , &self.source )
3654 .field ("source_property" , &self.source_property )
3655 .field ("target" , &self.target )
3656 .field ("target_property" , &self.target_property )
3657 .field (name: "flags" , &self.flags )
3658 .finish ()
3659 }
3660 }
3661
3662 impl <'a, 'f, 't> BindingBuilder <'a, 'f, 't> {
3663 fn new (
3664 source : &'a impl ObjectType ,
3665 source_property : &'a str ,
3666 target : &'a impl ObjectType ,
3667 target_property : &'a str ,
3668 ) -> Self {
3669 Self {
3670 source : source .as_object_ref (),
3671 source_property ,
3672 target : target .as_object_ref (),
3673 target_property ,
3674 flags : crate ::BindingFlags ::DEFAULT,
3675 transform_to : None ,
3676 transform_from : None ,
3677 }
3678 }
3679
3680 // rustdoc-stripper-ignore-next
3681 /// Transform changed property values from the target object to the source object with the given closure.
3682 ///
3683 /// This function operates on `glib::Value`s.
3684 /// See [`Self::transform_from`] for a version which operates on concrete argument and return types.
3685 pub fn transform_from_with_values <
3686 F: Fn (&crate ::Binding , &Value ) -> Option <Value > + Send + Sync + 'static,
3687 >(
3688 self,
3689 func : F,
3690 ) -> Self {
3691 Self {
3692 transform_from : Some (Box ::new (func )),
3693 ..self
3694 }
3695 }
3696
3697 // rustdoc-stripper-ignore-next
3698 /// Transform changed property values from the target object to the source object with the given closure.
3699 ///
3700 /// This function operates on concrete argument and return types.
3701 /// See [`Self::transform_from_with_values`] for a version which operates on `glib::Value`s.
3702 pub fn transform_from <
3703 S: FromValue <'f>,
3704 T: Into <Value >,
3705 F: Fn (&'f crate ::Binding , S) -> Option <T> + Send + Sync + 'static,
3706 >(
3707 self,
3708 func : F,
3709 ) -> Self {
3710 Self {
3711 transform_from : Some (Box ::new (move |binding , from_value | {
3712 let from_value = from_value .get ().expect ("Wrong value type" );
3713 func (binding , from_value ).map (|r | r .into ())
3714 })),
3715 ..self
3716 }
3717 }
3718
3719 // rustdoc-stripper-ignore-next
3720 /// Transform changed property values from the source object to the target object with the given closure.
3721 ///
3722 /// This function operates on `glib::Value`s.
3723 /// See [`Self::transform_to`] for a version which operates on concrete argument and return types.
3724 pub fn transform_to_with_values <
3725 F: Fn (&crate ::Binding , &Value ) -> Option <Value > + Send + Sync + 'static,
3726 >(
3727 self,
3728 func : F,
3729 ) -> Self {
3730 Self {
3731 transform_to : Some (Box ::new (func )),
3732 ..self
3733 }
3734 }
3735
3736 // rustdoc-stripper-ignore-next
3737 /// Transform changed property values from the source object to the target object with the given closure.
3738 ///
3739 /// This function operates on concrete argument and return types.
3740 /// See [`Self::transform_to_with_values`] for a version which operates on `glib::Value`s.
3741 pub fn transform_to <
3742 S: FromValue <'t>,
3743 T: Into <Value >,
3744 F: Fn (&'t crate ::Binding , S) -> Option <T> + Send + Sync + 'static,
3745 >(
3746 self,
3747 func : F,
3748 ) -> Self {
3749 Self {
3750 transform_to : Some (Box ::new (move |binding , from_value | {
3751 let from_value = from_value .get ().expect ("Wrong value type" );
3752 func (binding , from_value ).map (|r | r .into ())
3753 })),
3754 ..self
3755 }
3756 }
3757
3758 // rustdoc-stripper-ignore-next
3759 /// Bind the properties with the given flags.
3760 pub fn flags (self, flags : crate ::BindingFlags ) -> Self {
3761 Self { flags , ..self }
3762 }
3763
3764 // rustdoc-stripper-ignore-next
3765 /// Set the binding flags to [`BIDIRECTIONAL`][crate::BindingFlags::BIDIRECTIONAL].
3766 pub fn bidirectional (mut self) -> Self {
3767 self.flags |= crate ::BindingFlags ::BIDIRECTIONAL;
3768 self
3769 }
3770
3771 // rustdoc-stripper-ignore-next
3772 /// Set the binding flags to [`SYNC_CREATE`][crate::BindingFlags::SYNC_CREATE].
3773 pub fn sync_create (mut self) -> Self {
3774 self.flags |= crate ::BindingFlags ::SYNC_CREATE;
3775 self
3776 }
3777
3778 // rustdoc-stripper-ignore-next
3779 /// Set the binding flags to [`INVERT_BOOLEAN`][crate::BindingFlags::INVERT_BOOLEAN].
3780 pub fn invert_boolean (mut self) -> Self {
3781 self.flags |= crate ::BindingFlags ::INVERT_BOOLEAN;
3782 self
3783 }
3784
3785 // rustdoc-stripper-ignore-next
3786 /// Establish the property binding.
3787 ///
3788 /// # Panics
3789 /// This panics if the provided properties do not exist.
3790 #[track_caller ]
3791 pub fn build (self) -> crate ::Binding {
3792 unsafe extern "C" fn transform_to_trampoline (
3793 binding : * mut gobject_ffi ::GBinding ,
3794 from_value : * const gobject_ffi ::GValue ,
3795 to_value : * mut gobject_ffi ::GValue ,
3796 user_data : ffi ::gpointer ,
3797 ) -> ffi ::gboolean {
3798 let transform_data = &*(user_data
3799 as * const (TransformFn , TransformFn , crate ::ParamSpec , crate ::ParamSpec ));
3800
3801 match (transform_data .0 .as_ref ().unwrap ())(
3802 &from_glib_borrow (binding ),
3803 &*(from_value as * const Value ),
3804 ) {
3805 None => false ,
3806 Some (res ) => {
3807 assert !(
3808 res .type_ ().is_a (transform_data .3 .value_type ()),
3809 "Target property {} expected type {} but transform_to function returned {}" ,
3810 transform_data .3 .name (),
3811 transform_data .3 .value_type (),
3812 res .type_ ()
3813 );
3814 *to_value = res .into_raw ();
3815 true
3816 }
3817 }
3818 .into_glib ()
3819 }
3820
3821 unsafe extern "C" fn transform_from_trampoline (
3822 binding : * mut gobject_ffi ::GBinding ,
3823 from_value : * const gobject_ffi ::GValue ,
3824 to_value : * mut gobject_ffi ::GValue ,
3825 user_data : ffi ::gpointer ,
3826 ) -> ffi ::gboolean {
3827 let transform_data = &*(user_data
3828 as * const (TransformFn , TransformFn , crate ::ParamSpec , crate ::ParamSpec ));
3829
3830 match (transform_data .1 .as_ref ().unwrap ())(
3831 &from_glib_borrow (binding ),
3832 &*(from_value as * const Value ),
3833 ) {
3834 None => false ,
3835 Some (res ) => {
3836 assert !(
3837 res .type_ ().is_a (transform_data .2 .value_type ()),
3838 "Source property {} expected type {} but transform_from function returned {}" ,
3839 transform_data .2 .name (),
3840 transform_data .2 .value_type (),
3841 res .type_ ()
3842 );
3843 *to_value = res .into_raw ();
3844 true
3845 }
3846 }
3847 .into_glib ()
3848 }
3849
3850 unsafe extern "C" fn free_transform_data (data : ffi ::gpointer ) {
3851 let _ = Box ::from_raw (
3852 data as * mut (TransformFn , TransformFn , crate ::ParamSpec , crate ::ParamSpec ),
3853 );
3854 }
3855
3856 unsafe {
3857 let source = Object {
3858 inner : TypedObjectRef ::new (self.source .clone ()),
3859 phantom : std ::marker ::PhantomData ,
3860 };
3861 let target = Object {
3862 inner : TypedObjectRef ::new (self.target .clone ()),
3863 phantom : std ::marker ::PhantomData ,
3864 };
3865
3866 let source_property = source
3867 .find_property (self.source_property )
3868 .unwrap_or_else (|| {
3869 panic !(
3870 "Source property {} on type {} not found" ,
3871 self.source_property ,
3872 source .type_ ()
3873 );
3874 });
3875 let target_property = target
3876 .find_property (self.target_property )
3877 .unwrap_or_else (|| {
3878 panic !(
3879 "Target property {} on type {} not found" ,
3880 self.target_property ,
3881 target .type_ ()
3882 );
3883 });
3884
3885 let source_property_name = source_property .name ().as_ptr ();
3886 let target_property_name = target_property .name ().as_ptr ();
3887
3888 let have_transform_to = self.transform_to .is_some ();
3889 let have_transform_from = self.transform_from .is_some ();
3890 let transform_data = if have_transform_to || have_transform_from {
3891 Box ::into_raw (Box ::new ((
3892 self.transform_to ,
3893 self.transform_from ,
3894 source_property ,
3895 target_property ,
3896 )))
3897 } else {
3898 ptr ::null_mut ()
3899 };
3900
3901 from_glib_none (gobject_ffi ::g_object_bind_property_full (
3902 source .to_glib_none ().0 ,
3903 source_property_name as * const _,
3904 target .to_glib_none ().0 ,
3905 target_property_name as * const _,
3906 self.flags .into_glib (),
3907 if have_transform_to {
3908 Some (transform_to_trampoline )
3909 } else {
3910 None
3911 },
3912 if have_transform_from {
3913 Some (transform_from_trampoline )
3914 } else {
3915 None
3916 },
3917 transform_data as ffi ::gpointer ,
3918 if transform_data .is_null () {
3919 None
3920 } else {
3921 Some (free_transform_data )
3922 },
3923 ))
3924 }
3925 }
3926 }
3927
3928 // rustdoc-stripper-ignore-next
3929 /// Class struct of type `T`.
3930 #[repr (transparent)]
3931 pub struct Class <T: IsClass >(T::GlibClassType );
3932
3933 impl <T: IsClass > Class <T> {
3934 // rustdoc-stripper-ignore-next
3935 /// Get the type id for this class.
3936 ///
3937 /// This is not equivalent to `T::static_type()` but is the type of the subclass of `T` where
3938 /// this class belongs to.
3939 #[doc (alias = "get_type" )]
3940 #[inline ]
3941 pub fn type_ (&self) -> Type {
3942 unsafe {
3943 // This also works for interfaces because they also have the type
3944 // as the first struct field.
3945 let klass = self as * const _ as * const gobject_ffi ::GTypeClass ;
3946 from_glib ((*klass ).g_type )
3947 }
3948 }
3949
3950 // rustdoc-stripper-ignore-next
3951 /// Casts this class to a reference to a parent type's class.
3952 #[inline ]
3953 pub fn upcast_ref <U: IsClass >(&self) -> &Class <U>
3954 where
3955 T: IsA <U>,
3956 {
3957 unsafe {
3958 let klass = self as * const _ as * const Class <U>;
3959 &*klass
3960 }
3961 }
3962
3963 // rustdoc-stripper-ignore-next
3964 /// Casts this class to a mutable reference to a parent type's class.
3965 #[inline ]
3966 pub fn upcast_ref_mut <U: IsClass >(&mut self) -> &mut Class <U>
3967 where
3968 T: IsA <U>,
3969 {
3970 unsafe {
3971 let klass = self as * mut _ as * mut Class <U>;
3972 &mut *klass
3973 }
3974 }
3975
3976 // rustdoc-stripper-ignore-next
3977 /// Casts this class to a reference to a child type's class or
3978 /// fails if this class is not implementing the child class.
3979 #[inline ]
3980 pub fn downcast_ref <U: IsClass + IsA <T>>(&self) -> Option <&Class <U>> {
3981 if !self.type_ ().is_a (U::static_type ()) {
3982 return None ;
3983 }
3984
3985 unsafe {
3986 let klass = self as * const _ as * const Class <U>;
3987 Some (&*klass )
3988 }
3989 }
3990
3991 // rustdoc-stripper-ignore-next
3992 /// Casts this class to a mutable reference to a child type's class or
3993 /// fails if this class is not implementing the child class.
3994 #[inline ]
3995 pub fn downcast_ref_mut <U: IsClass + IsA <T>>(&mut self) -> Option <&mut Class <U>> {
3996 if !self.type_ ().is_a (U::static_type ()) {
3997 return None ;
3998 }
3999
4000 unsafe {
4001 let klass = self as * mut _ as * mut Class <U>;
4002 Some (&mut *klass )
4003 }
4004 }
4005
4006 // rustdoc-stripper-ignore-next
4007 /// Gets the class struct for `Self` of `type_`.
4008 ///
4009 /// This will return `None` if `type_` is not a subclass of `Self`.
4010 #[doc (alias = "g_type_class_ref" )]
4011 #[inline ]
4012 pub fn from_type (type_ : Type ) -> Option <ClassRef <'static, T>> {
4013 if !type_ .is_a (T::static_type ()) {
4014 return None ;
4015 }
4016
4017 unsafe {
4018 let ptr = gobject_ffi ::g_type_class_ref (type_ .into_glib ());
4019 if ptr .is_null () {
4020 None
4021 } else {
4022 Some (ClassRef (
4023 ptr ::NonNull ::new_unchecked (ptr as * mut Self),
4024 true ,
4025 PhantomData ,
4026 ))
4027 }
4028 }
4029 }
4030
4031 // rustdoc-stripper-ignore-next
4032 /// Gets the parent class struct, if any.
4033 #[doc (alias = "g_type_class_peek_parent" )]
4034 #[inline ]
4035 pub fn parent (&self) -> Option <ClassRef <T>> {
4036 unsafe {
4037 let ptr = gobject_ffi ::g_type_class_peek_parent (&self.0 as * const _ as * mut _);
4038 if ptr .is_null () {
4039 None
4040 } else {
4041 Some (ClassRef (
4042 ptr ::NonNull ::new_unchecked (ptr as * mut Self),
4043 false ,
4044 PhantomData ,
4045 ))
4046 }
4047 }
4048 }
4049 }
4050
4051 unsafe impl <T: IsClass > Send for Class <T> {}
4052 unsafe impl <T: IsClass > Sync for Class <T> {}
4053
4054 impl <T: IsClass > AsRef <T::GlibClassType > for Class <T> {
4055 #[inline ]
4056 fn as_ref (&self) -> &T::GlibClassType {
4057 &self.0
4058 }
4059 }
4060
4061 impl <T: IsClass > AsMut <T::GlibClassType > for Class <T> {
4062 #[inline ]
4063 fn as_mut (&mut self) -> &mut T::GlibClassType {
4064 &mut self.0
4065 }
4066 }
4067
4068 // rustdoc-stripper-ignore-next
4069 /// Reference to the class struct of type `T`.
4070 #[derive (Debug)]
4071 pub struct ClassRef <'a, T: IsClass >(ptr ::NonNull <Class <T>>, bool , PhantomData <&'a ()>);
4072
4073 impl <T: IsClass > ops ::Deref for ClassRef <'_, T> {
4074 type Target = Class <T>;
4075
4076 #[inline ]
4077 fn deref (&self) -> &Class <T> {
4078 unsafe { self.0 .as_ref () }
4079 }
4080 }
4081
4082 impl <T: IsClass > Drop for ClassRef <'_, T> {
4083 #[inline ]
4084 fn drop (&mut self) {
4085 if self.1 {
4086 unsafe {
4087 gobject_ffi ::g_type_class_unref (self.0 .as_ptr () as * mut _);
4088 }
4089 }
4090 }
4091 }
4092
4093 unsafe impl <T: IsClass > Send for ClassRef <'_, T> {}
4094 unsafe impl <T: IsClass > Sync for ClassRef <'_, T> {}
4095
4096 // This should require Self: IsA<Self::Super>, but that seems to cause a cycle error
4097 pub unsafe trait ParentClassIs : IsClass {
4098 type Parent : IsClass ;
4099 }
4100
4101 // rustdoc-stripper-ignore-next
4102 /// Automatically implemented by `ObjectSubclass` variants of
4103 /// [`wrapper!`][crate::wrapper!]
4104 pub unsafe trait ObjectSubclassIs : IsClass {
4105 type Subclass : ObjectSubclass ;
4106 }
4107
4108 impl <T: ParentClassIs > ops ::Deref for Class <T> {
4109 type Target = Class <T::Parent >;
4110
4111 #[inline ]
4112 fn deref (&self) -> &Self::Target {
4113 unsafe {
4114 let klass : *const Class<::Parent> = self as * const _ as * const Self::Target ;
4115 &*klass
4116 }
4117 }
4118 }
4119
4120 impl <T: ParentClassIs > ops ::DerefMut for Class <T> {
4121 #[inline ]
4122 fn deref_mut (&mut self) -> &mut Self::Target {
4123 unsafe {
4124 let klass : *mut Class<::Parent> = self as * mut _ as * mut Self::Target ;
4125 &mut *klass
4126 }
4127 }
4128 }
4129
4130 // rustdoc-stripper-ignore-next
4131 /// Trait implemented by class types.
4132 pub unsafe trait IsClass : ObjectType {}
4133
4134 // rustdoc-stripper-ignore-next
4135 /// Interface struct of type `T` for some type.
4136 #[repr (transparent)]
4137 pub struct Interface <T: IsInterface >(T::GlibClassType );
4138
4139 impl <T: IsInterface > Interface <T> {
4140 // rustdoc-stripper-ignore-next
4141 /// Get the type id for this interface.
4142 ///
4143 /// This is equivalent to `T::static_type()`.
4144 #[doc (alias = "get_type" )]
4145 #[inline ]
4146 pub fn type_ (&self) -> Type {
4147 unsafe {
4148 let klass = self as * const _ as * const gobject_ffi ::GTypeInterface ;
4149 from_glib ((*klass ).g_type )
4150 }
4151 }
4152
4153 // rustdoc-stripper-ignore-next
4154 /// Get the type id for the instance type of this interface.
4155 ///
4156 /// This is not equivalent to `T::static_type()` but is the type id of the type this specific
4157 /// interface belongs to.
4158 #[doc (alias = "get_instance_type" )]
4159 #[inline ]
4160 pub fn instance_type (&self) -> Type {
4161 unsafe {
4162 // This also works for interfaces because they also have the type
4163 // as the first struct field.
4164 let klass = self as * const _ as * const gobject_ffi ::GTypeInterface ;
4165 from_glib ((*klass ).g_instance_type )
4166 }
4167 }
4168
4169 // rustdoc-stripper-ignore-next
4170 /// Gets the interface struct for `Self` of `klass`.
4171 ///
4172 /// This will return `None` if `klass` is not implementing `Self`.
4173 #[inline ]
4174 pub fn from_class <U: IsClass >(klass : &Class <U>) -> Option <InterfaceRef <T>> {
4175 if !klass .type_ ().is_a (T::static_type ()) {
4176 return None ;
4177 }
4178
4179 unsafe {
4180 let ptr = gobject_ffi ::g_type_interface_peek (
4181 &klass .0 as * const _ as * mut _,
4182 T::static_type ().into_glib (),
4183 );
4184 if ptr .is_null () {
4185 None
4186 } else {
4187 Some (InterfaceRef (
4188 ptr ::NonNull ::new_unchecked (ptr as * mut Self),
4189 false ,
4190 PhantomData ,
4191 ))
4192 }
4193 }
4194 }
4195
4196 // rustdoc-stripper-ignore-next
4197 /// Gets the default interface struct for `Self`.
4198 ///
4199 /// This will return `None` if `type_` is not an interface.
4200 #[inline ]
4201 pub fn from_type (type_ : Type ) -> Option <InterfaceRef <'static, T>> {
4202 if !type_ .is_a (Type ::INTERFACE) {
4203 return None ;
4204 }
4205
4206 unsafe {
4207 let ptr = gobject_ffi ::g_type_default_interface_ref (T::static_type ().into_glib ());
4208 if ptr .is_null () {
4209 None
4210 } else {
4211 Some (InterfaceRef (
4212 ptr ::NonNull ::new_unchecked (ptr as * mut Self),
4213 true ,
4214 PhantomData ,
4215 ))
4216 }
4217 }
4218 }
4219
4220 // rustdoc-stripper-ignore-next
4221 /// Gets the default interface struct for `Self`.
4222 #[doc (alias = "g_type_default_interface_ref" )]
4223 #[allow (clippy::should_implement_trait)]
4224 #[inline ]
4225 pub fn default () -> InterfaceRef <'static, T> {
4226 unsafe {
4227 let ptr = gobject_ffi ::g_type_default_interface_ref (T::static_type ().into_glib ());
4228 debug_assert !(!ptr .is_null ());
4229 InterfaceRef (
4230 ptr ::NonNull ::new_unchecked (ptr as * mut Self),
4231 true ,
4232 PhantomData ,
4233 )
4234 }
4235 }
4236
4237 // rustdoc-stripper-ignore-next
4238 /// Gets the parent interface struct, if any.
4239 ///
4240 /// This returns the parent interface if a parent type of the instance type also implements the
4241 /// interface.
4242 #[doc (alias = "g_type_interface_peek_parent" )]
4243 #[inline ]
4244 pub fn parent (&self) -> Option <InterfaceRef <T>> {
4245 unsafe {
4246 let ptr = gobject_ffi ::g_type_interface_peek_parent (&self.0 as * const _ as * mut _);
4247 if ptr .is_null () {
4248 None
4249 } else {
4250 Some (InterfaceRef (
4251 ptr ::NonNull ::new_unchecked (ptr as * mut Self),
4252 false ,
4253 PhantomData ,
4254 ))
4255 }
4256 }
4257 }
4258 }
4259
4260 impl <T: IsA <Object > + IsInterface > Interface <T> {
4261 // rustdoc-stripper-ignore-next
4262 /// Check if this interface has a property `property_name` of the given `type_`.
4263 ///
4264 /// If no type is provided then only the existence of the property is checked.
4265 pub fn has_property (&self, property_name : &str , type_ : Option <Type >) -> bool {
4266 let ptype = self.property_type (property_name );
4267
4268 match (ptype , type_ ) {
4269 (None , _) => false ,
4270 (Some (_), None ) => true ,
4271 (Some (ptype ), Some (type_ )) => ptype == type_ ,
4272 }
4273 }
4274
4275 // rustdoc-stripper-ignore-next
4276 /// Get the type of the property `property_name` of this interface.
4277 ///
4278 /// This returns `None` if the property does not exist.
4279 #[doc (alias = "get_property_type" )]
4280 pub fn property_type (&self, property_name : &str ) -> Option <Type > {
4281 self.find_property (property_name )
4282 .map (|pspec | pspec .value_type ())
4283 }
4284
4285 // rustdoc-stripper-ignore-next
4286 /// Get the [`ParamSpec`](crate::ParamSpec) of the property `property_name` of this interface.
4287 #[doc (alias = "g_object_interface_find_property" )]
4288 pub fn find_property (&self, property_name : &str ) -> Option <crate ::ParamSpec > {
4289 unsafe {
4290 let interface = self as * const _ as * const gobject_ffi ::GTypeInterface ;
4291
4292 from_glib_none (gobject_ffi ::g_object_interface_find_property (
4293 interface as * mut _,
4294 property_name .to_glib_none ().0 ,
4295 ))
4296 }
4297 }
4298
4299 // rustdoc-stripper-ignore-next
4300 /// Return all [`ParamSpec`](crate::ParamSpec) of the properties of this interface.
4301 #[doc (alias = "g_object_interface_list_properties" )]
4302 pub fn list_properties (&self) -> PtrSlice <crate ::ParamSpec > {
4303 unsafe {
4304 let interface = self as * const _ as * const gobject_ffi ::GTypeInterface ;
4305
4306 let mut n_properties = 0 ;
4307
4308 let props = gobject_ffi ::g_object_interface_list_properties (
4309 interface as * mut _,
4310 &mut n_properties ,
4311 );
4312 PtrSlice ::from_glib_container_num (props , n_properties as usize , true )
4313 }
4314 }
4315 }
4316
4317 unsafe impl <T: IsInterface > Send for Interface <T> {}
4318 unsafe impl <T: IsInterface > Sync for Interface <T> {}
4319
4320 impl <T: IsInterface > AsRef <T::GlibClassType > for Interface <T> {
4321 #[inline ]
4322 fn as_ref (&self) -> &T::GlibClassType {
4323 &self.0
4324 }
4325 }
4326
4327 impl <T: IsInterface > AsMut <T::GlibClassType > for Interface <T> {
4328 #[inline ]
4329 fn as_mut (&mut self) -> &mut T::GlibClassType {
4330 &mut self.0
4331 }
4332 }
4333
4334 // rustdoc-stripper-ignore-next
4335 /// Reference to a class struct of type `T`.
4336 #[derive (Debug)]
4337 pub struct InterfaceRef <'a, T: IsInterface >(ptr ::NonNull <Interface <T>>, bool , PhantomData <&'a ()>);
4338
4339 impl <T: IsInterface > Drop for InterfaceRef <'_, T> {
4340 #[inline ]
4341 fn drop (&mut self) {
4342 if self.1 {
4343 unsafe {
4344 gobject_ffi ::g_type_default_interface_unref (self.0 .as_ptr () as * mut _);
4345 }
4346 }
4347 }
4348 }
4349
4350 impl <T: IsInterface > ops ::Deref for InterfaceRef <'_, T> {
4351 type Target = Interface <T>;
4352
4353 #[inline ]
4354 fn deref (&self) -> &Interface <T> {
4355 unsafe { self.0 .as_ref () }
4356 }
4357 }
4358
4359 unsafe impl <T: IsInterface > Send for InterfaceRef <'_, T> {}
4360 unsafe impl <T: IsInterface > Sync for InterfaceRef <'_, T> {}
4361
4362 // rustdoc-stripper-ignore-next
4363 /// Trait implemented by interface types.
4364 pub unsafe trait IsInterface : ObjectType {}
4365
4366 // rustdoc-stripper-ignore-next
4367 /// `Value` type checker for object types.
4368 pub struct ObjectValueTypeChecker <T>(std ::marker ::PhantomData <T>);
4369
4370 unsafe impl <T: StaticType > crate ::value ::ValueTypeChecker for ObjectValueTypeChecker <T> {
4371 type Error = crate ::value ::ValueTypeMismatchOrNoneError <crate ::value ::ValueTypeMismatchError >;
4372
4373 fn check (value : &Value ) -> Result <(), Self::Error > {
4374 // g_type_check_value_holds() only checks for the GType of the GValue. This might be
4375 // initialized to a parent type of the expected type and would then fail while it's
4376 // still valid to retrieve the value.
4377
4378 unsafe {
4379 let requested_type = T::static_type ().into_glib ();
4380 let type_ = value .inner .g_type ;
4381
4382 // Direct match or value type is a subtype of the requested type.
4383 if gobject_ffi ::g_type_is_a (type_ , requested_type ) != ffi ::GFALSE {
4384 let obj = gobject_ffi ::g_value_get_object (&value .inner );
4385 if obj .is_null () {
4386 return Err (Self::Error ::UnexpectedNone );
4387 } else {
4388 return Ok (());
4389 }
4390 }
4391
4392 // If the value type is not a GObject or subtype of GObject then there's a mismatch.
4393 if gobject_ffi ::g_type_is_a (type_ , gobject_ffi ::G_TYPE_OBJECT) == ffi ::GFALSE {
4394 return Err (crate ::value ::ValueTypeMismatchError ::new (
4395 Type ::from_glib (type_ ),
4396 T::static_type (),
4397 )
4398 .into ());
4399 }
4400
4401 // Otherwise peek at the actual object and its concrete type.
4402 let obj = gobject_ffi ::g_value_get_object (&value .inner );
4403
4404 // Allow any types if the object is NULL.
4405 if obj .is_null () {
4406 return Err (Self::Error ::UnexpectedNone );
4407 }
4408
4409 let type_ = (*(*obj ).g_type_instance .g_class ).g_type ;
4410 // Direct match or concrete type is a subtype of the requested type.
4411 if gobject_ffi ::g_type_is_a (type_ , requested_type ) != ffi ::GFALSE {
4412 Ok (())
4413 } else {
4414 Err (crate ::value ::ValueTypeMismatchError ::new (
4415 Type ::from_glib (type_ ),
4416 T::static_type (),
4417 )
4418 .into ())
4419 }
4420 }
4421 }
4422 }
4423
4424 // rustdoc-stripper-ignore-next
4425 /// Borrowed reference to an object of type `T`.
4426 ///
4427 /// This dereferences into `&T`.
4428 #[derive (Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
4429 #[repr (transparent)]
4430 pub struct BorrowedObject <'a, T> {
4431 ptr : ptr ::NonNull <gobject_ffi ::GObject >,
4432 phantom : PhantomData <&'a T>,
4433 }
4434
4435 unsafe impl <T: Send + Sync > Send for BorrowedObject <'_, T> {}
4436 unsafe impl <T: Send + Sync > Sync for BorrowedObject <'_, T> {}
4437
4438 impl <'a, T: ObjectType > BorrowedObject <'a, T> {
4439 // rustdoc-stripper-ignore-next
4440 /// Creates a new borrowed object reference.
4441 ///
4442 /// # SAFETY:
4443 ///
4444 /// The pointer needs to be valid for at least the lifetime `'a`.
4445 #[inline ]
4446 pub unsafe fn new (ptr : * mut T::GlibType ) -> BorrowedObject <'a, T> {
4447 BorrowedObject {
4448 ptr : ptr ::NonNull ::new_unchecked (ptr as * mut _),
4449 phantom : PhantomData ,
4450 }
4451 }
4452
4453 // rustdoc-stripper-ignore-next
4454 /// Downgrade to a weak reference.
4455 #[inline ]
4456 pub fn downgrade (&self) -> <Self as crate ::clone ::Downgrade >::Weak
4457 where
4458 T: crate ::clone ::Downgrade ,
4459 {
4460 <T as crate ::clone ::Downgrade >::downgrade (self)
4461 }
4462 }
4463
4464 impl <T> ops ::Deref for BorrowedObject <'_, T> {
4465 type Target = T;
4466
4467 #[inline ]
4468 fn deref (&self) -> &T {
4469 unsafe { &*(&self.ptr as * const _ as * const T) }
4470 }
4471 }
4472
4473 impl <T> AsRef <T> for BorrowedObject <'_, T> {
4474 #[inline ]
4475 fn as_ref (&self) -> &T {
4476 unsafe { &*(&self.ptr as * const _ as * const T) }
4477 }
4478 }
4479
4480 impl <T: PartialEq > PartialEq <T> for BorrowedObject <'_, T> {
4481 #[inline ]
4482 fn eq (&self, other : &T) -> bool {
4483 <T as PartialEq >::eq (self, other )
4484 }
4485 }
4486
4487 impl <T: PartialOrd > PartialOrd <T> for BorrowedObject <'_, T> {
4488 #[inline ]
4489 fn partial_cmp (&self, other : &T) -> Option <cmp ::Ordering > {
4490 <T as PartialOrd >::partial_cmp (self, other )
4491 }
4492 }
4493
4494 impl <T: crate ::clone ::Downgrade + ObjectType > crate ::clone ::Downgrade for BorrowedObject <'_, T> {
4495 type Weak = <T as crate ::clone ::Downgrade >::Weak ;
4496
4497 #[inline ]
4498 fn downgrade (&self) -> Self::Weak {
4499 <T as crate ::clone ::Downgrade >::downgrade (self)
4500 }
4501 }
4502
4503 #[cfg (test)]
4504 mod tests {
4505 use std ::{
4506 cell ::Cell ,
4507 rc ::Rc ,
4508 sync ::{
4509 atomic ::{AtomicBool , Ordering },
4510 Arc ,
4511 },
4512 };
4513
4514 use super ::*;
4515
4516 #[test ]
4517 fn new () {
4518 let obj : Object = Object ::new ();
4519 drop (obj);
4520 }
4521
4522 #[test ]
4523 fn data () {
4524 let obj : Object = Object ::new ();
4525 unsafe {
4526 obj.set_data ::<String >("foo" , "hello" .into ());
4527 let data = obj.data ::<String >("foo" ).unwrap ();
4528 assert_eq !(data.as_ref(), "hello" );
4529 let data2 = obj.steal_data ::<String >("foo" ).unwrap ();
4530 assert_eq !(data2, "hello" );
4531 }
4532 }
4533
4534 #[test ]
4535 fn weak_ref () {
4536 let obj : Object = Object ::new ();
4537
4538 let weakref : WeakRef <Object > = WeakRef ::new ();
4539 weakref.set (Some (&obj));
4540 assert !(weakref.upgrade().is_some());
4541 weakref.set (None );
4542 assert !(weakref.upgrade().is_none());
4543
4544 let weakref = WeakRef ::new ();
4545 weakref.set (Some (&obj));
4546 assert !(weakref.upgrade().is_some());
4547
4548 drop (obj);
4549 assert !(weakref.upgrade().is_none());
4550 }
4551
4552 #[test ]
4553 fn weak_ref_notify () {
4554 let obj : Object = Object ::new ();
4555
4556 let handle = obj.add_weak_ref_notify (|| {
4557 unreachable !();
4558 });
4559
4560 handle.disconnect ();
4561
4562 let called = Arc ::new (AtomicBool ::new (false ));
4563 let called_weak = Arc ::downgrade (&called);
4564 let handle = obj.add_weak_ref_notify (move || {
4565 called_weak.upgrade ().unwrap ().store (true , Ordering ::SeqCst );
4566 });
4567
4568 drop (obj);
4569 assert !(called.load(Ordering::SeqCst));
4570 handle.disconnect ();
4571
4572 let obj : Object = Object ::new ();
4573
4574 let called = Arc ::new (AtomicBool ::new (false ));
4575 let called_weak = Arc ::downgrade (&called);
4576 obj.add_weak_ref_notify (move || {
4577 called_weak.upgrade ().unwrap ().store (true , Ordering ::SeqCst );
4578 });
4579
4580 drop (obj);
4581 assert !(called.load(Ordering::SeqCst));
4582
4583 let obj : Object = Object ::new ();
4584
4585 let called = Rc ::new (Cell ::new (false ));
4586 let called_weak = Rc ::downgrade (&called);
4587 obj.add_weak_ref_notify_local (move || {
4588 called_weak.upgrade ().unwrap ().set (true );
4589 });
4590
4591 drop (obj);
4592 assert !(called.get());
4593 }
4594
4595 #[test ]
4596 fn test_value () {
4597 let obj1 : Object = Object ::new ();
4598 let v = obj1.to_value ();
4599 let obj2 = v.get ::<&Object >().unwrap ();
4600
4601 assert_eq !(obj1.as_ptr(), obj2.as_ptr());
4602 }
4603
4604 #[test ]
4605 fn test_borrow_hashing () {
4606 let mut m = std ::collections ::HashSet ::new ();
4607 let boxed_object = crate ::BoxedAnyObject ::new ("" );
4608
4609 m.insert (boxed_object.clone ());
4610
4611 let object : &Object = std ::borrow ::Borrow ::borrow (&boxed_object);
4612 assert_eq !(m.get(object), Some(&boxed_object));
4613 }
4614 }
4615