During the Paint phase GTK receives a single “render”
signal on the toplevel surface. The signal handler will create a
snapshot object (which is a helper for creating a scene graph) and
call the GtkWidget::snapshot()
vfunc, which will propagate down
the widget hierarchy. This lets each widget snapshot its content
at the right place and time, correctly handling things like
partial transparencies and overlapping widgets.
During the snapshotting of each widget, GTK automatically handles the CSS rendering according to the CSS box model. It snapshots first the background, then the border, then the widget content itself, and finally the outline.
To avoid excessive work when generating scene graphs, GTK caches
render nodes. Each widget keeps a reference to its render node
(which in turn, will refer to the render nodes of children, and
grandchildren, and so on), and will reuse that node during the
Paint phase. Invalidating a widget (by calling
gtk_widget_queue_draw()
) discards the cached render node, forcing
the widget to regenerate it the next time it needs to produce a
snapshot.