gdk4/auto/
frame_clock.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// DO NOT EDIT
4
5use crate::{ffi, FrameClockPhase, FrameTimings};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{connect_raw, SignalHandlerId},
10    translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15    /// Tells the application when to update and repaint a surface.
16    ///
17    /// This may be synced to the vertical refresh rate of the monitor, for example.
18    /// Even when the frame clock uses a simple timer rather than a hardware-based
19    /// vertical sync, the frame clock helps because it ensures everything paints at
20    /// the same time (reducing the total number of frames).
21    ///
22    /// The frame clock can also automatically stop painting when it knows the frames
23    /// will not be visible, or scale back animation framerates.
24    ///
25    /// [`FrameClock`][crate::FrameClock] is designed to be compatible with an OpenGL-based implementation
26    /// or with mozRequestAnimationFrame in Firefox, for example.
27    ///
28    /// A frame clock is idle until someone requests a frame with
29    /// [`request_phase()`][Self::request_phase()]. At some later point that makes sense
30    /// for the synchronization being implemented, the clock will process a frame and
31    /// emit signals for each phase that has been requested. (See the signals of the
32    /// [`FrameClock`][crate::FrameClock] class for documentation of the phases.
33    /// [`FrameClockPhase::UPDATE`][crate::FrameClockPhase::UPDATE] and the [`update`][struct@crate::FrameClock#update] signal
34    /// are most interesting for application writers, and are used to update the
35    /// animations, using the frame time given by [`frame_time()`][Self::frame_time()].
36    ///
37    /// The frame time is reported in microseconds and generally in the same
38    /// timescale as g_get_monotonic_time(), however, it is not the same
39    /// as g_get_monotonic_time(). The frame time does not advance during
40    /// the time a frame is being painted, and outside of a frame, an attempt
41    /// is made so that all calls to [`frame_time()`][Self::frame_time()] that
42    /// are called at a “similar” time get the same value. This means that
43    /// if different animations are timed by looking at the difference in
44    /// time between an initial value from [`frame_time()`][Self::frame_time()]
45    /// and the value inside the [`update`][struct@crate::FrameClock#update] signal of the clock,
46    /// they will stay exactly synchronized.
47    ///
48    /// This is an Abstract Base Class, you cannot instantiate it.
49    ///
50    /// ## Signals
51    ///
52    ///
53    /// #### `after-paint`
54    ///  This signal ends processing of the frame.
55    ///
56    /// Applications should generally not handle this signal.
57    ///
58    ///
59    ///
60    ///
61    /// #### `before-paint`
62    ///  Begins processing of the frame.
63    ///
64    /// Applications should generally not handle this signal.
65    ///
66    ///
67    ///
68    ///
69    /// #### `flush-events`
70    ///  Used to flush pending motion events that are being batched up and
71    /// compressed together.
72    ///
73    /// Applications should not handle this signal.
74    ///
75    ///
76    ///
77    ///
78    /// #### `layout`
79    ///  Emitted as the second step of toolkit and application processing
80    /// of the frame.
81    ///
82    /// Any work to update sizes and positions of application elements
83    /// should be performed. GTK normally handles this internally.
84    ///
85    ///
86    ///
87    ///
88    /// #### `paint`
89    ///  Emitted as the third step of toolkit and application processing
90    /// of the frame.
91    ///
92    /// The frame is repainted. GDK normally handles this internally and
93    /// emits [`render`][struct@crate::Surface#render] signals which are turned into
94    /// [GtkWidget::snapshot](../gtk4/signal.Widget.snapshot.html) signals
95    /// by GTK.
96    ///
97    ///
98    ///
99    ///
100    /// #### `resume-events`
101    ///  Emitted after processing of the frame is finished.
102    ///
103    /// This signal is handled internally by GTK to resume normal
104    /// event processing. Applications should not handle this signal.
105    ///
106    ///
107    ///
108    ///
109    /// #### `update`
110    ///  Emitted as the first step of toolkit and application processing
111    /// of the frame.
112    ///
113    /// Animations should be updated using [`FrameClock::frame_time()`][crate::FrameClock::frame_time()].
114    /// Applications can connect directly to this signal, or use
115    /// [gtk_widget_add_tick_callback()](../gtk4/method.Widget.add_tick_callback.html)
116    /// as a more convenient interface.
117    ///
118    ///
119    #[doc(alias = "GdkFrameClock")]
120    pub struct FrameClock(Object<ffi::GdkFrameClock, ffi::GdkFrameClockClass>);
121
122    match fn {
123        type_ => || ffi::gdk_frame_clock_get_type(),
124    }
125}
126
127impl FrameClock {
128    /// Starts updates for an animation.
129    ///
130    /// Until a matching call to [`end_updating()`][Self::end_updating()] is made,
131    /// the frame clock will continually request a new frame with the
132    /// [`FrameClockPhase::UPDATE`][crate::FrameClockPhase::UPDATE] phase. This function may be called multiple
133    /// times and frames will be requested until gdk_frame_clock_end_updating()
134    /// is called the same number of times.
135    #[doc(alias = "gdk_frame_clock_begin_updating")]
136    pub fn begin_updating(&self) {
137        unsafe {
138            ffi::gdk_frame_clock_begin_updating(self.to_glib_none().0);
139        }
140    }
141
142    /// Stops updates for an animation.
143    ///
144    /// See the documentation for [`begin_updating()`][Self::begin_updating()].
145    #[doc(alias = "gdk_frame_clock_end_updating")]
146    pub fn end_updating(&self) {
147        unsafe {
148            ffi::gdk_frame_clock_end_updating(self.to_glib_none().0);
149        }
150    }
151
152    /// Gets the frame timings for the current frame.
153    ///
154    /// # Returns
155    ///
156    /// the [`FrameTimings`][crate::FrameTimings] for the
157    ///   frame currently being processed, or even no frame is being
158    ///   processed, for the previous frame. Before any frames have been
159    ///   processed, returns [`None`].
160    #[doc(alias = "gdk_frame_clock_get_current_timings")]
161    #[doc(alias = "get_current_timings")]
162    pub fn current_timings(&self) -> Option<FrameTimings> {
163        unsafe {
164            from_glib_none(ffi::gdk_frame_clock_get_current_timings(
165                self.to_glib_none().0,
166            ))
167        }
168    }
169
170    /// Calculates the current frames-per-second, based on the
171    /// frame timings of @self.
172    ///
173    /// # Returns
174    ///
175    /// the current fps, as a `double`
176    #[doc(alias = "gdk_frame_clock_get_fps")]
177    #[doc(alias = "get_fps")]
178    pub fn fps(&self) -> f64 {
179        unsafe { ffi::gdk_frame_clock_get_fps(self.to_glib_none().0) }
180    }
181
182    /// [`FrameClock`][crate::FrameClock] maintains a 64-bit counter that increments for
183    /// each frame drawn.
184    ///
185    /// # Returns
186    ///
187    /// inside frame processing, the value of the frame counter
188    ///   for the current frame. Outside of frame processing, the frame
189    ///   counter for the last frame.
190    #[doc(alias = "gdk_frame_clock_get_frame_counter")]
191    #[doc(alias = "get_frame_counter")]
192    pub fn frame_counter(&self) -> i64 {
193        unsafe { ffi::gdk_frame_clock_get_frame_counter(self.to_glib_none().0) }
194    }
195
196    /// Gets the time that should currently be used for animations.
197    ///
198    /// Inside the processing of a frame, it’s the time used to compute the
199    /// animation position of everything in a frame. Outside of a frame, it's
200    /// the time of the conceptual “previous frame,” which may be either
201    /// the actual previous frame time, or if that’s too old, an updated
202    /// time.
203    ///
204    /// # Returns
205    ///
206    /// a timestamp in microseconds, in the timescale of
207    ///  of g_get_monotonic_time().
208    #[doc(alias = "gdk_frame_clock_get_frame_time")]
209    #[doc(alias = "get_frame_time")]
210    pub fn frame_time(&self) -> i64 {
211        unsafe { ffi::gdk_frame_clock_get_frame_time(self.to_glib_none().0) }
212    }
213
214    /// Returns the frame counter for the oldest frame available in history.
215    ///
216    /// [`FrameClock`][crate::FrameClock] internally keeps a history of [`FrameTimings`][crate::FrameTimings]
217    /// objects for recent frames that can be retrieved with
218    /// [`timings()`][Self::timings()]. The set of stored frames
219    /// is the set from the counter values given by
220    /// [`history_start()`][Self::history_start()] and
221    /// [`frame_counter()`][Self::frame_counter()], inclusive.
222    ///
223    /// # Returns
224    ///
225    /// the frame counter value for the oldest frame
226    ///  that is available in the internal frame history of the
227    ///  [`FrameClock`][crate::FrameClock]
228    #[doc(alias = "gdk_frame_clock_get_history_start")]
229    #[doc(alias = "get_history_start")]
230    pub fn history_start(&self) -> i64 {
231        unsafe { ffi::gdk_frame_clock_get_history_start(self.to_glib_none().0) }
232    }
233
234    /// Predicts a presentation time, based on history.
235    ///
236    /// Using the frame history stored in the frame clock, finds the last
237    /// known presentation time and refresh interval, and assuming that
238    /// presentation times are separated by the refresh interval,
239    /// predicts a presentation time that is a multiple of the refresh
240    /// interval after the last presentation time, and later than @base_time.
241    /// ## `base_time`
242    /// base time for determining a presentaton time
243    ///
244    /// # Returns
245    ///
246    ///
247    /// ## `refresh_interval_return`
248    /// a location to store the
249    ///   determined refresh interval, or [`None`]. A default refresh interval of
250    ///   1/60th of a second will be stored if no history is present.
251    ///
252    /// ## `presentation_time_return`
253    /// a location to store the next
254    ///   candidate presentation time after the given base time.
255    ///   0 will be will be stored if no history is present.
256    #[doc(alias = "gdk_frame_clock_get_refresh_info")]
257    #[doc(alias = "get_refresh_info")]
258    pub fn refresh_info(&self, base_time: i64) -> (i64, i64) {
259        unsafe {
260            let mut refresh_interval_return = std::mem::MaybeUninit::uninit();
261            let mut presentation_time_return = std::mem::MaybeUninit::uninit();
262            ffi::gdk_frame_clock_get_refresh_info(
263                self.to_glib_none().0,
264                base_time,
265                refresh_interval_return.as_mut_ptr(),
266                presentation_time_return.as_mut_ptr(),
267            );
268            (
269                refresh_interval_return.assume_init(),
270                presentation_time_return.assume_init(),
271            )
272        }
273    }
274
275    /// Retrieves a [`FrameTimings`][crate::FrameTimings] object holding timing information
276    /// for the current frame or a recent frame.
277    ///
278    /// The [`FrameTimings`][crate::FrameTimings] object may not yet be complete: see
279    /// [`FrameTimings::is_complete()`][crate::FrameTimings::is_complete()] and
280    /// [`history_start()`][Self::history_start()].
281    /// ## `frame_counter`
282    /// the frame counter value identifying the frame to
283    ///  be received
284    ///
285    /// # Returns
286    ///
287    /// the [`FrameTimings`][crate::FrameTimings] object
288    ///   for the specified frame, or [`None`] if it is not available
289    #[doc(alias = "gdk_frame_clock_get_timings")]
290    #[doc(alias = "get_timings")]
291    pub fn timings(&self, frame_counter: i64) -> Option<FrameTimings> {
292        unsafe {
293            from_glib_none(ffi::gdk_frame_clock_get_timings(
294                self.to_glib_none().0,
295                frame_counter,
296            ))
297        }
298    }
299
300    /// Asks the frame clock to run a particular phase.
301    ///
302    /// The signal corresponding the requested phase will be emitted the next
303    /// time the frame clock processes. Multiple calls to
304    /// gdk_frame_clock_request_phase() will be combined together
305    /// and only one frame processed. If you are displaying animated
306    /// content and want to continually request the
307    /// [`FrameClockPhase::UPDATE`][crate::FrameClockPhase::UPDATE] phase for a period of time,
308    /// you should use [`begin_updating()`][Self::begin_updating()] instead,
309    /// since this allows GTK to adjust system parameters to get maximally
310    /// smooth animations.
311    /// ## `phase`
312    /// the phase that is requested
313    #[doc(alias = "gdk_frame_clock_request_phase")]
314    pub fn request_phase(&self, phase: FrameClockPhase) {
315        unsafe {
316            ffi::gdk_frame_clock_request_phase(self.to_glib_none().0, phase.into_glib());
317        }
318    }
319
320    /// This signal ends processing of the frame.
321    ///
322    /// Applications should generally not handle this signal.
323    #[doc(alias = "after-paint")]
324    pub fn connect_after_paint<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
325        unsafe extern "C" fn after_paint_trampoline<F: Fn(&FrameClock) + 'static>(
326            this: *mut ffi::GdkFrameClock,
327            f: glib::ffi::gpointer,
328        ) {
329            let f: &F = &*(f as *const F);
330            f(&from_glib_borrow(this))
331        }
332        unsafe {
333            let f: Box_<F> = Box_::new(f);
334            connect_raw(
335                self.as_ptr() as *mut _,
336                c"after-paint".as_ptr() as *const _,
337                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
338                    after_paint_trampoline::<F> as *const (),
339                )),
340                Box_::into_raw(f),
341            )
342        }
343    }
344
345    /// Begins processing of the frame.
346    ///
347    /// Applications should generally not handle this signal.
348    #[doc(alias = "before-paint")]
349    pub fn connect_before_paint<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
350        unsafe extern "C" fn before_paint_trampoline<F: Fn(&FrameClock) + 'static>(
351            this: *mut ffi::GdkFrameClock,
352            f: glib::ffi::gpointer,
353        ) {
354            let f: &F = &*(f as *const F);
355            f(&from_glib_borrow(this))
356        }
357        unsafe {
358            let f: Box_<F> = Box_::new(f);
359            connect_raw(
360                self.as_ptr() as *mut _,
361                c"before-paint".as_ptr() as *const _,
362                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
363                    before_paint_trampoline::<F> as *const (),
364                )),
365                Box_::into_raw(f),
366            )
367        }
368    }
369
370    /// Used to flush pending motion events that are being batched up and
371    /// compressed together.
372    ///
373    /// Applications should not handle this signal.
374    #[doc(alias = "flush-events")]
375    pub fn connect_flush_events<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
376        unsafe extern "C" fn flush_events_trampoline<F: Fn(&FrameClock) + 'static>(
377            this: *mut ffi::GdkFrameClock,
378            f: glib::ffi::gpointer,
379        ) {
380            let f: &F = &*(f as *const F);
381            f(&from_glib_borrow(this))
382        }
383        unsafe {
384            let f: Box_<F> = Box_::new(f);
385            connect_raw(
386                self.as_ptr() as *mut _,
387                c"flush-events".as_ptr() as *const _,
388                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
389                    flush_events_trampoline::<F> as *const (),
390                )),
391                Box_::into_raw(f),
392            )
393        }
394    }
395
396    /// Emitted as the second step of toolkit and application processing
397    /// of the frame.
398    ///
399    /// Any work to update sizes and positions of application elements
400    /// should be performed. GTK normally handles this internally.
401    #[doc(alias = "layout")]
402    pub fn connect_layout<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
403        unsafe extern "C" fn layout_trampoline<F: Fn(&FrameClock) + 'static>(
404            this: *mut ffi::GdkFrameClock,
405            f: glib::ffi::gpointer,
406        ) {
407            let f: &F = &*(f as *const F);
408            f(&from_glib_borrow(this))
409        }
410        unsafe {
411            let f: Box_<F> = Box_::new(f);
412            connect_raw(
413                self.as_ptr() as *mut _,
414                c"layout".as_ptr() as *const _,
415                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
416                    layout_trampoline::<F> as *const (),
417                )),
418                Box_::into_raw(f),
419            )
420        }
421    }
422
423    /// Emitted as the third step of toolkit and application processing
424    /// of the frame.
425    ///
426    /// The frame is repainted. GDK normally handles this internally and
427    /// emits [`render`][struct@crate::Surface#render] signals which are turned into
428    /// [GtkWidget::snapshot](../gtk4/signal.Widget.snapshot.html) signals
429    /// by GTK.
430    #[doc(alias = "paint")]
431    pub fn connect_paint<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
432        unsafe extern "C" fn paint_trampoline<F: Fn(&FrameClock) + 'static>(
433            this: *mut ffi::GdkFrameClock,
434            f: glib::ffi::gpointer,
435        ) {
436            let f: &F = &*(f as *const F);
437            f(&from_glib_borrow(this))
438        }
439        unsafe {
440            let f: Box_<F> = Box_::new(f);
441            connect_raw(
442                self.as_ptr() as *mut _,
443                c"paint".as_ptr() as *const _,
444                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
445                    paint_trampoline::<F> as *const (),
446                )),
447                Box_::into_raw(f),
448            )
449        }
450    }
451
452    /// Emitted after processing of the frame is finished.
453    ///
454    /// This signal is handled internally by GTK to resume normal
455    /// event processing. Applications should not handle this signal.
456    #[doc(alias = "resume-events")]
457    pub fn connect_resume_events<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
458        unsafe extern "C" fn resume_events_trampoline<F: Fn(&FrameClock) + 'static>(
459            this: *mut ffi::GdkFrameClock,
460            f: glib::ffi::gpointer,
461        ) {
462            let f: &F = &*(f as *const F);
463            f(&from_glib_borrow(this))
464        }
465        unsafe {
466            let f: Box_<F> = Box_::new(f);
467            connect_raw(
468                self.as_ptr() as *mut _,
469                c"resume-events".as_ptr() as *const _,
470                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
471                    resume_events_trampoline::<F> as *const (),
472                )),
473                Box_::into_raw(f),
474            )
475        }
476    }
477
478    /// Emitted as the first step of toolkit and application processing
479    /// of the frame.
480    ///
481    /// Animations should be updated using [`frame_time()`][Self::frame_time()].
482    /// Applications can connect directly to this signal, or use
483    /// [gtk_widget_add_tick_callback()](../gtk4/method.Widget.add_tick_callback.html)
484    /// as a more convenient interface.
485    #[doc(alias = "update")]
486    pub fn connect_update<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
487        unsafe extern "C" fn update_trampoline<F: Fn(&FrameClock) + 'static>(
488            this: *mut ffi::GdkFrameClock,
489            f: glib::ffi::gpointer,
490        ) {
491            let f: &F = &*(f as *const F);
492            f(&from_glib_borrow(this))
493        }
494        unsafe {
495            let f: Box_<F> = Box_::new(f);
496            connect_raw(
497                self.as_ptr() as *mut _,
498                c"update".as_ptr() as *const _,
499                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
500                    update_trampoline::<F> as *const (),
501                )),
502                Box_::into_raw(f),
503            )
504        }
505    }
506}