Increasing vertical height to scrolled text window in Gtk3

I am building a Gtk3 application running under Rocky Linux 9 and the Mate desktop. I have a GtkTextView wrapped in a GtkScrolledWindow using GtkContainerAdd to have scroll bars. It seems the GtkTextView defaults to a size of roughly 5 lines high and adding additional content results in the vertical scroll bar appearing which is great. The horizontal scroll bar also appears correct.

However, if I would like to increase the default height of this scrolled window, how do I do that? I have searched but not found the solution.

Thanks.

Hi,

You can call gtk_widget_set_size_request(scrolledwindow, -1, 100) to give a minimal height (100px in this example).

Or apply a CSS class with the min-height property.

Thank you, that works great! However, I would rather set the height to number of lines with the font size used - is there a gtk function call where I can retrieve the height of the font used?

With the CSS method, you can use font units like “em” instead of pixels. Looks like a single line height is around 1.70em. But that only works if the scrolledwindow and the textview use the same font.

Or programmatically, use Pango APIs to measure a text layout. Here an example in Python:

layout = Pango.Layout.new(textview.get_pango_context())
layout.set_text("M\nM\nM\nM\nM")
h = layout.get_size().height
scrolledwindow.set_size_request(-1, h)

I tried to get the height of a /text entry field/ (since it sizes itself for one line in height), multiply by e.g. 8 to hopefully then set the scrolled window to 8 lines. It did not work because gtk_widget_get_size_request(entry, &width, & height) returned -1.

However, my call above might not be the right one to get the height of a field?

No, it’s not a good thing to do.
First, the GtkEntry is not just text, but it also has margins/padding/borders, so will be much bigger than the actual text.
Then, gtk_widget_get_size_request is not suitable for measuring a widget size. It will return the minimum requested height, which is always -1 unless the application explicitly requested a minimal size with gtk_widget_set_size_request. You shall use gtk_widget_get_height instead for that purpose.

Have you tried the Pango example?

I tried it but there must be something missing. My code is:
PangoLayout *layout = pango_layout_new(gtk_widget_get_pango_context((GTK_WIDGET(text_view_10))));
int w, h;
pango_layout_set_text(layout, “M\nM\nM\nM\nM”, -1);
pango_layout_get_size(layout, &w, &h);
gtk_widget_set_size_request(class_use_scroller, -1, h);

I thus expected the height of class_use_scroller to be five lines high but instead it is higher than the size of my monitor height. Looking at the docs, it seems pango_layout_get_size() returns the height in PANGO_UNITS, not in pixels which is what gtk_widget_set_size_request() expects. From the docs, it seems that PANGO_UNITS is currently hardcoded to 1024 suggesting I could just divide it by 1024 but that did not work.

What have I missed?

Ah yes indeed, you need something like:

gtk_widget_set_size_request(class_use_scroller, -1, PANGO_PIXELS (h));

Do you mean the scrolled window was still too high? Or too small?

If too small, make sure gtk_init() was called before trying to measure the Pango size. If you use a GtkApplication to manage the init (recommended), it means not before startup.

Great, that works, thank you! One last question: it seems I do need to specify the number of lines desired by using:
pango_layout_set_text(layout, “M\nM\nM\nM\nM\nM\nM”, -1);
separate from setting the default text itself in the scroller window (the number lines of the default text may vary)?

Yes, the pango layout text is independent of the textview one. It’s just used “offline” for the measurement.

When setting a default text to a GtkTextView, its size is not immediately computed (it’s done in a background processing), so it’s not possible to e.g. measure the textview height at init for sizing the scrolledwindow accordingly. On the other side, the pango layout will immediately measure its text, so can be used at init.

If the number of lines varies, then maybe just measure a single “M” and multiply by the number of lines. Or feed the pango layout with the real initial text.

Understood, thank you again for your help!

1 Like