Container secrets

I recently spent some time tracking down a problem with GTK+ containers and drawing. Here is what I found out.

CSS drawing

In GTK+ 3.22, most, if not all, containers support the full CSS drawing model with multiple layers of backgrounds and borders. This is how, for example, GtkFrame draws its frame nowadays. But also containers that normally only arrange their children, such as GtkBox, can draw backgrounds and borders. The possibilities are endless!

For example, we can use a GtkBox to put a frame around a list box and a label, to make the label visually appear as part of the list. You can even make it colorful and fun, using some CSS like:

box.frame {
 border: 5px solid magenta;
}

Allocation and resizing

Traditionally, most containers in GTK+ are not doing any drawing of their own and just arrange their children, and thus there is no real need for them to do a full redraw when their size changes – it is enough to redraw the children. This is what gtk_container_set_reallocate_redraws() is about. And it defaults to FALSE in GTK+ 3, since we did not want to risk adding excessive redraws  whenever allocations change.

You can see where this is going: If I use the delete button to remove Butter and Salt from the list of ingredients, the allocation of the list, and thus of the box around it, will shrink, and we get a redraw problem.

The solution

If you plan to make plain layout containers draw backgrounds or borders, make sure to set reallocate-redraws to TRUE for the right widgets (in this case, the parent of the fun box).

gtk_container_reallocate_redraws (GTK_CONTAINER (parent), TRUE);

Note that gtk_container_reallocate_redraws() is deprecated in GTK+ 3.22, since we will get rid of it in GTK+ 4 and do the right thing automatically. But that shouldn’t stop you from using it to fix this issue.

Another (and maybe better) alternative is to use a container that is meant to draw a border, such as GtkFrame.

2 thoughts on “Container secrets”

  1. Hm interesting, this is a case where the function maybe should not be deprecated even if it is going away, since your app can’t do the right thing without it. And since porting to GTK+ 4 is a simple matter of just removing the function call, the value of having the deprecation in GTK+ 3 is a lot lower.

  2. My general take on that is that deprecations are only useful if you are planning to port to the next major version. Unless that is the case, you are best off ignoring them

Comments are closed.