Skip to main content

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::{FrameClockPhase, FrameTimings, ffi};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{SignalHandlerId, connect_raw},
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            unsafe {
330                let f: &F = &*(f as *const F);
331                f(&from_glib_borrow(this))
332            }
333        }
334        unsafe {
335            let f: Box_<F> = Box_::new(f);
336            connect_raw(
337                self.as_ptr() as *mut _,
338                c"after-paint".as_ptr() as *const _,
339                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
340                    after_paint_trampoline::<F> as *const (),
341                )),
342                Box_::into_raw(f),
343            )
344        }
345    }
346
347    /// Begins processing of the frame.
348    ///
349    /// Applications should generally not handle this signal.
350    #[doc(alias = "before-paint")]
351    pub fn connect_before_paint<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
352        unsafe extern "C" fn before_paint_trampoline<F: Fn(&FrameClock) + 'static>(
353            this: *mut ffi::GdkFrameClock,
354            f: glib::ffi::gpointer,
355        ) {
356            unsafe {
357                let f: &F = &*(f as *const F);
358                f(&from_glib_borrow(this))
359            }
360        }
361        unsafe {
362            let f: Box_<F> = Box_::new(f);
363            connect_raw(
364                self.as_ptr() as *mut _,
365                c"before-paint".as_ptr() as *const _,
366                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
367                    before_paint_trampoline::<F> as *const (),
368                )),
369                Box_::into_raw(f),
370            )
371        }
372    }
373
374    /// Used to flush pending motion events that are being batched up and
375    /// compressed together.
376    ///
377    /// Applications should not handle this signal.
378    #[doc(alias = "flush-events")]
379    pub fn connect_flush_events<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
380        unsafe extern "C" fn flush_events_trampoline<F: Fn(&FrameClock) + 'static>(
381            this: *mut ffi::GdkFrameClock,
382            f: glib::ffi::gpointer,
383        ) {
384            unsafe {
385                let f: &F = &*(f as *const F);
386                f(&from_glib_borrow(this))
387            }
388        }
389        unsafe {
390            let f: Box_<F> = Box_::new(f);
391            connect_raw(
392                self.as_ptr() as *mut _,
393                c"flush-events".as_ptr() as *const _,
394                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
395                    flush_events_trampoline::<F> as *const (),
396                )),
397                Box_::into_raw(f),
398            )
399        }
400    }
401
402    /// Emitted as the second step of toolkit and application processing
403    /// of the frame.
404    ///
405    /// Any work to update sizes and positions of application elements
406    /// should be performed. GTK normally handles this internally.
407    #[doc(alias = "layout")]
408    pub fn connect_layout<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
409        unsafe extern "C" fn layout_trampoline<F: Fn(&FrameClock) + 'static>(
410            this: *mut ffi::GdkFrameClock,
411            f: glib::ffi::gpointer,
412        ) {
413            unsafe {
414                let f: &F = &*(f as *const F);
415                f(&from_glib_borrow(this))
416            }
417        }
418        unsafe {
419            let f: Box_<F> = Box_::new(f);
420            connect_raw(
421                self.as_ptr() as *mut _,
422                c"layout".as_ptr() as *const _,
423                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
424                    layout_trampoline::<F> as *const (),
425                )),
426                Box_::into_raw(f),
427            )
428        }
429    }
430
431    /// Emitted as the third step of toolkit and application processing
432    /// of the frame.
433    ///
434    /// The frame is repainted. GDK normally handles this internally and
435    /// emits [`render`][struct@crate::Surface#render] signals which are turned into
436    /// [GtkWidget::snapshot](../gtk4/signal.Widget.snapshot.html) signals
437    /// by GTK.
438    #[doc(alias = "paint")]
439    pub fn connect_paint<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
440        unsafe extern "C" fn paint_trampoline<F: Fn(&FrameClock) + 'static>(
441            this: *mut ffi::GdkFrameClock,
442            f: glib::ffi::gpointer,
443        ) {
444            unsafe {
445                let f: &F = &*(f as *const F);
446                f(&from_glib_borrow(this))
447            }
448        }
449        unsafe {
450            let f: Box_<F> = Box_::new(f);
451            connect_raw(
452                self.as_ptr() as *mut _,
453                c"paint".as_ptr() as *const _,
454                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
455                    paint_trampoline::<F> as *const (),
456                )),
457                Box_::into_raw(f),
458            )
459        }
460    }
461
462    /// Emitted after processing of the frame is finished.
463    ///
464    /// This signal is handled internally by GTK to resume normal
465    /// event processing. Applications should not handle this signal.
466    #[doc(alias = "resume-events")]
467    pub fn connect_resume_events<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
468        unsafe extern "C" fn resume_events_trampoline<F: Fn(&FrameClock) + 'static>(
469            this: *mut ffi::GdkFrameClock,
470            f: glib::ffi::gpointer,
471        ) {
472            unsafe {
473                let f: &F = &*(f as *const F);
474                f(&from_glib_borrow(this))
475            }
476        }
477        unsafe {
478            let f: Box_<F> = Box_::new(f);
479            connect_raw(
480                self.as_ptr() as *mut _,
481                c"resume-events".as_ptr() as *const _,
482                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
483                    resume_events_trampoline::<F> as *const (),
484                )),
485                Box_::into_raw(f),
486            )
487        }
488    }
489
490    /// Emitted as the first step of toolkit and application processing
491    /// of the frame.
492    ///
493    /// Animations should be updated using [`frame_time()`][Self::frame_time()].
494    /// Applications can connect directly to this signal, or use
495    /// [gtk_widget_add_tick_callback()](../gtk4/method.Widget.add_tick_callback.html)
496    /// as a more convenient interface.
497    #[doc(alias = "update")]
498    pub fn connect_update<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
499        unsafe extern "C" fn update_trampoline<F: Fn(&FrameClock) + 'static>(
500            this: *mut ffi::GdkFrameClock,
501            f: glib::ffi::gpointer,
502        ) {
503            unsafe {
504                let f: &F = &*(f as *const F);
505                f(&from_glib_borrow(this))
506            }
507        }
508        unsafe {
509            let f: Box_<F> = Box_::new(f);
510            connect_raw(
511                self.as_ptr() as *mut _,
512                c"update".as_ptr() as *const _,
513                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
514                    update_trampoline::<F> as *const (),
515                )),
516                Box_::into_raw(f),
517            )
518        }
519    }
520}