summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2016-05-19 20:59:10 (GMT)
committerMatthias Clasen <mclasen@redhat.com>2016-05-19 20:59:10 (GMT)
commitd3adf47d9f70ed785dc26aba3b48e607f89ee5b5 (patch)
tree4200d78fef7fef5135ad6f7be2afb0ea0a3a8094 /gtk/gtktreeview.c
parenteace965a197e7145d214cbdaa0bef24f2fb1bbd6 (diff)
downloadgtk+-d3adf47d9f70ed785dc26aba3b48e607f89ee5b5.zip
gtk+-d3adf47d9f70ed785dc26aba3b48e607f89ee5b5.tar.xz
treeview: Fix a rubberbanding-related crash
When starting a rubberband selection from an empty area, we could run into crashes if the selection moves over the rows and then back out to unpopulated area. Handle this case without crashing. https://bugzilla.gnome.org/show_bug.cgi?id=766336
Diffstat (limited to 'gtk/gtktreeview.c')
-rw-r--r--gtk/gtktreeview.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 757e072..1ac81ca 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -4381,24 +4381,30 @@ gtk_tree_view_stop_rubber_band (GtkTreeView *tree_view)
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
/* The anchor path should be set to the start path */
- tmp_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->rubber_band_start_tree,
- tree_view->priv->rubber_band_start_node);
+ if (tree_view->priv->rubber_band_start_node)
+ {
+ tmp_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->rubber_band_start_tree,
+ tree_view->priv->rubber_band_start_node);
- if (tree_view->priv->anchor)
- gtk_tree_row_reference_free (tree_view->priv->anchor);
+ if (tree_view->priv->anchor)
+ gtk_tree_row_reference_free (tree_view->priv->anchor);
- tree_view->priv->anchor =
- gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view),
- tree_view->priv->model,
- tmp_path);
+ tree_view->priv->anchor =
+ gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view),
+ tree_view->priv->model,
+ tmp_path);
- gtk_tree_path_free (tmp_path);
+ gtk_tree_path_free (tmp_path);
+ }
/* ... and the cursor to the end path */
- tmp_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->rubber_band_end_tree,
- tree_view->priv->rubber_band_end_node);
- gtk_tree_view_real_set_cursor (GTK_TREE_VIEW (tree_view), tmp_path, 0);
- gtk_tree_path_free (tmp_path);
+ if (tree_view->priv->rubber_band_end_node)
+ {
+ tmp_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->rubber_band_end_tree,
+ tree_view->priv->rubber_band_end_node);
+ gtk_tree_view_real_set_cursor (GTK_TREE_VIEW (tree_view), tmp_path, 0);
+ gtk_tree_path_free (tmp_path);
+ }
_gtk_tree_selection_emit_changed (tree_view->priv->selection);
@@ -4535,7 +4541,28 @@ gtk_tree_view_update_rubber_band_selection (GtkTreeView *tree_view)
_gtk_rbtree_find_offset (tree_view->priv->tree, MAX (tree_view->priv->press_start_y, bin_y), &end_tree, &end_node);
/* Handle the start area first */
- if (!tree_view->priv->rubber_band_start_node)
+ if (!start_node && !end_node)
+ {
+ if (tree_view->priv->rubber_band_start_node)
+ {
+ GtkRBNode *node = tree_view->priv->rubber_band_start_node;
+ GtkRBTree *tree = tree_view->priv->rubber_band_start_tree;
+
+ if (tree_view->priv->rubber_band_modify)
+ {
+ /* Toggle the selection state */
+ if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
+ GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SELECTED);
+ else
+ GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SELECTED);
+ }
+ else
+ GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SELECTED);
+
+ _gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL);
+ }
+ }
+ if (!tree_view->priv->rubber_band_start_node || !start_node)
{
gtk_tree_view_update_rubber_band_selection_range (tree_view,
start_tree,