Skip to main content

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::{Asset, Clip, Extractable, MetaContainer, Timeline, TrackType, ffi};
11use glib::{
12    object::ObjectType as _,
13    prelude::*,
14    signal::{SignalHandlerId, connect_raw},
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
128/// Trait containing all [`struct@Layer`] methods.
129///
130/// # Implementors
131///
132/// [`Layer`][struct@crate::Layer]
133pub trait LayerExt: IsA<Layer> + 'static {
134    /// See [`add_asset_full()`][Self::add_asset_full()], which also gives an error.
135    /// ## `asset`
136    /// The asset to extract the new clip from
137    /// ## `start`
138    /// The [`start`][struct@crate::TimelineElement#start] value to set on the new clip
139    /// If `start == `GST_CLOCK_TIME_NONE``, it will be added to the end
140    /// of `self`, i.e. it will be set to `self`'s duration
141    /// ## `inpoint`
142    /// The [`in-point`][struct@crate::TimelineElement#in-point] value to set on the new
143    /// clip
144    /// ## `duration`
145    /// The [`duration`][struct@crate::TimelineElement#duration] value to set on the new
146    /// clip
147    /// ## `track_types`
148    /// The [`supported-formats`][struct@crate::Clip#supported-formats] to set on the the new
149    /// clip, or [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN] to use the default
150    ///
151    /// # Returns
152    ///
153    /// The newly created clip.
154    #[doc(alias = "ges_layer_add_asset")]
155    fn add_asset(
156        &self,
157        asset: &impl IsA<Asset>,
158        start: impl Into<Option<gst::ClockTime>>,
159        inpoint: impl Into<Option<gst::ClockTime>>,
160        duration: impl Into<Option<gst::ClockTime>>,
161        track_types: TrackType,
162    ) -> Result<Clip, glib::BoolError> {
163        unsafe {
164            Option::<_>::from_glib_none(ffi::ges_layer_add_asset(
165                self.as_ref().to_glib_none().0,
166                asset.as_ref().to_glib_none().0,
167                start.into().into_glib(),
168                inpoint.into().into_glib(),
169                duration.into().into_glib(),
170                track_types.into_glib(),
171            ))
172            .ok_or_else(|| glib::bool_error!("Failed to add asset"))
173        }
174    }
175
176    /// Extracts a new clip from an asset and adds it to the layer with
177    /// the given properties.
178    /// ## `asset`
179    /// The asset to extract the new clip from
180    /// ## `start`
181    /// The [`start`][struct@crate::TimelineElement#start] value to set on the new clip
182    /// If `start == `GST_CLOCK_TIME_NONE``, it will be added to the end
183    /// of `self`, i.e. it will be set to `self`'s duration
184    /// ## `inpoint`
185    /// The [`in-point`][struct@crate::TimelineElement#in-point] value to set on the new
186    /// clip
187    /// ## `duration`
188    /// The [`duration`][struct@crate::TimelineElement#duration] value to set on the new
189    /// clip
190    /// ## `track_types`
191    /// The [`supported-formats`][struct@crate::Clip#supported-formats] to set on the the new
192    /// clip, or [`TrackType::UNKNOWN`][crate::TrackType::UNKNOWN] to use the default
193    ///
194    /// # Returns
195    ///
196    /// The newly created clip.
197    #[cfg(feature = "v1_18")]
198    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
199    #[doc(alias = "ges_layer_add_asset_full")]
200    fn add_asset_full(
201        &self,
202        asset: &impl IsA<Asset>,
203        start: impl Into<Option<gst::ClockTime>>,
204        inpoint: impl Into<Option<gst::ClockTime>>,
205        duration: impl Into<Option<gst::ClockTime>>,
206        track_types: TrackType,
207    ) -> Result<Clip, glib::Error> {
208        unsafe {
209            let mut error = std::ptr::null_mut();
210            let ret = ffi::ges_layer_add_asset_full(
211                self.as_ref().to_glib_none().0,
212                asset.as_ref().to_glib_none().0,
213                start.into().into_glib(),
214                inpoint.into().into_glib(),
215                duration.into().into_glib(),
216                track_types.into_glib(),
217                &mut error,
218            );
219            if error.is_null() {
220                Ok(from_glib_none(ret))
221            } else {
222                Err(from_glib_full(error))
223            }
224        }
225    }
226
227    /// See [`add_clip_full()`][Self::add_clip_full()], which also gives an error.
228    /// ## `clip`
229    /// The clip to add
230    ///
231    /// # Returns
232    ///
233    /// [`true`] if `clip` was properly added to `self`, or [`false`]
234    /// if `self` refused to add `clip`.
235    #[doc(alias = "ges_layer_add_clip")]
236    fn add_clip(&self, clip: &impl IsA<Clip>) -> Result<(), glib::error::BoolError> {
237        unsafe {
238            glib::result_from_gboolean!(
239                ffi::ges_layer_add_clip(
240                    self.as_ref().to_glib_none().0,
241                    clip.as_ref().to_glib_none().0
242                ),
243                "Failed to add clip"
244            )
245        }
246    }
247
248    /// Adds the given clip to the layer. If the method succeeds, the layer
249    /// will take ownership of the clip.
250    ///
251    /// This method will fail and return [`false`] if `clip` already resides in
252    /// some layer. It can also fail if the additional clip breaks some
253    /// compositional rules (see [`TimelineElement`][crate::TimelineElement]).
254    /// ## `clip`
255    /// The clip to add
256    ///
257    /// # Returns
258    ///
259    /// [`true`] if `clip` was properly added to `self`, or [`false`]
260    /// if `self` refused to add `clip`.
261    #[cfg(feature = "v1_18")]
262    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
263    #[doc(alias = "ges_layer_add_clip_full")]
264    fn add_clip_full(&self, clip: &impl IsA<Clip>) -> Result<(), glib::Error> {
265        unsafe {
266            let mut error = std::ptr::null_mut();
267            let is_ok = ffi::ges_layer_add_clip_full(
268                self.as_ref().to_glib_none().0,
269                clip.as_ref().to_glib_none().0,
270                &mut error,
271            );
272            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
273            if error.is_null() {
274                Ok(())
275            } else {
276                Err(from_glib_full(error))
277            }
278        }
279    }
280
281    /// Gets whether the layer is active for the given track. See
282    /// [`set_active_for_tracks()`][Self::set_active_for_tracks()].
283    /// ## `track`
284    /// The [`Track`][crate::Track] to check if `self` is currently active for
285    ///
286    /// # Returns
287    ///
288    /// [`true`] if `self` is active for `track`, or [`false`] otherwise.
289    #[cfg(feature = "v1_18")]
290    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
291    #[doc(alias = "ges_layer_get_active_for_track")]
292    #[doc(alias = "get_active_for_track")]
293    fn is_active_for_track(&self, track: &impl IsA<Track>) -> bool {
294        unsafe {
295            from_glib(ffi::ges_layer_get_active_for_track(
296                self.as_ref().to_glib_none().0,
297                track.as_ref().to_glib_none().0,
298            ))
299        }
300    }
301
302    /// Gets the [`auto-transition`][struct@crate::Layer#auto-transition] of the layer.
303    ///
304    /// # Returns
305    ///
306    /// [`true`] if transitions are automatically added to `self`.
307    #[doc(alias = "ges_layer_get_auto_transition")]
308    #[doc(alias = "get_auto_transition")]
309    #[doc(alias = "auto-transition")]
310    fn is_auto_transition(&self) -> bool {
311        unsafe {
312            from_glib(ffi::ges_layer_get_auto_transition(
313                self.as_ref().to_glib_none().0,
314            ))
315        }
316    }
317
318    /// Get the [`Clip`][crate::Clip]-s contained in this layer.
319    ///
320    /// # Returns
321    ///
322    /// A list of clips in
323    /// `self`.
324    #[doc(alias = "ges_layer_get_clips")]
325    #[doc(alias = "get_clips")]
326    fn clips(&self) -> Vec<Clip> {
327        unsafe {
328            FromGlibPtrContainer::from_glib_full(ffi::ges_layer_get_clips(
329                self.as_ref().to_glib_none().0,
330            ))
331        }
332    }
333
334    /// Gets the clips within the layer that appear between `start` and `end`.
335    /// ## `start`
336    /// Start of the interval
337    /// ## `end`
338    /// End of the interval
339    ///
340    /// # Returns
341    ///
342    /// A list of [`Clip`][crate::Clip]-s
343    /// that intersect the interval `[start, end)` in `self`.
344    #[doc(alias = "ges_layer_get_clips_in_interval")]
345    #[doc(alias = "get_clips_in_interval")]
346    fn clips_in_interval(
347        &self,
348        start: impl Into<Option<gst::ClockTime>>,
349        end: impl Into<Option<gst::ClockTime>>,
350    ) -> Vec<Clip> {
351        unsafe {
352            FromGlibPtrContainer::from_glib_full(ffi::ges_layer_get_clips_in_interval(
353                self.as_ref().to_glib_none().0,
354                start.into().into_glib(),
355                end.into().into_glib(),
356            ))
357        }
358    }
359
360    /// Retrieves the duration of the layer, which is the difference
361    /// between the start of the layer (always time 0) and the end (which will
362    /// be the end time of the final clip).
363    ///
364    /// # Returns
365    ///
366    /// The duration of `self`.
367    #[doc(alias = "ges_layer_get_duration")]
368    #[doc(alias = "get_duration")]
369    fn duration(&self) -> gst::ClockTime {
370        unsafe {
371            try_from_glib(ffi::ges_layer_get_duration(self.as_ref().to_glib_none().0))
372                .expect("mandatory glib value is None")
373        }
374    }
375
376    /// Get the priority of the layer. When inside a timeline, this is its
377    /// index in the timeline. See [`TimelineExt::move_layer()`][crate::prelude::TimelineExt::move_layer()].
378    ///
379    /// # Returns
380    ///
381    /// The priority of `self` within its timeline.
382    #[doc(alias = "ges_layer_get_priority")]
383    #[doc(alias = "get_priority")]
384    fn priority(&self) -> u32 {
385        unsafe { ffi::ges_layer_get_priority(self.as_ref().to_glib_none().0) }
386    }
387
388    /// Gets the timeline that the layer is a part of.
389    ///
390    /// # Deprecated since 1.30
391    ///
392    /// Use [`timeline_full()`][Self::timeline_full()] instead for MT-safety.
393    ///
394    /// # Returns
395    ///
396    /// The timeline that `self`
397    /// is currently part of, or [`None`] if it is not associated with any
398    /// timeline.
399    #[cfg_attr(feature = "v1_30", deprecated = "Since 1.30")]
400    #[allow(deprecated)]
401    #[doc(alias = "ges_layer_get_timeline")]
402    #[doc(alias = "get_timeline")]
403    fn timeline(&self) -> Option<Timeline> {
404        unsafe { from_glib_none(ffi::ges_layer_get_timeline(self.as_ref().to_glib_none().0)) }
405    }
406
407    /// Gets the timeline that the layer is a part of.
408    ///
409    /// # Returns
410    ///
411    /// The timeline that `self`
412    /// is currently part of, or [`None`] if it is not associated with any
413    /// timeline.
414    #[cfg(feature = "v1_30")]
415    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
416    #[doc(alias = "ges_layer_get_timeline_full")]
417    #[doc(alias = "get_timeline_full")]
418    fn timeline_full(&self) -> Option<Timeline> {
419        unsafe {
420            from_glib_full(ffi::ges_layer_get_timeline_full(
421                self.as_ref().to_glib_none().0,
422            ))
423        }
424    }
425
426    /// Convenience method to check if the layer is empty (doesn't contain
427    /// any [`Clip`][crate::Clip]), or not.
428    ///
429    /// # Returns
430    ///
431    /// [`true`] if `self` is empty, [`false`] if it contains at least
432    /// one clip.
433    #[doc(alias = "ges_layer_is_empty")]
434    fn is_empty(&self) -> bool {
435        unsafe { from_glib(ffi::ges_layer_is_empty(self.as_ref().to_glib_none().0)) }
436    }
437
438    /// Removes the given clip from the layer.
439    /// ## `clip`
440    /// The clip to remove
441    ///
442    /// # Returns
443    ///
444    /// [`true`] if `clip` was removed from `self`, or [`false`] if the
445    /// operation failed.
446    #[doc(alias = "ges_layer_remove_clip")]
447    fn remove_clip(&self, clip: &impl IsA<Clip>) -> Result<(), glib::error::BoolError> {
448        unsafe {
449            glib::result_from_gboolean!(
450                ffi::ges_layer_remove_clip(
451                    self.as_ref().to_glib_none().0,
452                    clip.as_ref().to_glib_none().0
453                ),
454                "Failed to remove clip"
455            )
456        }
457    }
458
459    /// Activate or deactivate track elements in `tracks` (or in all tracks if `tracks`
460    /// is [`None`]).
461    ///
462    /// When a layer is deactivated for a track, all the [`TrackElement`][crate::TrackElement]-s in
463    /// the track that belong to a [`Clip`][crate::Clip] in the layer will no longer be
464    /// active in the track, regardless of their individual
465    /// [`active`][struct@crate::TrackElement#active] value.
466    ///
467    /// Note that by default a layer will be active for all of its
468    /// timeline's tracks.
469    /// ## `active`
470    /// Whether elements in `tracks` should be active or not
471    /// ## `tracks`
472    /// The list of
473    /// tracks `self` should be (de-)active in, or [`None`] to include all the tracks
474    /// in the `self`'s timeline
475    ///
476    /// # Returns
477    ///
478    /// [`true`] if the operation worked [`false`] otherwise.
479    #[cfg(feature = "v1_18")]
480    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
481    #[doc(alias = "ges_layer_set_active_for_tracks")]
482    fn set_active_for_tracks(&self, active: bool, tracks: &[Track]) -> bool {
483        unsafe {
484            from_glib(ffi::ges_layer_set_active_for_tracks(
485                self.as_ref().to_glib_none().0,
486                active.into_glib(),
487                tracks.to_glib_none().0,
488            ))
489        }
490    }
491
492    /// Sets [`auto-transition`][struct@crate::Layer#auto-transition] for the layer. Use
493    /// [`TimelineExt::set_auto_transition()`][crate::prelude::TimelineExt::set_auto_transition()] if you want all layers within a
494    /// [`Timeline`][crate::Timeline] to have [`auto-transition`][struct@crate::Layer#auto-transition] set to [`true`]. Use this
495    /// method if you want different values for different layers (and make sure
496    /// to keep [`auto-transition`][struct@crate::Timeline#auto-transition] as [`false`] for the corresponding
497    /// timeline).
498    /// ## `auto_transition`
499    /// Whether transitions should be automatically added to
500    /// the layer
501    #[doc(alias = "ges_layer_set_auto_transition")]
502    #[doc(alias = "auto-transition")]
503    fn set_auto_transition(&self, auto_transition: bool) {
504        unsafe {
505            ffi::ges_layer_set_auto_transition(
506                self.as_ref().to_glib_none().0,
507                auto_transition.into_glib(),
508            );
509        }
510    }
511
512    /// Sets the layer to the given priority. See [`priority`][struct@crate::Layer#priority].
513    ///
514    /// # Deprecated since 1.16
515    ///
516    /// use `ges_timeline_move_layer` instead. This deprecation means
517    /// that you will not need to handle layer priorities at all yourself, GES
518    /// will make sure there is never 'gaps' between layer priorities.
519    /// ## `priority`
520    /// The priority to set
521    #[cfg_attr(feature = "v1_16", deprecated = "Since 1.16")]
522    #[allow(deprecated)]
523    #[doc(alias = "ges_layer_set_priority")]
524    #[doc(alias = "priority")]
525    fn set_priority(&self, priority: u32) {
526        unsafe {
527            ffi::ges_layer_set_priority(self.as_ref().to_glib_none().0, priority);
528        }
529    }
530
531    #[doc(alias = "ges_layer_set_timeline")]
532    fn set_timeline(&self, timeline: &impl IsA<Timeline>) {
533        unsafe {
534            ffi::ges_layer_set_timeline(
535                self.as_ref().to_glib_none().0,
536                timeline.as_ref().to_glib_none().0,
537            );
538        }
539    }
540
541    //#[cfg(feature = "v1_18")]
542    //#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
543    //#[doc(alias = "active-changed")]
544    //fn connect_active_changed<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
545    //    Empty ctype tracks: *.PtrArray TypeId { ns_id: 1, id: 17 }
546    //}
547
548    /// Will be emitted after the clip is added to the layer.
549    /// ## `clip`
550    /// The clip that was added
551    #[doc(alias = "clip-added")]
552    fn connect_clip_added<F: Fn(&Self, &Clip) + 'static>(&self, f: F) -> SignalHandlerId {
553        unsafe extern "C" fn clip_added_trampoline<P: IsA<Layer>, F: Fn(&P, &Clip) + 'static>(
554            this: *mut ffi::GESLayer,
555            clip: *mut ffi::GESClip,
556            f: glib::ffi::gpointer,
557        ) {
558            unsafe {
559                let f: &F = &*(f as *const F);
560                f(
561                    Layer::from_glib_borrow(this).unsafe_cast_ref(),
562                    &from_glib_borrow(clip),
563                )
564            }
565        }
566        unsafe {
567            let f: Box_<F> = Box_::new(f);
568            connect_raw(
569                self.as_ptr() as *mut _,
570                c"clip-added".as_ptr(),
571                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
572                    clip_added_trampoline::<Self, F> as *const (),
573                )),
574                Box_::into_raw(f),
575            )
576        }
577    }
578
579    /// Will be emitted after the clip is removed from the layer.
580    /// ## `clip`
581    /// The clip that was removed
582    #[doc(alias = "clip-removed")]
583    fn connect_clip_removed<F: Fn(&Self, &Clip) + 'static>(&self, f: F) -> SignalHandlerId {
584        unsafe extern "C" fn clip_removed_trampoline<P: IsA<Layer>, F: Fn(&P, &Clip) + 'static>(
585            this: *mut ffi::GESLayer,
586            clip: *mut ffi::GESClip,
587            f: glib::ffi::gpointer,
588        ) {
589            unsafe {
590                let f: &F = &*(f as *const F);
591                f(
592                    Layer::from_glib_borrow(this).unsafe_cast_ref(),
593                    &from_glib_borrow(clip),
594                )
595            }
596        }
597        unsafe {
598            let f: Box_<F> = Box_::new(f);
599            connect_raw(
600                self.as_ptr() as *mut _,
601                c"clip-removed".as_ptr(),
602                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
603                    clip_removed_trampoline::<Self, F> as *const (),
604                )),
605                Box_::into_raw(f),
606            )
607        }
608    }
609
610    #[doc(alias = "auto-transition")]
611    fn connect_auto_transition_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
612        unsafe extern "C" fn notify_auto_transition_trampoline<
613            P: IsA<Layer>,
614            F: Fn(&P) + 'static,
615        >(
616            this: *mut ffi::GESLayer,
617            _param_spec: glib::ffi::gpointer,
618            f: glib::ffi::gpointer,
619        ) {
620            unsafe {
621                let f: &F = &*(f as *const F);
622                f(Layer::from_glib_borrow(this).unsafe_cast_ref())
623            }
624        }
625        unsafe {
626            let f: Box_<F> = Box_::new(f);
627            connect_raw(
628                self.as_ptr() as *mut _,
629                c"notify::auto-transition".as_ptr(),
630                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
631                    notify_auto_transition_trampoline::<Self, F> as *const (),
632                )),
633                Box_::into_raw(f),
634            )
635        }
636    }
637
638    #[cfg_attr(feature = "v1_16", deprecated = "Since 1.16")]
639    #[doc(alias = "priority")]
640    fn connect_priority_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
641        unsafe extern "C" fn notify_priority_trampoline<P: IsA<Layer>, F: Fn(&P) + 'static>(
642            this: *mut ffi::GESLayer,
643            _param_spec: glib::ffi::gpointer,
644            f: glib::ffi::gpointer,
645        ) {
646            unsafe {
647                let f: &F = &*(f as *const F);
648                f(Layer::from_glib_borrow(this).unsafe_cast_ref())
649            }
650        }
651        unsafe {
652            let f: Box_<F> = Box_::new(f);
653            connect_raw(
654                self.as_ptr() as *mut _,
655                c"notify::priority".as_ptr(),
656                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
657                    notify_priority_trampoline::<Self, F> as *const (),
658                )),
659                Box_::into_raw(f),
660            )
661        }
662    }
663}
664
665impl<O: IsA<Layer>> LayerExt for O {}