GNOME Bugzilla – Bug 540201
Hard crash trying to use gtk_tree_model_iter_has_child in the GtkTreeModelFilter visible function callback
Last modified: 2009-09-05 15:26:21 UTC
I tried to make some rows invisible in a GtkTreeModelFilter, based on whether they have children or not. The code is organized like this ; first I set a visible function : gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered), tree_model_filter_hide_show_offline, self, NULL); then in that callback function, I do : result = gtk_tree_model_iter_has_child (model, iter); where I got both model and filter as arguments, so hopefully they match. And this call to gtk_tree_model_iter_has_child gives the following error : ** ** Gtk:ERROR:(/tmp/buildd/gtk+2.0-2.12.10/gtk/gtktreemodelfilter.c:1583):gtk_tree_model_filter_row_has_child_toggled: assertion failed: (elt->visible) if I replace the line with result = TRUE, then no problem, so I'm sure it's this call which gives issues.
I see the same error message. The steps leading to the crash in my case are: 1. A node with no children exists in the child model, and a corresponding node exists in the GtkTreeModelFilter but is not visible (elt->visible is FALSE). 2. Adding a first child to the node in the child model causes the child model to signal "row_inserted" on the child, followed by "row_has_child_toggled" on the parent. 3. The GtkTreeModelFilter's handler for the "row_has_child_toggled" signal, gtk_tree_model_filter_row_has_child_toggled(), gets called. When it checks to see if the parent is visible by calling gtk_tree_model_filter_visible() (gtktreemodelfilter.c line 1566), my visible function decides "yes, it should be visible" because there is now a child. However, at this point elt->visible is still FALSE! 4. gtk_tree_model_filter_row_has_child_toggled() fails at gtktreemodelfilter.c line 1583 with this output: (gtk_tree_model_filter_row_has_child_toggled): assertion failed: (elt->visible) So basically, g_assert(elt->visible) fails in the case where the act of becoming a parent makes the parent visible, and the parent already existed in the GtkTreeModelFilter with elt->visible FALSE. I did find a workaround, which is to make the child model call gtk_tree_model_row_changed() on the parent just before calling gtk_tree_model_row_has_child_toggled(). I don't know if this is related, but I also noticed that gtk_tree_model_filter_row_inserted() can call gtk_tree_model_row_has_child_toggled() even if the new row should not be visible. That seems wrong to me.
Thanks for the detailed description leading up to the crash. I am working on an extensive unit test suite for GtkTreeModelFilter model now and I have added this test to it. Just like you I have found some logic that needs checking in the filter model. Using the filter model test suite I will resolve this and the other problems that have been reported in Bugzilla soonish.
Fixed on master.