GtkTreeExpander should be able to update in runtime
The Problem
I'm the current maintainer for GTG (AKA Getting things GNOME). We're moving to Gtk4 and listviews (from the old Treeviews).
One feature we need is the ability to nest tags and tasks inside each other arbitrarily. That means using TreeModels and GtkTreeExpanders. The problem is that this should be modifiable at runtime. The users would drag a task on top of another to "parent" (nest) it, or outside to unparent.
That means the model_func
for the tree expander would change, sometimes it will have children sometimes it won't. But, as I've been told in the Matrix channel tree expanders weren't designed for this.
The pile of workarounds
The first workaround is to have the model_func
always return a model so the expanders are always available.
Then I changed the visibility of the expander based on whether the tag has children or not. However, this killed the indent on items with no children. So, the next step is to kill the indent for all rows with css (.arrow-only-expander indent { -gtk-icon-size: 0px; }
), and then fake the indent using the margin_start
of the box that contains all widgets.
But this still sucks, because the listview won't update when the model function changes. Not until you click the expander arrow. To solve this I kept a reference to every expander ever created and call toggle-expand
twice on them, then emit items-changed
for good measure.
The WIP code can be found here: https://github.com/getting-things-gnome/gtg/blob/c2e28ebbeec8994433589be8af57eb0b503005c3/GTG/gtk/browser/sidebar.py
Solutions?
There are two problems: Hiding the arrow and updating the listview.
Maybe have a property in the tree expander to set whether the arrow should show up. Then we can bind()
or bind_full()
to that prop. I don't know anything about Gtk's internals but I think that a change in the source for the bind would cause the list to refresh?
Another option would be to re-check model_func
when the listview updates, but that might be expensive for lists with lots of nested rows.