0
votes

The Gtk+ 3 migration guide shows how the GdkEventExpose.region field can be used to provide a fine-grained area for re-rendering widgets. We already do something like this in Inkscape to avoid rendering excessive amounts of complicated stuff on our drawing canvas.

However, the example in the guide shows how to do this for the old Gtk+ 2 expose_event handler.

How do I do the equivalent in a new Gtk+ 3 draw handler, which receives a "ready-clipped" Cairo context as a parameter, rather than a GdkEventExpose?

I guess one possibility is to use cairo_copy_clip_rectangle_list on the "ready-clipped" cairo context to obtain a list of rectangles that make up the region to draw. Does anyone have any experience of using this? Does it seem like a sensible approach?

2

2 Answers

1
votes

Yes, you should use cairo_copy_clip_rectangle_list() on the cairo_t that you get in your widget's ::draw() signal handler. See this commit for an example: http://git.gnome.org/browse/vte/commit/?id=21a064ac8b5925108b0ab9bd6516664c8cd3e268

0
votes

Since I have not much clue, I decided to check the source code. GDK emits a GDK_EXPOSE event on a window and creates the GdkEventExpose instance for this.

This event is then handled in gtk/gtkmain.c via gtk_widget_send_expose():

http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?id=eecb9607a5c0ee38eadb446545beccd0922cb0b8#n6104

This function clips the cairo_t to GdkEventExpose.region, as you already learned in the docs.

This then calls _gtk_widget_draw_internal() which emits the actual draw signal:

http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?id=eecb9607a5c0ee38eadb446545beccd0922cb0b8#n5726

As far as I can see, nothing here let's you access the clip region directly. In gtk_widget_send_expose() the GdkEvent is added as userdata to the cairo context. However, this is not accessible, because all the involved functions and variables are static. So you'll have to use cairo_copy_clip_rectangle_list().

However, this sounds quite inefficent. First gdk_cairo_region transforms the region into a number of calls to cairo_rectangle and then cairo transforms this from its internal representation into a cairo_rectangle_list_t (which may fail if the clip is, for some reason, not a region). If you see this being slow, it might make sense to have some shortcut for this added to gtk directly.