Gtk_widget_measure cached results

Gtk 4.10.4


GIF

a

layout

MyFlowBox   GTK_ORIENTATION_HORIZONTAL
  - MyChild ::wfh GTK_ORIENTATION_VERTICAL

I need to record the sum of the heights of the children when flowbox distributes the width to a fixed number of children in an even manner

So when I measure the child’s height, I pass the child’s width value as for_size to measure

But measure always returns the same value. Because the result is cached.

During the investigation, I found the key code

I currently don’t understand what this code means

    if (cur->lower_for_size <= for_size &&
		  cur->upper_for_size >= for_size)

I don’t know how to fix it.

I tried calling gtk_widget_queue_allocate before the measure child, but it didn’t work

I’m not quite sure about the logic of GtkSizeRequestMode .

My understanding is as follows:
width-for-height: Indicates that the height will also change when the width changes, that is, the width will not be affected when the height changes
height-for-width: Indicates that the width will also change when the height changes, that is, the height will not be affected when the width changes

Can anyone describe it in more words?

Hi! The way I understand it is:

  • width for height: GTK gives you the height of your control and you tell GTK what width the control needs
  • height for width: same, but GTK gives you a width and you tell GTK the required height

For example, suppose your control shows an image but must retain the aspect ratio, say height = 5/4 width. Here’s how you could implement the measure vfunc:

static void
my_control_measure (GtkWidget *widget,
                    GtkOrientation orientation,
                    int for_size,
                    int *minimum,
                    int *natural,
                    int *minimum_baseline,
                    int *natural_baseline)
{
  switch (orientation)
    {
    case GTK_ORIENTATION_HORIZONTAL:
      /* Width for height: GTK has given us a height (reported
       * in for_size), let's determine an appropriate minimum /
       * natural width
       */
      *natural = *minimum = for_size * 0.8;
      break;
    case GTK_ORIENTATION_VERTICAL:
      /* Height for width: GTK has given us a width (reported
       * in for_size), let's determine an appropriate minimum /
       * natural height
       */
      *natural = *minimum = for_size * 1.25;
      break;
    }
}
1 Like

thank you for the explanation.

What I get is the opposite result.

Have you considered using a layout manager like GtkBoxLayout? With that you don’t have to implement measure yourself. See Custom widgets in GTK 4 – Layout – GTK Development Blog

I need more possibilities, so I need to create layout

I found the problem, the reason is that the understanding of for_size is not deep

This is my first attempt at thinking about for_size layouts.

It’s a simple question of logic

static void lx_list_info_card_measure( GtkWidget*     widget,
                                       GtkOrientation orientation,
                                       int            for_size,
                                       int*           minimum,
                                       int*           natural,
                                       int*           minimum_baseline,
                                       int*           natural_baseline )
{
	_SELF( widget );

	int min = 0, nat = 0;

	if ( for_size > 0 ) {  // important !!!
		min = for_size;
		nat = for_size;
	}
	else {
		gtk_widget_measure( self->main_child, orientation, -1, &min, &nat, NULL, NULL );
        for_size = min;
	}

	lx_widget_measure_opt( GTK_ORIENTATION_VERTICAL, orientation, minimum, *minimum, min );
	lx_widget_measure_opt( GTK_ORIENTATION_VERTICAL, orientation, natural, *natural, nat );

	int mmin = min, mnat = nat;

	if ( orientation == GTK_ORIENTATION_HORIZONTAL )
		return;

	gtk_widget_measure( self->label_child, orientation, for_size, &min, &nat, NULL, NULL );
	lx_widget_measure_opt( GTK_ORIENTATION_VERTICAL, orientation, minimum, *minimum, min );
	lx_widget_measure_opt( GTK_ORIENTATION_VERTICAL, orientation, natural, *natural, nat );
}

When I measure the size of the child control, for_size is provided, but the child control doesn’t use it. causing it to use its own size every time. However for_size can be larger than its own size.

The result looks like it was cached. I saw the cache when I was troubleshooting, so I thought it was the result of the cache.

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