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
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    /// # Returns
391    ///
392    /// The timeline that `self`
393    /// is currently part of, or [`None`] if it is not associated with any
394    /// timeline.
395    #[doc(alias = "ges_layer_get_timeline")]
396    #[doc(alias = "get_timeline")]
397    fn timeline(&self) -> Option<Timeline> {
398        unsafe { from_glib_none(ffi::ges_layer_get_timeline(self.as_ref().to_glib_none().0)) }
399    }
400
401    /// Convenience method to check if the layer is empty (doesn't contain
402    /// any [`Clip`][crate::Clip]), or not.
403    ///
404    /// # Returns
405    ///
406    /// [`true`] if `self` is empty, [`false`] if it contains at least
407    /// one clip.
408    #[doc(alias = "ges_layer_is_empty")]
409    fn is_empty(&self) -> bool {
410        unsafe { from_glib(ffi::ges_layer_is_empty(self.as_ref().to_glib_none().0)) }
411    }
412
413    /// Removes the given clip from the layer.
414    /// ## `clip`
415    /// The clip to remove
416    ///
417    /// # Returns
418    ///
419    /// [`true`] if `clip` was removed from `self`, or [`false`] if the
420    /// operation failed.
421    #[doc(alias = "ges_layer_remove_clip")]
422    fn remove_clip(&self, clip: &impl IsA<Clip>) -> Result<(), glib::error::BoolError> {
423        unsafe {
424            glib::result_from_gboolean!(
425                ffi::ges_layer_remove_clip(
426                    self.as_ref().to_glib_none().0,
427                    clip.as_ref().to_glib_none().0
428                ),
429                "Failed to remove clip"
430            )
431        }
432    }
433
434    /// Activate or deactivate track elements in `tracks` (or in all tracks if `tracks`
435    /// is [`None`]).
436    ///
437    /// When a layer is deactivated for a track, all the [`TrackElement`][crate::TrackElement]-s in
438    /// the track that belong to a [`Clip`][crate::Clip] in the layer will no longer be
439    /// active in the track, regardless of their individual
440    /// [`active`][struct@crate::TrackElement#active] value.
441    ///
442    /// Note that by default a layer will be active for all of its
443    /// timeline's tracks.
444    /// ## `active`
445    /// Whether elements in `tracks` should be active or not
446    /// ## `tracks`
447    /// The list of
448    /// tracks `self` should be (de-)active in, or [`None`] to include all the tracks
449    /// in the `self`'s timeline
450    ///
451    /// # Returns
452    ///
453    /// [`true`] if the operation worked [`false`] otherwise.
454    #[cfg(feature = "v1_18")]
455    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
456    #[doc(alias = "ges_layer_set_active_for_tracks")]
457    fn set_active_for_tracks(&self, active: bool, tracks: &[Track]) -> bool {
458        unsafe {
459            from_glib(ffi::ges_layer_set_active_for_tracks(
460                self.as_ref().to_glib_none().0,
461                active.into_glib(),
462                tracks.to_glib_none().0,
463            ))
464        }
465    }
466
467    /// Sets [`auto-transition`][struct@crate::Layer#auto-transition] for the layer. Use
468    /// [`TimelineExt::set_auto_transition()`][crate::prelude::TimelineExt::set_auto_transition()] if you want all layers within a
469    /// [`Timeline`][crate::Timeline] to have [`auto-transition`][struct@crate::Layer#auto-transition] set to [`true`]. Use this
470    /// method if you want different values for different layers (and make sure
471    /// to keep [`auto-transition`][struct@crate::Timeline#auto-transition] as [`false`] for the corresponding
472    /// timeline).
473    /// ## `auto_transition`
474    /// Whether transitions should be automatically added to
475    /// the layer
476    #[doc(alias = "ges_layer_set_auto_transition")]
477    #[doc(alias = "auto-transition")]
478    fn set_auto_transition(&self, auto_transition: bool) {
479        unsafe {
480            ffi::ges_layer_set_auto_transition(
481                self.as_ref().to_glib_none().0,
482                auto_transition.into_glib(),
483            );
484        }
485    }
486
487    /// Sets the layer to the given priority. See [`priority`][struct@crate::Layer#priority].
488    ///
489    /// # Deprecated since 1.16
490    ///
491    /// use `ges_timeline_move_layer` instead. This deprecation means
492    /// that you will not need to handle layer priorities at all yourself, GES
493    /// will make sure there is never 'gaps' between layer priorities.
494    /// ## `priority`
495    /// The priority to set
496    #[cfg_attr(feature = "v1_16", deprecated = "Since 1.16")]
497    #[allow(deprecated)]
498    #[doc(alias = "ges_layer_set_priority")]
499    #[doc(alias = "priority")]
500    fn set_priority(&self, priority: u32) {
501        unsafe {
502            ffi::ges_layer_set_priority(self.as_ref().to_glib_none().0, priority);
503        }
504    }
505
506    #[doc(alias = "ges_layer_set_timeline")]
507    fn set_timeline(&self, timeline: &impl IsA<Timeline>) {
508        unsafe {
509            ffi::ges_layer_set_timeline(
510                self.as_ref().to_glib_none().0,
511                timeline.as_ref().to_glib_none().0,
512            );
513        }
514    }
515
516    //#[cfg(feature = "v1_18")]
517    //#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
518    //#[doc(alias = "active-changed")]
519    //fn connect_active_changed<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
520    //    Empty ctype tracks: *.PtrArray TypeId { ns_id: 1, id: 17 }
521    //}
522
523    /// Will be emitted after the clip is added to the layer.
524    /// ## `clip`
525    /// The clip that was added
526    #[doc(alias = "clip-added")]
527    fn connect_clip_added<F: Fn(&Self, &Clip) + 'static>(&self, f: F) -> SignalHandlerId {
528        unsafe extern "C" fn clip_added_trampoline<P: IsA<Layer>, F: Fn(&P, &Clip) + 'static>(
529            this: *mut ffi::GESLayer,
530            clip: *mut ffi::GESClip,
531            f: glib::ffi::gpointer,
532        ) {
533            let f: &F = &*(f as *const F);
534            f(
535                Layer::from_glib_borrow(this).unsafe_cast_ref(),
536                &from_glib_borrow(clip),
537            )
538        }
539        unsafe {
540            let f: Box_<F> = Box_::new(f);
541            connect_raw(
542                self.as_ptr() as *mut _,
543                c"clip-added".as_ptr() as *const _,
544                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
545                    clip_added_trampoline::<Self, F> as *const (),
546                )),
547                Box_::into_raw(f),
548            )
549        }
550    }
551
552    /// Will be emitted after the clip is removed from the layer.
553    /// ## `clip`
554    /// The clip that was removed
555    #[doc(alias = "clip-removed")]
556    fn connect_clip_removed<F: Fn(&Self, &Clip) + 'static>(&self, f: F) -> SignalHandlerId {
557        unsafe extern "C" fn clip_removed_trampoline<P: IsA<Layer>, F: Fn(&P, &Clip) + 'static>(
558            this: *mut ffi::GESLayer,
559            clip: *mut ffi::GESClip,
560            f: glib::ffi::gpointer,
561        ) {
562            let f: &F = &*(f as *const F);
563            f(
564                Layer::from_glib_borrow(this).unsafe_cast_ref(),
565                &from_glib_borrow(clip),
566            )
567        }
568        unsafe {
569            let f: Box_<F> = Box_::new(f);
570            connect_raw(
571                self.as_ptr() as *mut _,
572                c"clip-removed".as_ptr() as *const _,
573                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
574                    clip_removed_trampoline::<Self, F> as *const (),
575                )),
576                Box_::into_raw(f),
577            )
578        }
579    }
580
581    #[doc(alias = "auto-transition")]
582    fn connect_auto_transition_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
583        unsafe extern "C" fn notify_auto_transition_trampoline<
584            P: IsA<Layer>,
585            F: Fn(&P) + 'static,
586        >(
587            this: *mut ffi::GESLayer,
588            _param_spec: glib::ffi::gpointer,
589            f: glib::ffi::gpointer,
590        ) {
591            let f: &F = &*(f as *const F);
592            f(Layer::from_glib_borrow(this).unsafe_cast_ref())
593        }
594        unsafe {
595            let f: Box_<F> = Box_::new(f);
596            connect_raw(
597                self.as_ptr() as *mut _,
598                c"notify::auto-transition".as_ptr() as *const _,
599                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
600                    notify_auto_transition_trampoline::<Self, F> as *const (),
601                )),
602                Box_::into_raw(f),
603            )
604        }
605    }
606
607    #[cfg_attr(feature = "v1_16", deprecated = "Since 1.16")]
608    #[doc(alias = "priority")]
609    fn connect_priority_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
610        unsafe extern "C" fn notify_priority_trampoline<P: IsA<Layer>, F: Fn(&P) + 'static>(
611            this: *mut ffi::GESLayer,
612            _param_spec: glib::ffi::gpointer,
613            f: glib::ffi::gpointer,
614        ) {
615            let f: &F = &*(f as *const F);
616            f(Layer::from_glib_borrow(this).unsafe_cast_ref())
617        }
618        unsafe {
619            let f: Box_<F> = Box_::new(f);
620            connect_raw(
621                self.as_ptr() as *mut _,
622                c"notify::priority".as_ptr() as *const _,
623                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
624                    notify_priority_trampoline::<Self, F> as *const (),
625                )),
626                Box_::into_raw(f),
627            )
628        }
629    }
630}
631
632impl<O: IsA<Layer>> LayerExt for O {}