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}