diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index e3bee395bc..9ef634fd0c 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -12440,14 +12440,24 @@ gtk_tree_view_real_set_cursor (GtkTreeView *tree_view, gtk_tree_row_reference_free (tree_view->priv->cursor); tree_view->priv->cursor = NULL; - /* One cannot set the cursor on a separator. */ - if (!row_is_separator (tree_view, NULL, path)) + /* One cannot set the cursor on a separator. Also, if + * _gtk_tree_view_find_node returns TRUE, it ran out of tree + * before finding the tree and node belonging to path. The + * path maps to a non-existing path and we will silently bail out. + * We unset tree and node to avoid further processing. + */ + if (!row_is_separator (tree_view, NULL, path) + && _gtk_tree_view_find_node (tree_view, path, &tree, &node) == FALSE) { tree_view->priv->cursor = - gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), - tree_view->priv->model, - path); - _gtk_tree_view_find_node (tree_view, path, &tree, &node); + gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), + tree_view->priv->model, + path); + } + else + { + tree = NULL; + node = NULL; } if (tree != NULL) diff --git a/gtk/tests/treeview.c b/gtk/tests/treeview.c index 14020084e9..3dcc44287f 100644 --- a/gtk/tests/treeview.c +++ b/gtk/tests/treeview.c @@ -96,6 +96,60 @@ test_bug_539377 (void) &path, NULL) == FALSE); } +static void +test_select_collapsed_row (void) +{ + GtkTreeIter child, parent; + GtkTreePath *path; + GtkTreeStore *tree_store; + GtkTreeSelection *selection; + GtkWidget *view; + + /* Reported by Michael Natterer */ + tree_store = gtk_tree_store_new (1, G_TYPE_STRING); + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store)); + + gtk_tree_store_insert_with_values (tree_store, &parent, NULL, 0, + 0, "Parent", + -1); + + gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0, + 0, "Child", + -1); + gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0, + 0, "Child", + -1); + + + /* Try to select a child path. */ + path = gtk_tree_path_new_from_indices (0, 1, -1); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + + /* Check that the parent is not selected. */ + gtk_tree_path_up (path); + g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == FALSE); + + /* Nothing should be selected at this point. */ + g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 0); + + /* Check that selection really still works. */ + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE); + g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1); + + /* Expand and select child node now. */ + gtk_tree_path_append_index (path, 1); + gtk_tree_view_expand_all (GTK_TREE_VIEW (view)); + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE); + g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1); + + gtk_tree_path_free (path); +} + int main (int argc, char **argv) @@ -104,6 +158,8 @@ main (int argc, g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005); g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377); + g_test_add_func ("/TreeView/cursor/select-collapsed_row", + test_select_collapsed_row); return g_test_run (); }