Skip to main content

glib/
object.rs

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