I haven't used GdkFrameClock
in anger, just for a little bit of testing, but the following seems quite easy and works for me:
- Call
gtk_widget_add_tick_callback()
, passing the function you want to run on each refresh - Roughly 60 times a second (or as appropriate for your system), your callback will be called
- When you're done, call
gtk_widget_remove_tick_callback()
or returnFALSE
from your callback to stop receiving updates.
In step 2, you are passed the GdkFrameClock
in use, so you can call gdk_frame_clock_get_frame_time()
to get the exact frame timestamp, or use gdk_frame_clock_get_timings()
and the GdkFrameTimings
API to do more interesting things.
The following Vala code (easily convertible to D I'm sure :-)) shows this in action:
private static bool on_frame_tick(Gtk.Widget widget, Gdk.FrameClock frame_clock)
{
print("Got frame tick with timestamp %lld\n", frame_clock.get_frame_time());
return true; // Keep going
}
void main(string[] args)
{
Gtk.init(ref args);
var w = new Gtk.Window(Gtk.WindowType.TOPLEVEL);
w.add_tick_callback(on_frame_tick, null);
w.show_all();
Gtk.main();
}
Note that as per the docs, you'll need to call gtk_widget_queue_draw()
(or queue_draw_area()
) in your handler get it to get GTK to actually perform the redraw. This will in turn call the draw()
function of the widget in question.
As such, what I'd do is to save the frame timing information in my tick callback, call queue_redraw()
, then use the saved timing info in the draw()
implementation of my GtkDrawingArea
.