GTK’s main layout component is the GtkGrid widget, which roughly corresponds to CSS grids & flexboxes (for the latter Gtk used to have GtkBox, but they found GtkGrid filled the need). And I got a fair bit of interest when a mentioned this the other day.
Odysseus uses it as well, to:
- Group headerbar items, especially the addressbar.
- Layout popovers and autocompletion entries.
- Position the the infobars and the download bar around the WebView
- Layout download info.
To compute it’s size along a single dimension, GtkGrid figures out how many lines it has (a simple MAX() operation) and allocates an array for it, marking any lines to be expanded.
Then it uses dynamically-dispatched recursion and a MAX() operation to compute the size minimum and natural size for each line, before computing the alignment for each widget.
Then it considers widgets spanning multiple lines, with multiple formulas to expand line sizes if needed.
Before and after handling the multi-line widgets, GtkGrid may optionally apply another MAX() operation to ensure all lines are the same size.
From there it computes a count of how many nonempty lines there are and how much whitespace to add, before summing it up with the column sizes.
Once that size is computed any extra space is distributed between the lines, before computing sizes for the other dimension.
The rest of GtkGrid is pretty unremarkable.
Once the size is finalized, information is looked in those arrays to be forwarded to it’s children. For it’s parent class to render via dynamically-dispatched recursion.
And all these children are stored in a linked list alongside their column and row numbers.