`gtk_widget_queue_draw` should schedule a next frame if currently in a draw function
Steps to reproduce
gtk4 code
#include <gtk/gtk.h>
double n = 1;
static void
draw_cb (GtkDrawingArea *drawing_area,
cairo_t *cr,
int width,
int height,
gpointer data)
{
cairo_set_source_rgb (cr, n, n, n);
cairo_paint (cr);
n -= 0.01;
if (n < 0) {
n = 1.0;
}
gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *drawing_area;
window = gtk_application_window_new (app);
drawing_area = gtk_drawing_area_new();
gtk_window_set_child(GTK_WINDOW (window) , drawing_area);
// gtk_container_add (GTK_CONTAINER (window), drawing_area);
// g_signal_connect (G_OBJECT (drawing_area), "draw",
// G_CALLBACK (draw_cb), NULL);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL);
gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
// gtk_widget_show_all (window);
gtk_widget_show (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}
gtk3 code
#include <gtk/gtk.h>
double n = 1;
static void
draw_cb (GtkDrawingArea *drawing_area,
cairo_t *cr,
int width,
int height,
gpointer data)
{
cairo_set_source_rgb (cr, n, n, n);
cairo_paint (cr);
n -= 0.01;
if (n < 0) {
n = 1.0;
}
gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *drawing_area;
window = gtk_application_window_new (app);
drawing_area = gtk_drawing_area_new();
// gtk_window_set_child(GTK_WINDOW (window) , drawing_area);
gtk_container_add (GTK_CONTAINER (window), drawing_area);
g_signal_connect (G_OBJECT (drawing_area), "draw",
G_CALLBACK (draw_cb), NULL);
// gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL);
gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
gtk_widget_show_all (window);
// gtk_widget_show (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}
You will notice that the GTK3 application changes colour on its own without outside input.
Current behavior
If gtk_widget_queue_draw
gets called withing a GtkDrawingAreaDrawFunc
in GTK4 there is no draw scheduled for the next frame. This makes porting GTK3 application that do this over to GTK4 harder, and also makes less sense then the previous behaviour. In its current form, calling gtk_widget_queue_draw
doesn't schedule a draw at all, which is against what the documentation says. (https://developer.gnome.org/gtk4/stable/GtkWidget.html#gtk-widget-queue-draw)
Expected outcome
The expected outcome is that if you call gtk_widget_queue_draw
during a drawing phase, it should schedule a draw for the next frame instead of none at all. (since its specified that it will schedule a draw).
Version information
gtk4: 4.0.3
gtk3: 3.24.26
arch linux