When is size allocated for a widget

Hi, I am a bit confused about how widgets are drawn, more specifically, when is a size allocation made and assigned to a widget.

For example, I have the following widget tree:

GtkNotebook
   +-> GtkPaned
         +-> GtkScrolledWindow
         +-> GtkNotebook

What I would like to be able to do is set the GtkPaned separator to a specific value when adding it as a child of the GtkNotebook. In order to do that, I use the following sequence of calls:

gtk_notebook_append_page(notebook, paned, "New Page");
gtk_widget_show_all(notebook);
gtk_widget_get_allocation(paned, &allocation);
gtk_paned_set_position(paned, allocation.height - allocation.height * SPLIT);

However, what I am seeing is that the values in allocation for height and width are 1 instead of something reasonable.

One other detail is that the parent of the top level GtkNotebook and its parent are shown/visible, as well.

I thought that if all of the widgets in the tree are visible, the page child widget would have had an allocation assigned to it. Is that not true?

Thank you.

No, it’s not true.

Widgets are allocated within the frame cycle, so you cannot just build your scene graph and assume everything will be valid. That’s why we have signals and properties to let you know when values are set.

Widgets need to be realized and mapped, in order to have an allocation; just toggling the visibility flag isn’t enough. This means that a widget needs to have a top-level associated to it, as the allocation flows from the top level down to the leaf widgets; additionally, an allocation can only be derived by querying the preferred size of each widget in the graph.

In practice, a widget will only ever have a valid allocation when the GtkWidget::size-allocate signal is emitted, or when the widget is drawn.

Thank you for the reply and explanation.

So, to clarify, the correct way to do what I am after is to connect the page child widget’s size-allocate signal to a handler, which will set the GtkPaned separator position and then just disconnect the signal?

The appropriate way would be to wait until the size-allocate, then schedule an idle callback to set the separator position in the GtkPaned. Setting the separator position will queue a relayout, and than cannot happen from within the size allocation. You need to re-enter the main loop to avoid layout cycles.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.