Search code examples
clinuxgtkgtk4

C - GTK 4 - Able to remove row from liststore but unable to append row to liststore


I am trying to make a program in C with GTK 4.0 on and for Linux and I am trying to update all of the rows in a liststore and add some rows to the liststore. I can use gtk_list_store_remove but when I try to use gtk_list_store_append the program crashes with this:

Gtk:ERROR:../gtk/gtk/gtktreerbtree.c:475:gtk_tree_rbtree_insert_after: assertion failed: (gtk_tree_rbtree_is_nil (tree->root))
Bail out! Gtk:ERROR:../gtk/gtk/gtktreerbtree.c:475:gtk_tree_rbtree_insert_after: assertion failed: (gtk_tree_rbtree_is_nil (tree->root))

The last part is different on Arch Linux and Ubuntu.

Arch Linux:

[1]    [PID] IOT instruction (core dumped) [executable]

Ubuntu:

Aborted (core dumped)

I have tried using gtk_list_store_insert to make a new row but it produces the same result. A snippet of my code around where the crash occurs is below. All of the code is available on GitHub. The code is now slightly different on GitHub but still has the same problem.

gboolean valid;
GtkTreeIter iter;
GtkTreeIter curr_iter;
GtkListStore *store = GTK_LIST_STORE(model);

valid = gtk_tree_model_get_iter_first(model, &iter);
// Add or Remove rows so that the total number of rows is equal to rowsWanted
while (valid){
    valid = gtk_tree_model_iter_next(model, &iter);
    if (valid == false && rowsWanted > gtk_tree_model_iter_n_children(model, NULL)){
        // The error occurs here
        gtk_list_store_append(store, &iter);
        gtk_tree_model_row_inserted(model, gtk_tree_model_get_path(model, &iter), &iter);
        //valid = gtk_tree_model_iter_next(model, &iter);
        valid = true;
    }
    else if (valid == true && rowsWanted < gtk_tree_model_iter_n_children(model, NULL)){
       gtk_list_store_remove(store, &iter);
       gtk_tree_model_row_deleted(model, gtk_tree_model_get_path(model, &iter));
    }
}

Does anyone know why this is happening? Thanks.

Edit: After running the executable through the terminal and not through my IDE, I am seeing "IOT instruction (core dumped)". I am running Arch Linux x86_64.

Edit 2: On an Ubuntu 21.10 VM, I do not get the IOT instruction but instead I get "Aborted (core dumped)" (makes more sense because assertion is failing). The GTK errors are still the same.


Solution

  • While I could not reproduce this (in an flatpak environment), calling gtk_tree_model_row_inserted() and gtk_tree_model_row_deleted() seems very suspicious to me.

    To my knowledge, GtkTreeView uses that internal RBTree implementation, and it uses those signals to know when to update. gtk_list_store_append() and gtk_list_store_remove() already call these signals, so signaling row-inserted twice for the same element would be just wrong.

    On my end when I insert your code in GitHub manually I get messages such as:

    (taskmonitor:19172): Gtk-CRITICAL **: 00:00:00.000: ../gtk/gtktreeview.c:4960 (gtk_tree_view_bin_snapshot): assertion `has_next' failed.
    There is a disparity between the internal view of the GtkTreeView,
    and the GtkTreeModel.  This generally means that the model has changed
    without letting the view know.  Any display from now on is likely to
    be incorrect.
    

    So try removing those two lines calling gtk_tree_model_row_inserted() and gtk_tree_model_row_deleted() each.