I want to draw with cairo, but not within a draw event. According to the docs, I should be able to ust gtk_cairo_create from a widget, say, in response to a mouse event. But I can't get this to work. Here is the code that I have, but the draw from the GtkButtonPressEvent does not display anything. It should draw a redish horizontal line that works its way down the page on each draw event.

/ gtk3 test
// build command# g++ -o gtk3 gtk3.cpp `pkg-config --libs --cflags gtk+-3.0`

#include <gtk/gtk.h>

unsigned y = 20;

void draw (cairo_t* cairo) {

printf ("draw cairo\n");
::cairo_set_source_rgb (cairo, 1, 0.5, 0);
::cairo_move_to (cairo, 0, y);
::cairo_line_to (cairo, 1000, y);
::cairo_stroke (cairo);
y += 20;

void draw (GtkWidget* widget) {

GdkWindow* w = gtk_widget_get_window (widget);
cairo_t* cr = gdk_cairo_create (w);
draw (cr);
cairo_destroy (cr);

gboolean gtk_draw_event (GtkWidget* widget, cairo_t* cairo, gpointer data) {

//draw (cairo); // draws fine
return false;

gboolean GtkButtonPressEvent (GtkWidget* widget, GdkEventButton* event, gpointer) {

draw (widget); // does not draw
return true;

int main (int argc, char *argv []) {

gtk_init (&argc, &argv);

GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "gtk3 test");
gtk_window_set_default_size (GTK_WINDOW (window), 1000, 800);
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

GtkWidget* layout = gtk_layout_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), layout);

g_signal_connect (layout, "draw", G_CALLBACK (gtk_draw_event), NULL);
g_signal_connect (G_OBJECT (layout), "button_press_event",
G_CALLBACK (GtkButtonPressEvent), NULL);
gtk_widget_add_events (layout, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);

gtk_widget_show_all (window);
gtk_main ();