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