Gtk_gl_area doesn't render automatically

gtk_gl_area_get_auto_render(GTK_GL_AREA(gl_area)) returns 1 but the gl_area doesn’t render automatically and it renders only if I use manually gtk_gl_area_queue_render (GTK_GL_AREA(gl_area));
Does I have a misunderstanding of the property of GLArea:auto-render or there is some bug ?

/* OpenGL Area
 *
 * GtkGLArea is a widget that allows custom drawing using OpenGL calls.
 */

// compiling with: g++ gl_draw_area.cpp `pkg-config --cflags gtk+-3.0` 
// \ `pkg-config --libs gtk+-3.0` -lepoxy

#include <string.h>
#include <stdio.h>
#include <math.h>
#include <gtk/gtk.h>
#include <epoxy/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <iostream>

unsigned int WIDTH = 800;
unsigned int HEIGHT = 600;

using glm::mat4;
using glm::vec3;
using glm::lookAt;
using glm::perspective;
using glm::rotate;

const GLchar  *VERTEX_SOURCE =
"#version 330\n"
"in vec3 position;\n"
"in vec3 normal;\n"
"out vec3 transformedNormal;\n"
"out vec3 originalNormal;\n"
"uniform mat4 projection;\n"
"uniform mat4 view;\n"
"uniform mat4 model;\n"
"void main(){\n"
"    gl_Position =  projection * view * model * vec4(position, 1.0);\n"
"    mat3 normalMatrix = transpose(inverse(mat3(view * model)));\n"
"    transformedNormal = normalMatrix * normal;\n"
"    originalNormal = abs(normal);\n"
"}\n";

const GLchar *FRAGMENT_SOURCE =
"#version 330\n"
"in vec3 transformedNormal;\n"
"in vec3 originalNormal;\n"
"out vec4 outputColor;\n"
"void main() {\n"
"vec3 color = originalNormal;\n"
"float lighting = abs(dot(transformedNormal, vec3(0,0,-1)));\n"
"outputColor = vec4(color * lighting, 1.0f);\n" //constant white
"}";

/* the GtkGLArea widget */
static GtkWidget *gl_area = NULL;

/* The object we are drawing */
static const GLfloat vertex_data[] = {
  1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 
  1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 
  -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 
  1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 
  -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 
  -1.0, -1.0,-1.0, 0.0, -1.0, 0.0, 

  -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 
  1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 
  1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 
  -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 
  1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 
  -1.0, 1.0,-1.0, 0.0, 1.0, 0.0, 

  -1.0, -1.0,-1.0, -1.0, 0.0, 0.0, 
  -1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 
  -1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 
  -1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 
  -1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 
  -1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 

  -1.0, -1.0,1.0, 0.0, 0.0, 1.0, 
  1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 
  -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 
  1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 
  1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 
  -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 

  1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 
  1.0,-1.0, -1.0, 0.0, 0.0, -1.0, 
  -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 
  1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 
  -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 
  -1.0, 1.0, -1.0, 0.0, 0.0, -1.0,

  1.0, 1.0, 1.0,1.0, 0.0, 0.0, 
  1.0, -1.0, 1.0,1.0, 0.0, 0.0, 
  1.0, -1.0,-1.0,1.0, 0.0, 0.0, 
  1.0, 1.0, 1.0,1.0, 0.0, 0.0, 
  1.0, -1.0, -1.0,1.0, 0.0, 0.0, 
  1.0, 1.0, -1.0,1.0, 0.0, 0.0

};

long current_frame = 0.0;
long delta_time = 0.0;
GDateTime *last_frame;
int dt = 0;

static GLuint position_buffer;
static GLuint program;
static GLuint vao;

mat4 model = mat4(1.0);


/* Create and compile a shader */
static GLuint
create_shader (int  type)
{
  GLuint shader;
  int status;
  shader = glCreateShader (type);
  if (type== GL_FRAGMENT_SHADER){
    glShaderSource (shader, 1, &FRAGMENT_SOURCE, NULL);
  }
  if (type== GL_VERTEX_SHADER){
    glShaderSource (shader, 1, &VERTEX_SOURCE, NULL);
  }
  glCompileShader (shader);

  glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
  if (status == GL_FALSE)
  {
    int log_len;
    char *buffer;
    glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len);
    buffer = (char*)g_malloc (log_len + 1);
    glGetShaderInfoLog (shader, log_len, NULL, buffer);
    g_warning ("Compile failure in %s shader:\n%s",
               type == GL_VERTEX_SHADER ? "vertex" : "fragment",
               buffer);
    g_free (buffer);
    glDeleteShader (shader);
    return 0;
  }

  return shader;
}


/* We need to set up our state when we realize the GtkGLArea widget */
static void
realize (GtkWidget *widget)
{
  GdkGLContext *context;
  gtk_gl_area_make_current (GTK_GL_AREA (widget));
  if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL)
    return;
  context = gtk_gl_area_get_context (GTK_GL_AREA (widget));

  /* We only use one VAO, so we always keep it bound */
  glGenVertexArrays (1, &vao);
  glBindVertexArray (vao);

  /* This is the buffer that holds the vertices */
  glGenBuffers (1, &position_buffer);
  glBindBuffer (GL_ARRAY_BUFFER, position_buffer);
  glBufferData(GL_ARRAY_BUFFER,sizeof(vertex_data),vertex_data,GL_STATIC_DRAW);
  glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
  glEnableVertexAttribArray (0);
  glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
  glEnableVertexAttribArray (1);
  glBindBuffer (GL_ARRAY_BUFFER, 0);

  GLuint vertex, fragment;
  int status;
  vertex = create_shader (GL_VERTEX_SHADER);

  if (vertex == 0)
    {
      return;
    }

  fragment = create_shader (GL_FRAGMENT_SHADER);

  if (fragment == 0)
    {
      glDeleteShader (vertex);
      return;
    }

  program = glCreateProgram ();
  glAttachShader (program, vertex);
  glAttachShader (program, fragment);

  glLinkProgram (program);

  glGetProgramiv (program, GL_LINK_STATUS, &status);
  if (status == GL_FALSE)
  {
    int log_len;
    char *buffer;

    glGetProgramiv (program, GL_INFO_LOG_LENGTH, &log_len);

    buffer = (char*)g_malloc (log_len + 1);
    glGetProgramInfoLog (program, log_len, NULL, buffer);

    g_warning ("Linking failure:\n%s", buffer);

    g_free (buffer);

    glDeleteProgram (program);
    program = 0;

    glDeleteShader (vertex);
    glDeleteShader (fragment);

    return;
  }

  glDetachShader (program, vertex);
  glDetachShader (program, fragment);

  glEnable(GL_CULL_FACE);
  glFrontFace(GL_CCW);  
  glCullFace(GL_BACK);
  glEnable(GL_DEPTH_TEST);
}

/* We should tear down the state when unrealizing */
static void
unrealize (GtkWidget *widget)
{
  gtk_gl_area_make_current (GTK_GL_AREA (widget));

  if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL)
    return;

  glDeleteBuffers (1, &position_buffer);
  glDeleteProgram (program);
}

static void
draw_box (long delta_time)
{
  /* Use our shaders */
  glUseProgram (program);

  model = rotate(model, (float)delta_time/1000, vec3(1,1,0));
  glUniformMatrix4fv(glGetUniformLocation(program, "model"), 1, GL_FALSE, &model[0][0]);
  vec3 position = vec3(0,0,5);
  vec3 front = vec3(0,0,-1);
  vec3 up = vec3(0,1,0);
  mat4 view = lookAt(position, position + front, up);
  glUniformMatrix4fv(glGetUniformLocation(program, "view"), 1, GL_FALSE, &view[0][0]);
  mat4 projection = perspective(45.0, double(WIDTH)/double(HEIGHT), 0.1, 100.0);
  glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, &projection[0][0]);

  glBindVertexArray(vao);
  /* Use the vertices in our buffer */

  /* Draw the three vertices as a triangle */
  glDrawArrays (GL_TRIANGLES, 0, 36);

  /* We finished using the buffers and program */
  glBindVertexArray(0);
  glDisableVertexAttribArray (0);
  glBindBuffer (GL_ARRAY_BUFFER, 0);
  glUseProgram (0);
}

static gboolean
render (GtkGLArea    *area,
        GdkGLContext *context)
{
  GDateTime *date_time;

  date_time = g_date_time_new_now_local();  
  current_frame = g_date_time_get_microsecond(date_time);
  delta_time = g_date_time_difference(date_time, last_frame) / 1000;
  last_frame = date_time;

  if (gtk_gl_area_get_error (area) != NULL)
    return FALSE;

  /* Clear the viewport */
  glClearColor (0.0, 0.0, 0.0, 1.0);
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  /* Draw our object */
  draw_box (delta_time);
  /* Flush the contents of the pipeline */
  glFlush ();
  return TRUE;
}

static void
on_axis_value_change (void)
{
  gtk_widget_queue_draw (gl_area);
}

int main(int argc, char **argv)
{
  GtkWidget *window, *box;
  /* initialize gtk */
  gtk_init();
  /* Create new top level window. */
  window = gtk_window_new( );
  gtk_window_set_default_size (GTK_WINDOW(window),WIDTH,HEIGHT);
  gtk_window_set_title(GTK_WINDOW(window), "GL Area");
//  gtk_container_set_border_width(GTK_CONTAINER(window), 10);
//  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE);
//  g_object_set (box, "margin", 12, NULL);
//  gtk_box_set_spacing (GTK_BOX (box), 6);
//  gtk_container_add (GTK_CONTAINER (window), box);
//  gtk_window_set_child (GTK_WINDOW (window), box);

  GtkWidget * frame;
  frame = gtk_frame_new (NULL);
  gtk_window_set_child (GTK_WINDOW (window), frame);

  gl_area = gtk_gl_area_new ();
//  gtk_box_pack_start (GTK_BOX(box), gl_area,1,1, 0);
//  gtk_box_prepend (GTK_BOX(box), gl_area);
  /* We need to initialize and free GL resources, so we use
  * the realize and unrealize signals on the widget
  */
//  gtk_window_set_child (GTK_WINDOW (window), gl_area);
  gtk_frame_set_child (GTK_FRAME (frame), gl_area);

  g_signal_connect (gl_area, "realize", G_CALLBACK (realize), NULL);
  g_signal_connect (gl_area, "unrealize", G_CALLBACK (unrealize), NULL);

  /* The main "draw" call for GtkGLArea */
  g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL);
  /* Quit form main if got delete event */
//  g_signal_connect(G_OBJECT(window), "delete-event",
//                 G_CALLBACK(gtk_main_quit), NULL);

  gtk_widget_show(GTK_WIDGET(window));
//  gtk_main();
  int i = 0;
  while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
  {  g_main_context_iteration (NULL, TRUE);
     gtk_gl_area_queue_render (GTK_GL_AREA(gl_area)); // only if I queue render manually it renders.
	 if (!gtk_gl_area_get_auto_render(GTK_GL_AREA(gl_area)))
	   g_print("auto render not set\n");
	 else
	   printf("auto render set, %d %d\n", i++);
  }

  return 0;
}

ps: I also write another version whose output is

activated
rendering
auto_render is 1

(g:14727): GLib-CRITICAL **: 11:23:42.952: g_date_time_difference: assertion 'begin != NULL' failed

when it is launched, and then it outputs

rendering
auto_render is 1
rendering
auto_render is 1
rendering
auto_render is 1
rendering
auto_render is 1
rendering
auto_render is 1
...

only if I resize the window.

/* OpenGL Area
 *
 * GtkGLArea is a widget that allows custom drawing using OpenGL calls.
 */

// compiling with: g++ gl_draw_area.cpp `pkg-config --cflags gtk+-3.0` 
// \ `pkg-config --libs gtk+-3.0` -lepoxy

#include <string.h>
#include <stdio.h>
#include <math.h>
#include <gtk/gtk.h>
#include <epoxy/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <iostream>

unsigned int WIDTH = 800;
unsigned int HEIGHT = 600;

using glm::mat4;
using glm::vec3;
using glm::lookAt;
using glm::perspective;
using glm::rotate;

const GLchar  *VERTEX_SOURCE =
"#version 330\n"
"in vec3 position;\n"
"in vec3 normal;\n"
"out vec3 transformedNormal;\n"
"out vec3 originalNormal;\n"
"uniform mat4 projection;\n"
"uniform mat4 view;\n"
"uniform mat4 model;\n"
"void main(){\n"
"    gl_Position =  projection * view * model * vec4(position, 1.0);\n"
"    mat3 normalMatrix = transpose(inverse(mat3(view * model)));\n"
"    transformedNormal = normalMatrix * normal;\n"
"    originalNormal = abs(normal);\n"
"}\n";

const GLchar *FRAGMENT_SOURCE =
"#version 330\n"
"in vec3 transformedNormal;\n"
"in vec3 originalNormal;\n"
"out vec4 outputColor;\n"
"void main() {\n"
"vec3 color = originalNormal;\n"
"float lighting = abs(dot(transformedNormal, vec3(0,0,-1)));\n"
"outputColor = vec4(color * lighting, 1.0f);\n" //constant white
"}";

/* the GtkGLArea widget */
static GtkWidget *gl_area = NULL;

/* The object we are drawing */
static const GLfloat vertex_data[] = {
  1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 
  1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 
  -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 
  1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 
  -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 
  -1.0, -1.0,-1.0, 0.0, -1.0, 0.0, 

  -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 
  1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 
  1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 
  -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 
  1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 
  -1.0, 1.0,-1.0, 0.0, 1.0, 0.0, 

  -1.0, -1.0,-1.0, -1.0, 0.0, 0.0, 
  -1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 
  -1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 
  -1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 
  -1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 
  -1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 

  -1.0, -1.0,1.0, 0.0, 0.0, 1.0, 
  1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 
  -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 
  1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 
  1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 
  -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 

  1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 
  1.0,-1.0, -1.0, 0.0, 0.0, -1.0, 
  -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 
  1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 
  -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 
  -1.0, 1.0, -1.0, 0.0, 0.0, -1.0,

  1.0, 1.0, 1.0,1.0, 0.0, 0.0, 
  1.0, -1.0, 1.0,1.0, 0.0, 0.0, 
  1.0, -1.0,-1.0,1.0, 0.0, 0.0, 
  1.0, 1.0, 1.0,1.0, 0.0, 0.0, 
  1.0, -1.0, -1.0,1.0, 0.0, 0.0, 
  1.0, 1.0, -1.0,1.0, 0.0, 0.0

};

long current_frame = 0.0;
long delta_time = 0.0;
GDateTime *last_frame;
int dt = 0;

static GLuint position_buffer;
static GLuint program;
static GLuint vao;

mat4 model = mat4(1.0);


/* Create and compile a shader */
static GLuint
create_shader (int  type)
{
  GLuint shader;
  int status;
  shader = glCreateShader (type);
  if (type== GL_FRAGMENT_SHADER){
    glShaderSource (shader, 1, &FRAGMENT_SOURCE, NULL);
  }
  if (type== GL_VERTEX_SHADER){
    glShaderSource (shader, 1, &VERTEX_SOURCE, NULL);
  }
  glCompileShader (shader);

  glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
  if (status == GL_FALSE)
  {
    int log_len;
    char *buffer;
    glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len);
    buffer = (char*)g_malloc (log_len + 1);
    glGetShaderInfoLog (shader, log_len, NULL, buffer);
    g_warning ("Compile failure in %s shader:\n%s",
               type == GL_VERTEX_SHADER ? "vertex" : "fragment",
               buffer);
    g_free (buffer);
    glDeleteShader (shader);
    return 0;
  }

  return shader;
}


/* We need to set up our state when we realize the GtkGLArea widget */
static void
realize (GtkWidget *widget)
{
  GdkGLContext *context;
  gtk_gl_area_make_current (GTK_GL_AREA (widget));
  if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL)
    return;
  context = gtk_gl_area_get_context (GTK_GL_AREA (widget));

  /* We only use one VAO, so we always keep it bound */
  glGenVertexArrays (1, &vao);
  glBindVertexArray (vao);

  /* This is the buffer that holds the vertices */
  glGenBuffers (1, &position_buffer);
  glBindBuffer (GL_ARRAY_BUFFER, position_buffer);
  glBufferData(GL_ARRAY_BUFFER,sizeof(vertex_data),vertex_data,GL_STATIC_DRAW);
  glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
  glEnableVertexAttribArray (0);
  glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
  glEnableVertexAttribArray (1);
  glBindBuffer (GL_ARRAY_BUFFER, 0);

  GLuint vertex, fragment;
  int status;
  vertex = create_shader (GL_VERTEX_SHADER);

  if (vertex == 0)
    {
      return;
    }

  fragment = create_shader (GL_FRAGMENT_SHADER);

  if (fragment == 0)
    {
      glDeleteShader (vertex);
      return;
    }

  program = glCreateProgram ();
  glAttachShader (program, vertex);
  glAttachShader (program, fragment);

  glLinkProgram (program);

  glGetProgramiv (program, GL_LINK_STATUS, &status);
  if (status == GL_FALSE)
  {
    int log_len;
    char *buffer;

    glGetProgramiv (program, GL_INFO_LOG_LENGTH, &log_len);

    buffer = (char*)g_malloc (log_len + 1);
    glGetProgramInfoLog (program, log_len, NULL, buffer);

    g_warning ("Linking failure:\n%s", buffer);

    g_free (buffer);

    glDeleteProgram (program);
    program = 0;

    glDeleteShader (vertex);
    glDeleteShader (fragment);

    return;
  }

  glDetachShader (program, vertex);
  glDetachShader (program, fragment);

  glEnable(GL_CULL_FACE);
  glFrontFace(GL_CCW);  
  glCullFace(GL_BACK);
  glEnable(GL_DEPTH_TEST);

  gtk_gl_area_set_auto_render (GTK_GL_AREA (widget), GL_TRUE);
}

static void
draw_box (long delta_time)
{
  /* Use our shaders */
  glUseProgram (program);

  model = rotate(model, (float)delta_time/1000, vec3(1,1,0));
  glUniformMatrix4fv(glGetUniformLocation(program, "model"), 1, GL_FALSE, &model[0][0]);
  vec3 position = vec3(0,0,5);
  vec3 front = vec3(0,0,-1);
  vec3 up = vec3(0,1,0);
  mat4 view = lookAt(position, position + front, up);
  glUniformMatrix4fv(glGetUniformLocation(program, "view"), 1, GL_FALSE, &view[0][0]);
  mat4 projection = perspective(45.0, double(WIDTH)/double(HEIGHT), 0.1, 100.0);
  glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, &projection[0][0]);

  glBindVertexArray(vao);
  /* Use the vertices in our buffer */

  /* Draw the three vertices as a triangle */
  glDrawArrays (GL_TRIANGLES, 0, 36);

  /* We finished using the buffers and program */
  glBindVertexArray(0);
  glDisableVertexAttribArray (0);
  glBindBuffer (GL_ARRAY_BUFFER, 0);
  glUseProgram (0);
}

static gboolean
render (GtkGLArea    *area,
        GdkGLContext *context,
		gpointer user_data)
{
  g_print("rendering\n");
  printf("auto_render is %d\n", (int)gtk_gl_area_get_auto_render (area));

  GDateTime *date_time;

  date_time = g_date_time_new_now_local();  
  current_frame = g_date_time_get_microsecond(date_time);
  delta_time = g_date_time_difference(date_time, last_frame) / 1000;
  last_frame = date_time;

  if (gtk_gl_area_get_error (area) != NULL)
  {
    printf("error\n");
    return FALSE;
  }

  glClearColor (0.0, 0.0, 0.0, 1.0);
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  draw_box (delta_time);

  glFlush ();
//  gtk_gl_area_queue_render (GTK_GL_AREA(gl_area));
  return TRUE;
}

static void
on_axis_value_change (void)
{
  gtk_widget_queue_draw (gl_area);
}


static void
activate (GtkApplication * app, gpointer user_data)
{
  GtkWidget * window;
  GtkWidget * box;

  window = gtk_application_window_new (app);
  gtk_window_set_title(GTK_WINDOW(window), "GL Area");
  gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
  
  gl_area = gtk_gl_area_new ();
  gtk_window_set_child (GTK_WINDOW (window), gl_area);

  g_signal_connect (gl_area, "realize", G_CALLBACK (realize), NULL);

  g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL);
  gtk_gl_area_set_auto_render (GTK_GL_AREA (gl_area), GL_TRUE);
 
  gtk_window_present (GTK_WINDOW (window));
  g_print("activated\n");
}
  


int main (int argc, char ** argv)
{
  GtkApplication * app;
  int status;
  app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);

  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}
1 Like

Hello, for animations you will want to use gtk_widget_add_tick_callback on the area, and then use queue_render inside the callback. That will force the area to redraw every frame.

The auto_render = 1 only means the area will emit a render signal every time the widget is supposed to redraw. Without any other mechanism like the tick callback, gtk widgets only redraw when they need to, such as when the layout changes and the widget needs to be resized, or if the css changes, etc. And that is what auto_render controls in relation to the GL content, if you set it to 0 then you would also have to detect those cases manually and call queue_render in more situations.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.