How to get content height of ScrolledWindow?

What I’m trying to do is to shrink the one of descendants of ScrolledWindow, so that the “Result” can be visible (as much as possible). I want to know the full height of the ScrolledWindow content, but haven’t figured out how. Tried various get_allocated_height(), get_preferred_height(), get_page_size() but all seems to be the visible height, not the full height.

I think you want to get the size of the child of the GtkViewport. The hierarchy likely looks like this:

  • GtkScrolledWindow
    • GtkViewport
      • content ← this is what you want to measure

Yes. Under Viewport is a Flowbox. I want to get its full size, but get_allocated_height() only returns the height of visible part.

Could it be that your content is not resizing and the full size is the same? Maybe you want to compare to this simple Javascript example. If you resize the window vertically and then click any of the buttons, it should print the same height for the content each time:

imports.gi.versions.Gtk = '4.0';
const Gtk = imports.gi.Gtk;

let app = new Gtk.Application({ application_id: 'org.test.Test' });

app.connect('activate', () => {
    let win = new Gtk.ApplicationWindow({ application: app });
    let scroller = new Gtk.ScrolledWindow({});
    let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
    for (let i = 0; i < 20; i++) {
      let btn = new Gtk.Button({ label: 'Print Content Size' });
      btn.connect('clicked', () => {
        const content = scroller.get_child().get_child();
        const w = content.get_allocated_width();
        const h = content.get_allocated_height();
        print(`${w}, ${h}`);
      });
      box.append(btn);
    }
    scroller.set_child(box);
    win.set_child(scroller);
    win.present();
});

app.run([]);

It is scrolled. This the lower part.

Here is the code I tried to print heights:

def shrink_preview_to_fit_screen(self):
	wh = self.main_scrolled_window.get_allocated_height()
	logger.debug('Scrolled window height: {}', wh)
	viewport = self.main_scrolled_window.get_child()
	logger.debug('Viewport height: {}', viewport.get_allocated_height())
	logger.debug('Viewport gdk window height: {}', viewport.get_view_window().get_height())
	flowbox = viewport.get_child()
	logger.debug('Flowbox height: {}', flowbox.get_allocated_height())
	logger.debug('Flowbox prefered height: {}', flowbox.get_preferred_height())
	adj = self.main_scrolled_window.get_vadjustment()
	logger.debug('Page size: {}', adj.get_page_size())
	logger.debug('Lower: {}', adj.get_lower())
	logger.debug('Upper: {}', adj.get_upper())
	logger.debug('Value: {}', adj.get_value())
	adj.set_value(adj.get_upper())
	logger.debug('Value: {}', adj.get_value())

and the log output:

(__main__.py:795): cobang-DEBUG: 16:41:29.420: Scrolled window height: 601
(__main__.py:795): cobang-DEBUG: 16:41:29.420: Viewport height: 599
(__main__.py:795): cobang-DEBUG: 16:41:29.421: Viewport gdk window height: 599
(__main__.py:795): cobang-DEBUG: 16:41:29.421: Flowbox height: 599
(__main__.py:795): cobang-DEBUG: 16:41:29.422: Flowbox prefered height: (minimum_height=757, natural_height=757)
(__main__.py:795): cobang-DEBUG: 16:41:29.422: Page size: 599.0
(__main__.py:795): cobang-DEBUG: 16:41:29.423: Lower: 0.0
(__main__.py:795): cobang-DEBUG: 16:41:29.423: Upper: 599.0
(__main__.py:795): cobang-DEBUG: 16:41:29.423: Value: 0.0
(__main__.py:795): cobang-DEBUG: 16:41:29.423: Value: 0.0

Oh, I’ve just noticed that if I manually scroll down (by mouse, not programmatically) to the bottom, the allocated_height seems to be the full height:

(__main__.py:870): cobang-DEBUG: 16:44:07.882: Scrolled window height: 601
(__main__.py:870): cobang-DEBUG: 16:44:07.882: Viewport height: 599
(__main__.py:870): cobang-DEBUG: 16:44:07.883: Viewport gdk window height: 599
(__main__.py:870): cobang-DEBUG: 16:44:07.883: Flowbox height: 757
(__main__.py:870): cobang-DEBUG: 16:44:07.884: Flowbox prefered height: (minimum_height=757, natural_height=757)
(__main__.py:870): cobang-DEBUG: 16:44:07.884: Page size: 599.0
(__main__.py:870): cobang-DEBUG: 16:44:07.885: Lower: 0.0
(__main__.py:870): cobang-DEBUG: 16:44:07.885: Upper: 757.0
(__main__.py:870): cobang-DEBUG: 16:44:07.885: Value: 158.0
(__main__.py:870): cobang-DEBUG: 16:44:07.886: Value: 158.0

Ohh, this time trying, I notice that the result of get_preferred_height() is bigger than get_allocated_height() and seems to be the full size. Last time I tested, they are the same. Weird. But this is the result I expect.

– Update 1 –

After testing again and again, I can confirm that if the scrolled window is not scrolled down, the content’s get_preferred_height() just return the same value as get_preferred_height() and is the height of visible part. :cry:

– Update 2 —

Actually. how get_preferred_height() yield is also dependent on other elements in the tree. The unexpected result appears when I test this image:

The difference is that, this case the Result pane have a text view opened.

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