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