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