Limitations on visible functions in GtkTreeModelFilter

When concluding the discussion on reference counting rules for nodes in an earlier blog post, we noted that these rules put limits on what kind of visible functions will function properly. The filter model must follow changes in its child model to keep the internal data structure up to date. As we have seen, changes can only be expected to be received for levels in which the filter model has a reference on at least one node. By default any references obtained on filter model nodes are passed on to the child model. So, the filter model will receive signals for all nodes that are visible in the filter model’s observer.

This is not enough to support an often used use case. If we, for example, want to only show a parent node if one of its children is visible, we need to monitor signals received on the child nodes, also when the parent node is hidden. Once one of the children changes state such that it will become visible, we must make the parent visible as well. Clearly, when the parent is invisible, its children are not referenced by the filter model’s observer.

Because this use case is so often used, we have made GtkTreeModelFilter explicitly support it. This is done by building child levels in the internal data structure of each node that could be visible. When a child level is built, a reference is obtained on the first node in that level. A node could be visible if any node in the level it is contained in (so any sibling) has been referenced by the filter model’s observer. Note that we thus look at the reference count of a level here and not at the reference count of individual nodes. We must also build the child level for invisible nodes contained in a visible level. Such child levels are monitored for changes and for every signal received a check is done whether this changed the visibility state of the parent node.

This explicit support is limited to dependencies from a node on its child for the node’s visibility state. If you want a node’s visibility to depend on the children of the node’s immediate children, you are on your own. In such cases you can either rely on GtkTreeStore, which always emits signals for all nodes because it does not implement reference counting, or obtain references on the additional child levels yourself.

To wrap up, we can in general say that visible functions should only use data or properties from the node for which the visibility state must be determined, its siblings or its parents. Because of the explicit support for this, it may also use data or properties from its children. If any other data is used, the filter model may not work reliably.

 

With this post, we have come to the end of the blog post series on peculiarities learned when fixing up GtkTreeModelSort and GtkTreeModelFilter last Summer. If you have any questions about these posts, do feel free to
contact me.