Custom signal for scrollable content


Hello everybody ! I’ve already asked for help about this specific problem of mine, but didn’t have any help that suited me, so I ask again, but I try to explain may issue more accurately.
The situation is the following : I have a widget in a scrolled-window, and its content is too big for being entirely displayed in the window,
when the window is resized both in height and width at the same time or separately and the content of the widget is entirely displayed (In my case a TextView), I need to trigger a signal.
The fact is that it is exactly the behavior of the visibility of the scrollbar in a scrolled-window. Anyone can point me to the section of GTK code that handle this behavior ? Thanks !

Well, I do not know an easy way to do what you want. You could try the following approach. Connect to the “size-allocate” signal of the GtkTextView instance. The event handler can look like this (GTK3):

void updatescrollbar(GtkWidget *widget, GdkRectangle *rect, gpointer data)
    GtkAdjustment *just = (GtkAdjustment *)gtk_range_get_adjustment((GtkRange *)gtk_scrolled_window_get_vscrollbar((GtkScrolledWindow *)scrollwin));
    double pagesize = gtk_adjustment_get_page_size(just); // == rect->height
    double maxpos = gtk_adjustment_get_upper(just);

    // compare pagesize and maxpos and do the necessary tasks depending on the result of the comparison

    if(pagesize < maxpos) printf("Scrollbar is visible\n");
    else  printf("Scrollbar is hidden\n");

scrollwin is the scrolled window that contains the instance of GtkTextView. You can use a static variable that saves the last comparison in order to report the change in the state only.

1 Like

I’ll try that, might be what I need, I’ll try and let you know ! Thanks for your help !

Hi, unfortunately, I’m using GTK4 and there is no size-allocate signal. I searched the GTK3 doc too, and it seems that it doesn’t exist there too. Maybe you’ve mistaken size-allocate for another signal ?

1 Like

Oh ! It seems that I’ve not searched well, but I can’t find it for GTK4, unfortunately. But I think I can do the same thing if I bind the TextView property width-request and height-request and use notify.

Notifying on width-request and height-request will not work, those are for you to set if you want to override the size to a fixed value.

GTK4 does not have a signal for this because it is hard to use correctly, and plus signals pass through an FFI boundary and that makes them slow. To do what you want you will have to make a custom widget and override the size_allocate vfunc. Or see here for some other suggestions: Adapt to GtkWidget’s size allocation changes

1 Like

Hi @jfrancis, thanks for your reply ! Indeed, that’s what I was trying to do : “Make a custom widget that override the size_allocate vfunc”, but I faced two problems, the first was that the vfunc size_allocate was called only if the window was resized horizontally and the second was that someone told me that the way I was using my custom widget to override size_allocate was “a terrible idea”.
The situation was the following : I wanted to do an end-user license agreement like, so what I did was, create a GtkTextView, that I putted in a MyCustomWidget (the one I overrode the size_allocate vfunc) and then, put the whole in a GtkScrolledWindow. The thing is that I’ve no clue on how to do it differently, if you have an idea I would be glad to here it ! Thanks for your help.

It could be a bad idea, why do you need custom sizing for that? Overriding size_allocate should only be done if you are implementing a custom layout or a widget with custom drawing. If all you are doing is trying to size a TextView, consider just putting it in a layout, or changing the scrollbar policy properties on the ScrolledWindow.

As someone who has written extensive amounts of GtkTextView related code, and maintained it, GtkSourceView, and a number of text editors on it for some time, I do think trying to solve it this way is a, quote, “terrible idea”.

The reason for that is that GtkTextView is aimed at trying to snapshot only the visible regions. If you put it and another widget in box in a sourceview, you take away it’s ability to do proper layout and snapshotting. At that point, you might as well use a giant GtkLabel.

I would suggest one of two options:

  1. Put your accept/cancel buttons in the GtkTextView using gtk_text_buffer_create_child_anchor() and gtk_text_view_add_child_at_anchor().


  1. Use an overlay with the main child a GtkScrolledWindow containing your GtkTextView and the buttons as an overlay near the bottom. Add enough space to the bottom of your textview by setting the bottom-margin property. Only make the buttons sensitive when the vadjustment of the scrolledwindow >= (upper - page_size).

A simpler option may be to just use a normal dialog, do set_sensitive(FALSE) on the ok button and then monitor the scrollbar adjustment for reaching the bottom…

That is already what I’m doing, it works well when there is a scrollbar and the window is too tiny to display the whole content, then yes I can scroll-down and my “Ok” button become sensitive. But if instead I choose to resize the window, vertically, horizontally or if I click the “full-screen” button of the window, then all the content is displayed but my “Ok” button is still not sensitive.

Thanks, indeed your solutions 1 or 2 are acceptable to me !

I tried your solution 2, it was the one that rendered the closest to what I was expecting. The issue is that when everything gets calculated, when I first run the app, the upper value has exactly the same value as page_size. So it validates automatically the condition and the OK button is set sensitive directly. Any Idea on how to overcome this issue ? I tried setting a GtkAdjustment in my .ui file, assigning a value of 999999 for upper, but it didn’t change. Maybe I’ll only have the option one left. Thanks for your help.

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