gstreamer_editing_services/auto/
layer.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5#![allow(deprecated)]
6
7#[cfg(feature = "v1_18")]
8#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
9use crate::Track;
10use crate::{ffi, Asset, Clip, Extractable, MetaContainer, Timeline, TrackType};
11use glib::{
12    object::ObjectType as _,
13    prelude::*,
14    signal::{connect_raw, SignalHandlerId},
15    translate::*,
16};
17use std::boxed::Box as Box_;
18
19glib::wrapper! {
20    /// [`Layer`][crate::Layer]-s are responsible for collecting and ordering [`Clip`][crate::Clip]-s.
21    ///
22    /// A layer within a timeline will have an associated priority,
23    /// corresponding to their index within the timeline. A layer with the
24    /// index/priority 0 will have the highest priority and the layer with the
25    /// largest index will have the lowest priority (the order of priorities,
26    /// in this sense, is the _reverse_ of the numerical ordering of the
27    /// indices). [`TimelineExt::move_layer()`][crate::prelude::TimelineExt::move_layer()] should be used if you wish to
28    /// change how layers are prioritised in a timeline.
29    ///
30    /// Layers with higher priorities will have their content priorities
31    /// over content from lower priority layers, similar to how layers are
32    /// used in image editing. For example, if two separate layers both
33    /// display video content, then the layer with the higher priority will
34    /// have its images shown first. The other layer will only have its image
35    /// shown if the higher priority layer has no content at the given
36    /// playtime, or is transparent in some way. Audio content in separate
37    /// layers will simply play in addition.
38    ///
39    /// ## Properties
40    ///
41    ///
42    /// #### `auto-transition`
43    ///  Whether to automatically create a [`TransitionClip`][crate::TransitionClip] whenever two
44    /// [`Source`][crate::Source]-s that both belong to a [`Clip`][crate::Clip] in the layer overlap.
45    /// See [`Timeline`][crate::Timeline] for what counts as an overlap.
46    ///
47    /// When a layer is added to a [`Timeline`][crate::Timeline], if this property is left as
48    /// [`false`], but the timeline's [`auto-transition`][struct@crate::Timeline#auto-transition] is [`true`], it
49    /// will be set to [`true`] as well.
50    ///
51    /// Readable | Writeable
52    ///
53    ///
54    /// #### `priority`
55    ///  The priority of the layer in the [`Timeline`][crate::Timeline]. 0 is the highest
56    /// priority. Conceptually, a timeline is a stack of layers,
57    /// and the priority of the layer represents its position in the stack. Two
58    /// layers should not have the same priority within a given GESTimeline.
59    ///
60    /// Note that the timeline needs to be committed (with `ges_timeline_commit`)
61    /// for the change to be taken into account.
62    ///
63    /// Readable | Writeable
64    ///
65    /// ## Signals
66    ///
67    ///
68    /// #### `active-changed`
69    ///  Will be emitted whenever the layer is activated or deactivated
70    /// for some [`Track`][crate::Track]. See [`LayerExt::set_active_for_tracks()`][crate::prelude::LayerExt::set_active_for_tracks()].
71    ///
72    ///
73    ///
74    ///
75    /// #### `clip-added`
76    ///  Will be emitted after the clip is added to the layer.
77    ///
78    ///
79    ///
80    ///
81    /// #### `clip-removed`
82    ///  Will be emitted after the clip is removed from the layer.
83    ///
84    ///
85    /// <details><summary><h4>MetaContainer</h4></summary>
86    ///
87    ///
88    /// #### `notify-meta`
89    ///  This is emitted for a meta container whenever the metadata under one
90    /// of its fields changes, is set for the first time, or is removed. In
91    /// the latter case, `value` will be [`None`].
92    ///
93    /// Detailed
94    /// </details>
95    ///
96    /// # Implements
97    ///
98    /// [`LayerExt`][trait@crate::prelude::LayerExt], [`trait@glib::ObjectExt`], [`ExtractableExt`][trait@crate::prelude::ExtractableExt], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt]
99    #[doc(alias = "GESLayer")]
100    pub struct Layer(Object<ffi::GESLayer, ffi::GESLayerClass>) @implements Extractable, MetaContainer;
101
102    match fn {
103        type_ => || ffi::ges_layer_get_type(),
104    }
105}
106
107impl Layer {
108    pub const NONE: Option<&'static Layer> = None;
109
110    /// Creates a new layer.
111    ///
112    /// # Returns
113    ///
114    /// A new layer.
115    #[doc(alias = "ges_layer_new")]
116    pub fn new() -> Layer {
117        assert_initialized_main_thread!();
118        unsafe { from_glib_none(ffi::ges_layer_new()) }
119    }
120}
121
122impl Default for Layer {
123    fn default() -> Self {
124        Self::new()
125    }
126}
127
128mod sealed {
129    pub trait Sealed {}
130    impl<T: super::IsA<super::Layer>> Sealed for T {}
131}
132
133/// Trait containing all [`struct@Layer`] methods.
134///
135/// # Implementors
136///
137/// [`Layer`][struct@crate::Layer]
138pub trait LayerExt: IsA<Layer> + sealed::Sealed + 'static {
139    /// See [`add_asset_full()`][Self::add_asset_full()], which also gives an error.
140    /// ## `asset`
141    /// The asset to extract the new clip from
142    /// ## `start`
143    /// The [`start`][struct@crate::TimelineElement#start] value to set on the new clip
144    /// If `start == `GST_CLOCK_TIME_NONE``, it will be added to the end
145    /// of `self`, i.e. it will be set to `self`'s duration
146    /// ## `inpoint`
147    /// The [`in-point`][struct@crate::TimelineElement#in-point] value to set on the new
148    /// clip
149    /// ## `duration`
150    /// The [`duration`][struct@crate::TimelineElement#duration] value to set on the new
151    /// clip
152    /// ## `track_types`
153    /// The [`supported-formats`][struct@crate::Clip#supported-formats] to set on the the new
154    /// clip, or [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN] to use the default
155    ///
156    /// # Returns
157    ///
158    /// The newly created clip.
159    #[doc(alias = "ges_layer_add_asset")]
160    fn add_asset(
161        &self,
162        asset: &impl IsA<Asset>,
163        start: impl Into<Option<gst::ClockTime>>,
164        inpoint: impl Into<Option<gst::ClockTime>>,
165        duration: impl Into<Option<gst::ClockTime>>,
166        track_types: TrackType,
167    ) -> Result<Clip, glib::BoolError> {
168        unsafe {
169            Option::<_>::from_glib_none(ffi::ges_layer_add_asset(
170                self.as_ref().to_glib_none().0,
171                asset.as_ref().to_glib_none().0,
172                start.into().into_glib(),
173                inpoint.into().into_glib(),
174                duration.into().into_glib(),
175                track_types.into_glib(),
176            ))
177            .ok_or_else(|| glib::bool_error!("Failed to add asset"))
178        }
179    }
180
181    /// Extracts a new clip from an asset and adds it to the layer with
182    /// the given properties.
183    /// ## `asset`
184    /// The asset to extract the new clip from
185    /// ## `start`
186    /// The [`start`][struct@crate::TimelineElement#start] value to set on the new clip
187    /// If `start == `GST_CLOCK_TIME_NONE``, it will be added to the end
188    /// of `self`, i.e. it will be set to `self`'s duration
189    /// ## `inpoint`
190    /// The [`in-point`][struct@crate::TimelineElement#in-point] value to set on the new
191    /// clip
192    /// ## `duration`
193    /// The [`duration`][struct@crate::TimelineElement#duration] value to set on the new
194    /// clip
195    /// ## `track_types`
196    /// The [`supported-formats`][struct@crate::Clip#supported-formats] to set on the the new
197    /// clip, or [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN] to use the default
198    ///
199    /// # Returns
200    ///
201    /// The newly created clip.
202    #[cfg(feature = "v1_18")]
203    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
204    #[doc(alias = "ges_layer_add_asset_full")]
205    fn add_asset_full(
206        &self,
207        asset: &impl IsA<Asset>,
208        start: impl Into<Option<gst::ClockTime>>,
209        inpoint: impl Into<Option<gst::ClockTime>>,
210        duration: impl Into<Option<gst::ClockTime>>,
211        track_types: TrackType,
212    ) -> Result<Clip, glib::Error> {
213        unsafe {
214            let mut error = std::ptr::null_mut();
215            let ret = ffi::ges_layer_add_asset_full(
216                self.as_ref().to_glib_none().0,
217                asset.as_ref().to_glib_none().0,
218                start.into().into_glib(),
219                inpoint.into().into_glib(),
220                duration.into().into_glib(),
221                track_types.into_glib(),
222                &mut error,
223            );
224            if error.is_null() {
225                Ok(from_glib_none(ret))
226            } else {
227                Err(from_glib_full(error))
228            }
229        }
230    }
231
232    /// See [`add_clip_full()`][Self::add_clip_full()], which also gives an error.
233    /// ## `clip`
234    /// The clip to add
235    ///
236    /// # Returns
237    ///
238    /// [`true`] if `clip` was properly added to `self`, or [`false`]
239    /// if `self` refused to add `clip`.
240    #[doc(alias = "ges_layer_add_clip")]
241    fn add_clip(&self, clip: &impl IsA<Clip>) -> Result<(), glib::error::BoolError> {
242        unsafe {
243            glib::result_from_gboolean!(
244                ffi::ges_layer_add_clip(
245                    self.as_ref().to_glib_none().0,
246                    clip.as_ref().to_glib_none().0
247                ),
248                "Failed to add clip"
249            )
250        }
251    }
252
253    /// Adds the given clip to the layer. If the method succeeds, the layer
254    /// will take ownership of the clip.
255    ///
256    /// This method will fail and return [`false`] if `clip` already resides in
257    /// some layer. It can also fail if the additional clip breaks some
258    /// compositional rules (see [`TimelineElement`][crate::TimelineElement]).
259    /// ## `clip`
260    /// The clip to add
261    ///
262    /// # Returns
263    ///
264    /// [`true`] if `clip` was properly added to `self`, or [`false`]
265    /// if `self` refused to add `clip`.
266    #[cfg(feature = "v1_18")]
267    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
268    #[doc(alias = "ges_layer_add_clip_full")]
269    fn add_clip_full(&self, clip: &impl IsA<Clip>) -> Result<(), glib::Error> {
270        unsafe {
271            let mut error = std::ptr::null_mut();
272            let is_ok = ffi::ges_layer_add_clip_full(
273                self.as_ref().to_glib_none().0,
274                clip.as_ref().to_glib_none().0,
275                &mut error,
276            );
277            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
278            if error.is_null() {
279                Ok(())
280            } else {
281                Err(from_glib_full(error))
282            }
283        }
284    }
285
286    /// Gets whether the layer is active for the given track. See
287    /// [`set_active_for_tracks()`][Self::set_active_for_tracks()].
288    /// ## `track`
289    /// The [`Track`][crate::Track] to check if `self` is currently active for
290    ///
291    /// # Returns
292    ///
293    /// [`true`] if `self` is active for `track`, or [`false`] otherwise.
294    #[cfg(feature = "v1_18")]
295    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
296    #[doc(alias = "ges_layer_get_active_for_track")]
297    #[doc(alias = "get_active_for_track")]
298    fn is_active_for_track(&self, track: &impl IsA<Track>) -> bool {
299        unsafe {
300            from_glib(ffi::ges_layer_get_active_for_track(
301                self.as_ref().to_glib_none().0,
302                track.as_ref().to_glib_none().0,
303            ))
304        }
305    }
306
307    /// Gets the [`auto-transition`][struct@crate::Layer#auto-transition] of the layer.
308    ///
309    /// # Returns
310    ///
311    /// [`true`] if transitions are automatically added to `self`.
312    #[doc(alias = "ges_layer_get_auto_transition")]
313    #[doc(alias = "get_auto_transition")]
314    #[doc(alias = "auto-transition")]
315    fn is_auto_transition(&self) -> bool {
316        unsafe {
317            from_glib(ffi::ges_layer_get_auto_transition(
318                self.as_ref().to_glib_none().0,
319            ))
320        }
321    }
322
323    /// Get the [`Clip`][crate::Clip]-s contained in this layer.
324    ///
325    /// # Returns
326    ///
327    /// A list of clips in
328    /// `self`.
329    #[doc(alias = "ges_layer_get_clips")]
330    #[doc(alias = "get_clips")]
331    fn clips(&self) -> Vec<Clip> {
332        unsafe {
333            FromGlibPtrContainer::from_glib_full(ffi::ges_layer_get_clips(
334                self.as_ref().to_glib_none().0,
335            ))
336        }
337    }
338
339    /// Gets the clips within the layer that appear between `start` and `end`.
340    /// ## `start`
341    /// Start of the interval
342    /// ## `end`
343    /// End of the interval
344    ///
345    /// # Returns
346    ///
347    /// A list of [`Clip`][crate::Clip]-s
348    /// that intersect the interval `[start, end)` in `self`.
349    #[doc(alias = "ges_layer_get_clips_in_interval")]
350    #[doc(alias = "get_clips_in_interval")]
351    fn clips_in_interval(
352        &self,
353        start: impl Into<Option<gst::ClockTime>>,
354        end: impl Into<Option<gst::ClockTime>>,
355    ) -> Vec<Clip> {
356        unsafe {
357            FromGlibPtrContainer::from_glib_full(ffi::ges_layer_get_clips_in_interval(
358                self.as_ref().to_glib_none().0,
359                start.into().into_glib(),
360                end.into().into_glib(),
361            ))
362        }
363    }
364
365    /// Retrieves the duration of the layer, which is the difference
366    /// between the start of the layer (always time 0) and the end (which will
367    /// be the end time of the final clip).
368    ///
369    /// # Returns
370    ///
371    /// The duration of `self`.
372    #[doc(alias = "ges_layer_get_duration")]
373    #[doc(alias = "get_duration")]
374    fn duration(&self) -> gst::ClockTime {
375        unsafe {
376            try_from_glib(ffi::ges_layer_get_duration(self.as_ref().to_glib_none().0))
377                .expect("mandatory glib value is None")
378        }
379    }
380
381    /// Get the priority of the layer. When inside a timeline, this is its
382    /// index in the timeline. See [`TimelineExt::move_layer()`][crate::prelude::TimelineExt::move_layer()].
383    ///
384    /// # Returns
385    ///
386    /// The priority of `self` within its timeline.
387    #[doc(alias = "ges_layer_get_priority")]
388    #[doc(alias = "get_priority")]
389    fn priority(&self) -> u32 {
390        unsafe { ffi::ges_layer_get_priority(self.as_ref().to_glib_none().0) }
391    }
392
393    /// Gets the timeline that the layer is a part of.
394    ///
395    /// # Returns
396    ///
397    /// The timeline that `self`
398    /// is currently part of, or [`None`] if it is not associated with any
399    /// timeline.
400    #[doc(alias = "ges_layer_get_timeline")]
401    #[doc(alias = "get_timeline")]
402    fn timeline(&self) -> Option<Timeline> {
403        unsafe { from_glib_none(ffi::ges_layer_get_timeline(self.as_ref().to_glib_none().0)) }
404    }
405
406    /// Convenience method to check if the layer is empty (doesn't contain
407    /// any [`Clip`][crate::Clip]), or not.
408    ///
409    /// # Returns
410    ///
411    /// [`true`] if `self` is empty, [`false`] if it contains at least
412    /// one clip.
413    #[doc(alias = "ges_layer_is_empty")]
414    fn is_empty(&self) -> bool {
415        unsafe { from_glib(ffi::ges_layer_is_empty(self.as_ref().to_glib_none().0)) }
416    }
417
418    /// Removes the given clip from the layer.
419    /// ## `clip`
420    /// The clip to remove
421    ///
422    /// # Returns
423    ///
424    /// [`true`] if `clip` was removed from `self`, or [`false`] if the
425    /// operation failed.
426    #[doc(alias = "ges_layer_remove_clip")]
427    fn remove_clip(&self, clip: &impl IsA<Clip>) -> Result<(), glib::error::BoolError> {
428        unsafe {
429            glib::result_from_gboolean!(
430                ffi::ges_layer_remove_clip(
431                    self.as_ref().to_glib_none().0,
432                    clip.as_ref().to_glib_none().0
433                ),
434                "Failed to remove clip"
435            )
436        }
437    }
438
439    /// Activate or deactivate track elements in `tracks` (or in all tracks if `tracks`
440    /// is [`None`]).
441    ///
442    /// When a layer is deactivated for a track, all the [`TrackElement`][crate::TrackElement]-s in
443    /// the track that belong to a [`Clip`][crate::Clip] in the layer will no longer be
444    /// active in the track, regardless of their individual
445    /// [`active`][struct@crate::TrackElement#active] value.
446    ///
447    /// Note that by default a layer will be active for all of its
448    /// timeline's tracks.
449    /// ## `active`
450    /// Whether elements in `tracks` should be active or not
451    /// ## `tracks`
452    /// The list of
453    /// tracks `self` should be (de-)active in, or [`None`] to include all the tracks
454    /// in the `self`'s timeline
455    ///
456    /// # Returns
457    ///
458    /// [`true`] if the operation worked [`false`] otherwise.
459    #[cfg(feature = "v1_18")]
460    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
461    #[doc(alias = "ges_layer_set_active_for_tracks")]
462    fn set_active_for_tracks(&self, active: bool, tracks: &[Track]) -> bool {
463        unsafe {
464            from_glib(ffi::ges_layer_set_active_for_tracks(
465                self.as_ref().to_glib_none().0,
466                active.into_glib(),
467                tracks.to_glib_none().0,
468            ))
469        }
470    }
471
472    /// Sets [`auto-transition`][struct@crate::Layer#auto-transition] for the layer. Use
473    /// [`TimelineExt::set_auto_transition()`][crate::prelude::TimelineExt::set_auto_transition()] if you want all layers within a
474    /// [`Timeline`][crate::Timeline] to have [`auto-transition`][struct@crate::Layer#auto-transition] set to [`true`]. Use this
475    /// method if you want different values for different layers (and make sure
476    /// to keep [`auto-transition`][struct@crate::Timeline#auto-transition] as [`false`] for the corresponding
477    /// timeline).
478    /// ## `auto_transition`
479    /// Whether transitions should be automatically added to
480    /// the layer
481    #[doc(alias = "ges_layer_set_auto_transition")]
482    #[doc(alias = "auto-transition")]
483    fn set_auto_transition(&self, auto_transition: bool) {
484        unsafe {
485            ffi::ges_layer_set_auto_transition(
486                self.as_ref().to_glib_none().0,
487                auto_transition.into_glib(),
488            );
489        }
490    }
491
492    /// Sets the layer to the given priority. See [`priority`][struct@crate::Layer#priority].
493    ///
494    /// # Deprecated since 1.16
495    ///
496    /// use `ges_timeline_move_layer` instead. This deprecation means
497    /// that you will not need to handle layer priorities at all yourself, GES
498    /// will make sure there is never 'gaps' between layer priorities.
499    /// ## `priority`
500    /// The priority to set
501    #[cfg_attr(feature = "v1_16", deprecated = "Since 1.16")]
502    #[allow(deprecated)]
503    #[doc(alias = "ges_layer_set_priority")]
504    #[doc(alias = "priority")]
505    fn set_priority(&self, priority: u32) {
506        unsafe {
507            ffi::ges_layer_set_priority(self.as_ref().to_glib_none().0, priority);
508        }
509    }
510
511    #[doc(alias = "ges_layer_set_timeline")]
512    fn set_timeline(&self, timeline: &impl IsA<Timeline>) {
513        unsafe {
514            ffi::ges_layer_set_timeline(
515                self.as_ref().to_glib_none().0,
516                timeline.as_ref().to_glib_none().0,
517            );
518        }
519    }
520
521    //#[cfg(feature = "v1_18")]
522    //#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
523    //#[doc(alias = "active-changed")]
524    //fn connect_active_changed<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
525    //    Empty ctype tracks: *.PtrArray TypeId { ns_id: 1, id: 17 }
526    //}
527
528    /// Will be emitted after the clip is added to the layer.
529    /// ## `clip`
530    /// The clip that was added
531    #[doc(alias = "clip-added")]
532    fn connect_clip_added<F: Fn(&Self, &Clip) + 'static>(&self, f: F) -> SignalHandlerId {
533        unsafe extern "C" fn clip_added_trampoline<P: IsA<Layer>, F: Fn(&P, &Clip) + 'static>(
534            this: *mut ffi::GESLayer,
535            clip: *mut ffi::GESClip,
536            f: glib::ffi::gpointer,
537        ) {
538            let f: &F = &*(f as *const F);
539            f(
540                Layer::from_glib_borrow(this).unsafe_cast_ref(),
541                &from_glib_borrow(clip),
542            )
543        }
544        unsafe {
545            let f: Box_<F> = Box_::new(f);
546            connect_raw(
547                self.as_ptr() as *mut _,
548                b"clip-added\0".as_ptr() as *const _,
549                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
550                    clip_added_trampoline::<Self, F> as *const (),
551                )),
552                Box_::into_raw(f),
553            )
554        }
555    }
556
557    /// Will be emitted after the clip is removed from the layer.
558    /// ## `clip`
559    /// The clip that was removed
560    #[doc(alias = "clip-removed")]
561    fn connect_clip_removed<F: Fn(&Self, &Clip) + 'static>(&self, f: F) -> SignalHandlerId {
562        unsafe extern "C" fn clip_removed_trampoline<P: IsA<Layer>, F: Fn(&P, &Clip) + 'static>(
563            this: *mut ffi::GESLayer,
564            clip: *mut ffi::GESClip,
565            f: glib::ffi::gpointer,
566        ) {
567            let f: &F = &*(f as *const F);
568            f(
569                Layer::from_glib_borrow(this).unsafe_cast_ref(),
570                &from_glib_borrow(clip),
571            )
572        }
573        unsafe {
574            let f: Box_<F> = Box_::new(f);
575            connect_raw(
576                self.as_ptr() as *mut _,
577                b"clip-removed\0".as_ptr() as *const _,
578                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
579                    clip_removed_trampoline::<Self, F> as *const (),
580                )),
581                Box_::into_raw(f),
582            )
583        }
584    }
585
586    #[doc(alias = "auto-transition")]
587    fn connect_auto_transition_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
588        unsafe extern "C" fn notify_auto_transition_trampoline<
589            P: IsA<Layer>,
590            F: Fn(&P) + 'static,
591        >(
592            this: *mut ffi::GESLayer,
593            _param_spec: glib::ffi::gpointer,
594            f: glib::ffi::gpointer,
595        ) {
596            let f: &F = &*(f as *const F);
597            f(Layer::from_glib_borrow(this).unsafe_cast_ref())
598        }
599        unsafe {
600            let f: Box_<F> = Box_::new(f);
601            connect_raw(
602                self.as_ptr() as *mut _,
603                b"notify::auto-transition\0".as_ptr() as *const _,
604                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
605                    notify_auto_transition_trampoline::<Self, F> as *const (),
606                )),
607                Box_::into_raw(f),
608            )
609        }
610    }
611
612    #[cfg_attr(feature = "v1_16", deprecated = "Since 1.16")]
613    #[doc(alias = "priority")]
614    fn connect_priority_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
615        unsafe extern "C" fn notify_priority_trampoline<P: IsA<Layer>, F: Fn(&P) + 'static>(
616            this: *mut ffi::GESLayer,
617            _param_spec: glib::ffi::gpointer,
618            f: glib::ffi::gpointer,
619        ) {
620            let f: &F = &*(f as *const F);
621            f(Layer::from_glib_borrow(this).unsafe_cast_ref())
622        }
623        unsafe {
624            let f: Box_<F> = Box_::new(f);
625            connect_raw(
626                self.as_ptr() as *mut _,
627                b"notify::priority\0".as_ptr() as *const _,
628                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
629                    notify_priority_trampoline::<Self, F> as *const (),
630                )),
631                Box_::into_raw(f),
632            )
633        }
634    }
635}
636
637impl<O: IsA<Layer>> LayerExt for O {}