Lazy scrollable list


I currently have a ListBox, however I’m adding in the range of 1000 widgets inside and I’m filtering them. The listbox takes ~500ms to get populated the first time (and the GUI is frozen for that time), and memory use is quite high. Filtering then is fast enough though. I’m aware that ListBox is not the right widget if I want to have many items in the list. I’ve discarded this solution for my use-case due to the performance.

What I do want is something like a listbox… Each entry will contain an icon, formatted text, a button on which you can click that opens a popover, and there are several different row types mixed together in the same list (which is not a problem with ListBox).

I tried making a TreeView afterwards. The plan was to write a custom cell renderer that would draw the cell contents using cairo & use the ‘activate’ to catch clicks and display my popover if the user clicked on the spot of the button. And the TreeView can be lazy/reuse rows. But that didn’t work out because I have different row types, it would get very messy with TreeView & CellRenderer which are not meant for that, and setting up a CellRenderer & TreeView is quite boilerplaty.

That brings me to my current plan… Use a DrawingArea and draw the rows manually. They can have the same height per row type, I can catch click events, and I was going to draw the cells with cairo with the TreeView as well anyway.

I have two questions regarding that approach:

  1. is going for a DrawingArea the right approach in my case? I know it’ll work, maybe it’s more work than it could be, but I have no better idea.

  2. If using a DrawingArea, I’ll need a scrollbar, and the “virtual” area is going to be quite large – since I intend to “simulate” a ListBox like that. Often it’s advised to use a DrawingArea within a ScrolledWindow, and setting the height of the DrawingArea to the wanted value. However I intended to handle the scrolling myself, having a DrawingArea of the display size (not the virtual size) and a separate scrollbar, assuming the ScrolledWindow approach would take considerably more memory. But the ScrolledWindow approach is often mentioned on internet as though it doesn’t have any minuses. I guess it’s technically possible that it would only use the memory required for the ‘display’ area, not the one for the ‘virtual’ area. So my question is, is it way more efficient to have DrawingArea of the display size & a separate scrollbar as opposed to having a very large DrawingArea inside a ScrolledWindow? Or is the performance (speed, memory use) difference not that large?

Thank you, I’m aware this is a long read…


1 Like

What you describe sounds like you’re just going to reimplement parts of GtkTreeView.

  1. The “right” approach is always to use widgets. What you’re trying to do has been done a few times already, but GTK4 actually has support for such large lists.
  2. You can have a drawing area that is only the size of the scrolled window but still scrolls its contents around just fine by implementing GtkScrollable.

But then again, 1000 is not even that much and you could just do that in a few main loop iterations, which would not block the UI but still leave you with the least amount of work.

Thank you for the answer! I’ll review GtkScrollable, it seems like I definitely want to use it if I persist on that GtkDrawingArea path.

The adding of 1000 widgets in a GtkListBox is ~500ms for me and I could achieve that refilling the listbox doesn’t block the GUI thread as you mention, but it’ll remain slowish, and crucially the memory use goes from 14Mb to 100Mb when displaying 1000 of my entries in a ListBox. What may be happening however is that I’m not adding gtk widgets per se… But I’m using rust & and so I’m adding relm widgets. Maybe if I made proper gtk widgets it’d be faster & take less memory (I could ask the author of relm about that – or actually test it myself). But then again I display 1000 children for me right now, there’s no reason it couldn’t be 10.000 and more for another user of the app with a larger dataset and it’s known that GtkListBox scales only up to a point.

I read that gtk4 gained support for some kind of virtualized listbox, this is great! But for me right now on gtk3, if there is no library wrapping this support available, I don’t have tons of options :frowning:

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