Skip to main content

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