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}