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
    1a2932ba29

Closes #7 - Port to Gtk3
This commit is contained in:
Luca Bacci 2018-09-05 15:07:25 +02:00 committed by Mike Fleetwood
parent 2953778a4c
commit 0078cf01cc
1 changed files with 2 additions and 0 deletions

View File

@ -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 );