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