Currently, if it takes longer than 1/15th of a second to draw a frame,
the next frame will be queued before it has a chance to finish, which
then takes longer than 1/15th of a second to draw, so the next one gets
queued, ad infinitum.
We do two things to solve this problem. First, the timer runs at a
low priority so that a redraw doesn't get queued while a redraw is in
progress. Second, the timer skips queueing any frames that have missed
their time.
struct lbx_imginfo info;
GtkSpinButton *spin;
GtkToggleButton *play;
struct lbx_imginfo info;
GtkSpinButton *spin;
GtkToggleButton *play;
+ unsigned frame, newframe;
return;
elapsed += delta;
return;
elapsed += delta;
while (elapsed > seconds_per_frame) {
elapsed -= seconds_per_frame;
while (elapsed > seconds_per_frame) {
elapsed -= seconds_per_frame;
- if (++frame >= info.nframes) {
+ if (++newframe >= info.nframes) {
if (!info.looping) {
gtk_toggle_button_set_active(play, FALSE);
break;
}
if (!info.looping) {
gtk_toggle_button_set_active(play, FALSE);
break;
}
- frame = info.loopstart;
+ newframe = info.loopstart;
-
- gtk_spin_button_set_value(spin, frame);
+
+ if (frame != newframe)
+ gtk_spin_button_set_value(spin, newframe);
}
static gboolean timeout(gpointer data)
}
static gboolean timeout(gpointer data)
init_interface();
gtk_builder_connect_signals(builder, window);
init_interface();
gtk_builder_connect_signals(builder, window);
- g_timeout_add(10, timeout, NULL);
+ g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 10, timeout, NULL, NULL);
gtk_widget_show_all(window);
init_background(canvas->window);
gtk_widget_show_all(window);
init_background(canvas->window);