[gparted] port-to-gtk3: Block Gtk::TreeSelection changed handler on tree model clear (#7)



commit 0078cf01cc3eff08c801040f62cee1925d39b59e
Author: Luca Bacci <luca bacci982 gmail com>
Date:   Wed Sep 5 15:07:25 2018 +0200

    port-to-gtk3: Block Gtk::TreeSelection changed handler on tree model clear (#7)
    
    Now GParted compiles with Gtkmm3, but we get a failed assertion doing
    the following:
     * Select a device with more than 1 partition
     * Select a partition
     * Activate 'Refresh Devices' (or do any operation that causes it, like
       mount/unmount etc.)
    
    This is the failed assertion:
        **
        ERROR:Win_GParted.cc:1152:void GParted::Win_GParted::set_valid_operations(): assertion failed: 
(valid_display_partition_ptr( selected_partition_ptr ))
        Aborted (core dumped)
    
    Where is the problem?
    
    Win_GParted::Refresh_Visual() calls TreeView_Detail::load_partitions()
    to clear and refill the treeview.
    
    The problem is in GParted::TreeView_Detail::load_partitions() at
    TreeView_Detail.cc:91:
        treestore_detail->clear();
    
    This activates TreeView_Detail::on_selection_changed() which in turn
    activates Win_GParted::on_partition_selected() passing an old, stale
    pointer as an argument.  This triggers the failed assertion.
    
    Why does this happen with Gtk3 and not with Gtk2?
    
    First a bit of background of GtkTreeView:
    
    What happens to the selection in a GtkTreeView when the selected row
    is removed?
    
    With Gtk2 the selection simply becomes empty, so nothing is selected
    afterwards.  With Gtk3 this was changed [1] and selection moves to an
    adjacent row.
    
    gtk_tree_store_clear() removes rows one by one.  While removing rows the
    selection changed signal is emitted.  With Gtk2 it is emitted only one
    time, to indicate that selection has become empty.  With Gtk3 it is
    instead emitted several times, each time indicating that selection has
    moved to the adjacent row.
    
    The handler TreeView_Detail::on_selection_changed() only takes action
    when the selection is not empty.  So with Gtk3 it really takes action
    and activates Win_GParted::on_partition_selected() with a pointer to old
    data.
    
    What's the purpose of TreeView_Detail::on_selection_changed()?
    
    Its task is to update the selection in the drawing area above the
    TreeViewDetail, the DrawingAreaVisualDisk, so that the selected
    partition stays in sync on the two widgets.
    
    Fix by blocking the signal handler during the treeview clear.
    
    Reference:
    [1] Commit - treeview: Handle the case where the cursor row gets deleted
        https://gitlab.gnome.org/GNOME/gtk/commit/1a2932ba2915c34171581a85afba39311e9c3ac6
    
    Closes #7 - Port to Gtk3

 src/TreeView_Detail.cc | 2 ++
 1 file changed, 2 insertions(+)
---
diff --git a/src/TreeView_Detail.cc b/src/TreeView_Detail.cc
index 2e105b03..dcf02ac9 100644
--- a/src/TreeView_Detail.cc
+++ b/src/TreeView_Detail.cc
@@ -88,7 +88,9 @@ void TreeView_Detail::load_partitions( const PartitionVector & partitions )
        bool show_mountpoints = false;
        bool show_labels      = false;
 
+       block = true;
        treestore_detail ->clear() ;
+       block = false;
 
        load_partitions( partitions, show_names, show_mountpoints, show_labels );
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]