Calling layout_changed() from inside .allocate()

Is it safe to call gtk_layout_manager_layout_changed() from inside the .allocate() function of a layout manager?

In my tests it works like a charm, but my concern is whether it could theoretically create infinite loops.

―madmurpy

No, it’s not safe—it has the same restrictions as calling gtk_widget_queue_resize() inside a GtkWidget.size_allocate() implementation, because it effectively is.

It will definitely create a loop; if the size allocated is the same, the loop will break, and if the loop doesn’t break after 4 cycles, GTK will automatically bail out.

What it leads to is unstable layouts, or constant redrawing; it will make rendering not hit the next frame target, and will make animations and redraws slower and janky.

Hi Emmanuele,

Thank you for your answer. The problem is that GTK does not call .measure() if you try to downsize my widget below its natural allocation, as you can see in this screencast:

without-allocate

(Therefore the mouse cursor is allowed to go where it shouldn’t)

What I do is basically trying to solve this problem. As you can see from this other screencast calling gtk_layout_manager_layout_changed() seems to solve the problem:

with-allocate

All this is related to this bug that I opened in GTK. Differently from what I explain there, in the last screencast the invocation of gtk_layout_manager_layout_changed() inside .allocate() happens only under a specific condition. To be precise, I have replaced what there was

priv->allocated_fix_size = occupied.fix_size;
gtk_layout_manager_layout_changed(manager);

with

if (priv->allocated_fix_size != occupied.fix_size) {

	priv->allocated_fix_size = occupied.fix_size;
	gtk_layout_manager_layout_changed(manager);

}

Is this is not allowed I am out of solutions and I will need help to find one.

EDIT: To find a possible alternative, how can I force GTK to call .measure() after .allocate()?

―madmurphy

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