treeview: Replace cursor handling by keeping the node
Previously the code used a GtkTreeRowReference, which was (a) less performant and more importantly (b) hiding errors. The errors being hidden were the referenced row becoming invalid or collapsed, because such rows would not be valid cursor rows and it would be necesary to select a new row and emit a "cursor-changed" signal. So if a crash bisects down to this commit, it is very likely that the cursor has not correctly been updated and the cursor row is invalid.
This commit is contained in:
		@ -317,7 +317,8 @@ struct _GtkTreeViewPrivate
 | 
			
		||||
  gint cursor_offset;
 | 
			
		||||
 | 
			
		||||
  GtkTreeRowReference *anchor;
 | 
			
		||||
  GtkTreeRowReference *cursor;
 | 
			
		||||
  GtkRBNode *cursor_node;
 | 
			
		||||
  GtkRBTree *cursor_tree;
 | 
			
		||||
 | 
			
		||||
  GtkTreeViewColumn *focus_column;
 | 
			
		||||
 | 
			
		||||
@ -2055,9 +2056,6 @@ gtk_tree_view_destroy (GtkWidget *widget)
 | 
			
		||||
      tree_view->priv->destroy_count_data = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gtk_tree_row_reference_free (tree_view->priv->cursor);
 | 
			
		||||
  tree_view->priv->cursor = NULL;
 | 
			
		||||
 | 
			
		||||
  gtk_tree_row_reference_free (tree_view->priv->anchor);
 | 
			
		||||
  tree_view->priv->anchor = NULL;
 | 
			
		||||
 | 
			
		||||
@ -4678,8 +4676,6 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 | 
			
		||||
  GtkRBTree *tree;
 | 
			
		||||
  GList *list;
 | 
			
		||||
  GtkRBNode *node;
 | 
			
		||||
  GtkRBNode *cursor = NULL;
 | 
			
		||||
  GtkRBTree *cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *drag_highlight = NULL;
 | 
			
		||||
  GtkRBTree *drag_highlight_tree = NULL;
 | 
			
		||||
  GtkTreeIter iter;
 | 
			
		||||
@ -4695,7 +4691,6 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 | 
			
		||||
  gint expander_cell_width;
 | 
			
		||||
  gint bin_window_width;
 | 
			
		||||
  gint bin_window_height;
 | 
			
		||||
  GtkTreePath *cursor_path;
 | 
			
		||||
  GtkTreePath *drag_dest_path;
 | 
			
		||||
  GList *first_column, *last_column;
 | 
			
		||||
  gint vertical_separator;
 | 
			
		||||
@ -4766,16 +4761,8 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 | 
			
		||||
  depth = gtk_tree_path_get_depth (path);
 | 
			
		||||
  gtk_tree_path_free (path);
 | 
			
		||||
  
 | 
			
		||||
  cursor_path = NULL;
 | 
			
		||||
  drag_dest_path = NULL;
 | 
			
		||||
 | 
			
		||||
  if (tree_view->priv->cursor)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path)
 | 
			
		||||
    _gtk_tree_view_find_node (tree_view, cursor_path,
 | 
			
		||||
                              &cursor_tree, &cursor);
 | 
			
		||||
 | 
			
		||||
  if (tree_view->priv->drag_dest_row)
 | 
			
		||||
    drag_dest_path = gtk_tree_row_reference_get_path (tree_view->priv->drag_dest_row);
 | 
			
		||||
 | 
			
		||||
@ -4895,7 +4882,7 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 | 
			
		||||
          else
 | 
			
		||||
            flags &= ~GTK_CELL_RENDERER_SORTED;
 | 
			
		||||
 | 
			
		||||
	  if (cursor == node)
 | 
			
		||||
	  if (tree_view->priv->cursor_node == node)
 | 
			
		||||
            flags |= GTK_CELL_RENDERER_FOCUSED;
 | 
			
		||||
          else
 | 
			
		||||
            flags &= ~GTK_CELL_RENDERER_FOCUSED;
 | 
			
		||||
@ -4984,7 +4971,7 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 | 
			
		||||
          gtk_style_context_add_region (context, GTK_STYLE_REGION_ROW, row_flags);
 | 
			
		||||
          gtk_style_context_add_region (context, GTK_STYLE_REGION_COLUMN, column_flags);
 | 
			
		||||
 | 
			
		||||
	  if (node == cursor && has_can_focus_cell
 | 
			
		||||
	  if (node == tree_view->priv->cursor_node && has_can_focus_cell
 | 
			
		||||
              && ((column == tree_view->priv->focus_column
 | 
			
		||||
                   && tree_view->priv->draw_keyfocus &&
 | 
			
		||||
                   gtk_widget_has_visible_focus (widget))
 | 
			
		||||
@ -5224,7 +5211,7 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* draw the big row-spanning focus rectangle, if needed */
 | 
			
		||||
      if (!has_can_focus_cell && node == cursor &&
 | 
			
		||||
      if (!has_can_focus_cell && node == tree_view->priv->cursor_node &&
 | 
			
		||||
          tree_view->priv->draw_keyfocus &&
 | 
			
		||||
	  gtk_widget_has_visible_focus (widget))
 | 
			
		||||
        {
 | 
			
		||||
@ -5317,9 +5304,6 @@ done:
 | 
			
		||||
  if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
 | 
			
		||||
    gtk_tree_view_paint_rubber_band (tree_view, cr);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path)
 | 
			
		||||
    gtk_tree_path_free (cursor_path);
 | 
			
		||||
 | 
			
		||||
  if (drag_dest_path)
 | 
			
		||||
    gtk_tree_path_free (drag_dest_path);
 | 
			
		||||
 | 
			
		||||
@ -8712,8 +8696,9 @@ gtk_tree_view_row_changed (GtkTreeModel *model,
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (path != NULL || iter != NULL);
 | 
			
		||||
 | 
			
		||||
  if (tree_view->priv->cursor != NULL)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
  if (tree_view->priv->cursor_node != NULL)
 | 
			
		||||
    cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                  tree_view->priv->cursor_node);
 | 
			
		||||
  else
 | 
			
		||||
    cursor_path = NULL;
 | 
			
		||||
 | 
			
		||||
@ -10057,8 +10042,9 @@ gtk_tree_view_focus_to_cursor (GtkTreeView *tree_view)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cursor_path = NULL;
 | 
			
		||||
  if (tree_view->priv->cursor)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
  if (tree_view->priv->cursor_node)
 | 
			
		||||
    cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                  tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path == NULL)
 | 
			
		||||
    {
 | 
			
		||||
@ -10085,9 +10071,6 @@ gtk_tree_view_focus_to_cursor (GtkTreeView *tree_view)
 | 
			
		||||
				       TRUE, NULL, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      gtk_tree_row_reference_free (tree_view->priv->cursor);
 | 
			
		||||
      tree_view->priv->cursor = NULL;
 | 
			
		||||
 | 
			
		||||
      if (cursor_path)
 | 
			
		||||
	{
 | 
			
		||||
	  if (gtk_tree_selection_get_mode (tree_view->priv->selection) == GTK_SELECTION_MULTIPLE)
 | 
			
		||||
@ -10139,8 +10122,6 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
				   gint         count)
 | 
			
		||||
{
 | 
			
		||||
  gint selection_count;
 | 
			
		||||
  GtkRBTree *cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *cursor_node = NULL;
 | 
			
		||||
  GtkRBTree *new_cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *new_cursor_node = NULL;
 | 
			
		||||
  GtkTreePath *cursor_path = NULL;
 | 
			
		||||
@ -10154,18 +10135,11 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
  if (! gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cursor_path = NULL;
 | 
			
		||||
  if (!gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
    /* FIXME: we lost the cursor; should we get the first? */
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, cursor_path,
 | 
			
		||||
			    &cursor_tree, &cursor_node);
 | 
			
		||||
 | 
			
		||||
  if (cursor_tree == NULL)
 | 
			
		||||
    /* FIXME: we lost the cursor; should we get the first? */
 | 
			
		||||
    return;
 | 
			
		||||
  cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  direction = count < 0 ? GTK_DIR_UP : GTK_DIR_DOWN;
 | 
			
		||||
 | 
			
		||||
@ -10178,9 +10152,9 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
    {
 | 
			
		||||
      gtk_tree_view_column_cell_set_cell_data (tree_view->priv->focus_column,
 | 
			
		||||
					       tree_view->priv->model,
 | 
			
		||||
					       &iter,
 | 
			
		||||
					       GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
 | 
			
		||||
					       cursor_node->children?TRUE:FALSE);
 | 
			
		||||
                                               &iter,
 | 
			
		||||
                                               GTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, GTK_RBNODE_IS_PARENT),
 | 
			
		||||
					       tree_view->priv->cursor_node->children ? TRUE : FALSE);
 | 
			
		||||
 | 
			
		||||
      /* Save the last cell that had focus, if we hit the end of the view we'll give
 | 
			
		||||
       * focus back to it. */
 | 
			
		||||
@ -10193,7 +10167,7 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
 | 
			
		||||
  selection_count = gtk_tree_selection_count_selected_rows (tree_view->priv->selection);
 | 
			
		||||
  selectable = _gtk_tree_selection_row_is_selectable (tree_view->priv->selection,
 | 
			
		||||
						      cursor_node,
 | 
			
		||||
						      tree_view->priv->cursor_node,
 | 
			
		||||
						      cursor_path);
 | 
			
		||||
 | 
			
		||||
  if (selection_count == 0
 | 
			
		||||
@ -10202,16 +10176,16 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
      && selectable)
 | 
			
		||||
    {
 | 
			
		||||
      /* Don't move the cursor, but just select the current node */
 | 
			
		||||
      new_cursor_tree = cursor_tree;
 | 
			
		||||
      new_cursor_node = cursor_node;
 | 
			
		||||
      new_cursor_tree = tree_view->priv->cursor_tree;
 | 
			
		||||
      new_cursor_node = tree_view->priv->cursor_node;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (count == -1)
 | 
			
		||||
	_gtk_rbtree_prev_full (cursor_tree, cursor_node,
 | 
			
		||||
	_gtk_rbtree_prev_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node,
 | 
			
		||||
			       &new_cursor_tree, &new_cursor_node);
 | 
			
		||||
      else
 | 
			
		||||
	_gtk_rbtree_next_full (cursor_tree, cursor_node,
 | 
			
		||||
	_gtk_rbtree_next_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node,
 | 
			
		||||
			       &new_cursor_tree, &new_cursor_node);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -10238,20 +10212,21 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
      new_cursor_node == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (count == -1)
 | 
			
		||||
        _gtk_rbtree_next_full (cursor_tree, cursor_node,
 | 
			
		||||
        _gtk_rbtree_next_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node,
 | 
			
		||||
    			       &new_cursor_tree, &new_cursor_node);
 | 
			
		||||
      else
 | 
			
		||||
        _gtk_rbtree_prev_full (cursor_tree, cursor_node,
 | 
			
		||||
        _gtk_rbtree_prev_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node,
 | 
			
		||||
			       &new_cursor_tree, &new_cursor_node);
 | 
			
		||||
 | 
			
		||||
      if (new_cursor_node == NULL
 | 
			
		||||
	  && !GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_SELECTED))
 | 
			
		||||
	  && !GTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, GTK_RBNODE_IS_SELECTED))
 | 
			
		||||
        {
 | 
			
		||||
          new_cursor_node = cursor_node;
 | 
			
		||||
          new_cursor_tree = cursor_tree;
 | 
			
		||||
          new_cursor_node = tree_view->priv->cursor_node;
 | 
			
		||||
          new_cursor_tree = tree_view->priv->cursor_tree;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          new_cursor_tree = NULL;
 | 
			
		||||
          new_cursor_node = NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -10268,7 +10243,9 @@ gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
 | 
			
		||||
      gtk_tree_view_clamp_node_visible (tree_view, 
 | 
			
		||||
                                        tree_view->priv->cursor_tree,
 | 
			
		||||
                                        tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
      if (!tree_view->priv->extend_selection_pressed)
 | 
			
		||||
        {
 | 
			
		||||
@ -10304,12 +10281,12 @@ static void
 | 
			
		||||
gtk_tree_view_move_cursor_page_up_down (GtkTreeView *tree_view,
 | 
			
		||||
					gint         count)
 | 
			
		||||
{
 | 
			
		||||
  GtkRBTree *cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *cursor_node = NULL;
 | 
			
		||||
  GtkTreePath *old_cursor_path = NULL;
 | 
			
		||||
  GtkTreePath *cursor_path = NULL;
 | 
			
		||||
  GtkRBTree *start_cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *start_cursor_node = NULL;
 | 
			
		||||
  GtkRBTree *cursor_tree;
 | 
			
		||||
  GtkRBNode *cursor_node;
 | 
			
		||||
  gint y;
 | 
			
		||||
  gint window_y;
 | 
			
		||||
  gint vertical_separator;
 | 
			
		||||
@ -10317,25 +10294,15 @@ gtk_tree_view_move_cursor_page_up_down (GtkTreeView *tree_view,
 | 
			
		||||
  if (!gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
    old_cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
  else
 | 
			
		||||
    /* This is sorta weird.  Focus in should give us a cursor */
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  old_cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                    tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  gtk_widget_style_get (GTK_WIDGET (tree_view), "vertical-separator", &vertical_separator, NULL);
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, old_cursor_path,
 | 
			
		||||
			    &cursor_tree, &cursor_node);
 | 
			
		||||
 | 
			
		||||
  if (cursor_tree == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* FIXME: we lost the cursor.  Should we try to get one? */
 | 
			
		||||
      gtk_tree_path_free (old_cursor_path);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  g_return_if_fail (cursor_node != NULL);
 | 
			
		||||
 | 
			
		||||
  y = _gtk_rbtree_node_find_offset (cursor_tree, cursor_node);
 | 
			
		||||
  y = _gtk_rbtree_node_find_offset (tree_view->priv->cursor_tree, tree_view->priv->cursor_node);
 | 
			
		||||
  window_y = RBTREE_Y_TO_TREE_WINDOW_Y (tree_view, y);
 | 
			
		||||
  y += tree_view->priv->cursor_offset;
 | 
			
		||||
  y += count * (int)gtk_adjustment_get_page_increment (tree_view->priv->vadjustment);
 | 
			
		||||
@ -10413,8 +10380,6 @@ static void
 | 
			
		||||
gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
 | 
			
		||||
				      gint         count)
 | 
			
		||||
{
 | 
			
		||||
  GtkRBTree *cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *cursor_node = NULL;
 | 
			
		||||
  GtkTreePath *cursor_path = NULL;
 | 
			
		||||
  GtkTreeViewColumn *column;
 | 
			
		||||
  GtkTreeIter iter;
 | 
			
		||||
@ -10431,14 +10396,12 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
 | 
			
		||||
  if (!gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
  else
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, cursor_path, &cursor_tree, &cursor_node);
 | 
			
		||||
  if (cursor_tree == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
  cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path) == FALSE)
 | 
			
		||||
    {
 | 
			
		||||
      gtk_tree_path_free (cursor_path);
 | 
			
		||||
@ -10472,8 +10435,8 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
 | 
			
		||||
      gtk_tree_view_column_cell_set_cell_data (column,
 | 
			
		||||
					       tree_view->priv->model,
 | 
			
		||||
					       &iter,
 | 
			
		||||
					       GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
 | 
			
		||||
					       cursor_node->children?TRUE:FALSE);
 | 
			
		||||
					       GTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, GTK_RBNODE_IS_PARENT),
 | 
			
		||||
					       tree_view->priv->cursor_node->children ? TRUE : FALSE);
 | 
			
		||||
 | 
			
		||||
      cell_area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
 | 
			
		||||
      if (gtk_cell_area_focus (cell_area, direction))
 | 
			
		||||
@ -10494,8 +10457,8 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
 | 
			
		||||
    {
 | 
			
		||||
      if (!gtk_tree_view_has_can_focus_cell (tree_view))
 | 
			
		||||
	_gtk_tree_view_queue_draw_node (tree_view,
 | 
			
		||||
				        cursor_tree,
 | 
			
		||||
				        cursor_node,
 | 
			
		||||
				        tree_view->priv->cursor_tree,
 | 
			
		||||
				        tree_view->priv->cursor_node,
 | 
			
		||||
				        NULL);
 | 
			
		||||
      g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0);
 | 
			
		||||
      gtk_widget_grab_focus (GTK_WIDGET (tree_view));
 | 
			
		||||
@ -10621,12 +10584,12 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view,
 | 
			
		||||
  if (!gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (tree_view->priv->cursor)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path == NULL)
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, cursor_path,
 | 
			
		||||
			    &cursor_tree, &cursor_node);
 | 
			
		||||
 | 
			
		||||
@ -10693,20 +10656,11 @@ gtk_tree_view_real_toggle_cursor_row (GtkTreeView *tree_view)
 | 
			
		||||
  if (!gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  cursor_path = NULL;
 | 
			
		||||
  if (tree_view->priv->cursor)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path == NULL)
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, cursor_path,
 | 
			
		||||
			    &cursor_tree, &cursor_node);
 | 
			
		||||
  if (cursor_tree == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      gtk_tree_path_free (cursor_path);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  _gtk_tree_selection_internal_select_node (tree_view->priv->selection,
 | 
			
		||||
					    cursor_node,
 | 
			
		||||
@ -10721,10 +10675,12 @@ gtk_tree_view_real_toggle_cursor_row (GtkTreeView *tree_view)
 | 
			
		||||
   */
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, cursor_path, &new_tree, &new_node);
 | 
			
		||||
 | 
			
		||||
  if (cursor_tree != new_tree || cursor_node != new_node)
 | 
			
		||||
  if (tree_view->priv->cursor_node != new_node)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
 | 
			
		||||
  gtk_tree_view_clamp_node_visible (tree_view,
 | 
			
		||||
                                    tree_view->priv->cursor_tree,
 | 
			
		||||
                                    tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  gtk_widget_grab_focus (GTK_WIDGET (tree_view));
 | 
			
		||||
  gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
 | 
			
		||||
@ -10740,24 +10696,18 @@ gtk_tree_view_real_expand_collapse_cursor_row (GtkTreeView *tree_view,
 | 
			
		||||
					       gboolean     open_all)
 | 
			
		||||
{
 | 
			
		||||
  GtkTreePath *cursor_path = NULL;
 | 
			
		||||
  GtkRBTree *tree;
 | 
			
		||||
  GtkRBNode *node;
 | 
			
		||||
 | 
			
		||||
  if (!gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  cursor_path = NULL;
 | 
			
		||||
  if (tree_view->priv->cursor)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path == NULL)
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (_gtk_tree_view_find_node (tree_view, cursor_path, &tree, &node))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  /* Don't handle the event if we aren't an expander */
 | 
			
		||||
  if (!((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT))
 | 
			
		||||
  if (!GTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, GTK_RBNODE_IS_PARENT))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!logical
 | 
			
		||||
@ -10765,9 +10715,18 @@ gtk_tree_view_real_expand_collapse_cursor_row (GtkTreeView *tree_view,
 | 
			
		||||
    expand = !expand;
 | 
			
		||||
 | 
			
		||||
  if (expand)
 | 
			
		||||
    gtk_tree_view_real_expand_row (tree_view, cursor_path, tree, node, open_all, TRUE);
 | 
			
		||||
    gtk_tree_view_real_expand_row (tree_view,
 | 
			
		||||
                                   cursor_path,
 | 
			
		||||
                                   tree_view->priv->cursor_tree,
 | 
			
		||||
                                   tree_view->priv->cursor_node,
 | 
			
		||||
                                   open_all,
 | 
			
		||||
                                   TRUE);
 | 
			
		||||
  else
 | 
			
		||||
    gtk_tree_view_real_collapse_row (tree_view, cursor_path, tree, node, TRUE);
 | 
			
		||||
    gtk_tree_view_real_collapse_row (tree_view,
 | 
			
		||||
                                     cursor_path,
 | 
			
		||||
                                     tree_view->priv->cursor_tree,
 | 
			
		||||
                                     tree_view->priv->cursor_node,
 | 
			
		||||
                                     TRUE);
 | 
			
		||||
 | 
			
		||||
  gtk_tree_path_free (cursor_path);
 | 
			
		||||
 | 
			
		||||
@ -10777,34 +10736,21 @@ gtk_tree_view_real_expand_collapse_cursor_row (GtkTreeView *tree_view,
 | 
			
		||||
static gboolean
 | 
			
		||||
gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view)
 | 
			
		||||
{
 | 
			
		||||
  GtkRBTree *cursor_tree = NULL;
 | 
			
		||||
  GtkRBNode *cursor_node = NULL;
 | 
			
		||||
  GtkTreePath *cursor_path = NULL;
 | 
			
		||||
  GdkModifierType state;
 | 
			
		||||
 | 
			
		||||
  if (!gtk_widget_has_focus (GTK_WIDGET (tree_view)))
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  cursor_path = NULL;
 | 
			
		||||
  if (tree_view->priv->cursor)
 | 
			
		||||
    cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
 | 
			
		||||
  if (cursor_path == NULL)
 | 
			
		||||
  if (tree_view->priv->cursor_node == NULL)
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  _gtk_tree_view_find_node (tree_view, cursor_path,
 | 
			
		||||
			    &cursor_tree, &cursor_node);
 | 
			
		||||
  if (cursor_tree == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      gtk_tree_path_free (cursor_path);
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
  cursor_path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
 | 
			
		||||
  if (cursor_tree->parent_node)
 | 
			
		||||
  if (tree_view->priv->cursor_tree->parent_node)
 | 
			
		||||
    {
 | 
			
		||||
      gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
 | 
			
		||||
      cursor_node = cursor_tree->parent_node;
 | 
			
		||||
      cursor_tree = cursor_tree->parent_tree;
 | 
			
		||||
 | 
			
		||||
      gtk_tree_path_up (cursor_path);
 | 
			
		||||
 | 
			
		||||
@ -11369,8 +11315,8 @@ gtk_tree_view_set_model (GtkTreeView  *tree_view,
 | 
			
		||||
 | 
			
		||||
      gtk_tree_row_reference_free (tree_view->priv->drag_dest_row);
 | 
			
		||||
      tree_view->priv->drag_dest_row = NULL;
 | 
			
		||||
      gtk_tree_row_reference_free (tree_view->priv->cursor);
 | 
			
		||||
      tree_view->priv->cursor = NULL;
 | 
			
		||||
      tree_view->priv->cursor_tree = NULL;
 | 
			
		||||
      tree_view->priv->cursor_node = NULL;
 | 
			
		||||
      gtk_tree_row_reference_free (tree_view->priv->anchor);
 | 
			
		||||
      tree_view->priv->anchor = NULL;
 | 
			
		||||
      gtk_tree_row_reference_free (tree_view->priv->top_row);
 | 
			
		||||
@ -12871,13 +12817,10 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
 | 
			
		||||
      gtk_tree_path_free (child_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
  if (tree_view->priv->cursor_node)
 | 
			
		||||
    {
 | 
			
		||||
      GtkTreePath *cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
 | 
			
		||||
      cursor_changed = gtk_tree_path_is_ancestor (path, cursor_path);
 | 
			
		||||
 | 
			
		||||
      gtk_tree_path_free (cursor_path);
 | 
			
		||||
      cursor_changed = (node->children == tree_view->priv->cursor_tree)
 | 
			
		||||
                       || _gtk_rbtree_contains (node->children, tree_view->priv->cursor_tree);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (gtk_tree_row_reference_valid (tree_view->priv->anchor))
 | 
			
		||||
@ -13156,41 +13099,31 @@ gtk_tree_view_real_set_cursor (GtkTreeView     *tree_view,
 | 
			
		||||
			       gboolean         clear_and_select,
 | 
			
		||||
			       gboolean         clamp_node)
 | 
			
		||||
{
 | 
			
		||||
  GtkRBTree *tree = NULL;
 | 
			
		||||
  GtkRBNode *node = NULL;
 | 
			
		||||
 | 
			
		||||
  if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
  if (tree_view->priv->cursor_node)
 | 
			
		||||
    {
 | 
			
		||||
      GtkTreePath *cursor_path;
 | 
			
		||||
      cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
      gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
 | 
			
		||||
      gtk_tree_path_free (cursor_path);
 | 
			
		||||
      _gtk_tree_view_queue_draw_node (tree_view,
 | 
			
		||||
                                      tree_view->priv->cursor_tree,
 | 
			
		||||
                                      tree_view->priv->cursor_node,
 | 
			
		||||
                                      NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gtk_tree_row_reference_free (tree_view->priv->cursor);
 | 
			
		||||
  tree_view->priv->cursor = NULL;
 | 
			
		||||
 | 
			
		||||
  /* 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)
 | 
			
		||||
  if (row_is_separator (tree_view, NULL, path)
 | 
			
		||||
      || _gtk_tree_view_find_node (tree_view,
 | 
			
		||||
                                   path,
 | 
			
		||||
                                   &tree_view->priv->cursor_tree,
 | 
			
		||||
                                   &tree_view->priv->cursor_node))
 | 
			
		||||
    {
 | 
			
		||||
      tree_view->priv->cursor =
 | 
			
		||||
          gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view),
 | 
			
		||||
                                            tree_view->priv->model,
 | 
			
		||||
                                            path);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      tree = NULL;
 | 
			
		||||
      node = NULL;
 | 
			
		||||
      tree_view->priv->cursor_tree = NULL;
 | 
			
		||||
      tree_view->priv->cursor_node = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (tree != NULL)
 | 
			
		||||
  if (tree_view->priv->cursor_node != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      GtkRBTree *new_tree = NULL;
 | 
			
		||||
      GtkRBNode *new_node = NULL;
 | 
			
		||||
@ -13203,7 +13136,10 @@ gtk_tree_view_real_set_cursor (GtkTreeView     *tree_view,
 | 
			
		||||
            mode |= GTK_TREE_SELECT_MODE_EXTEND;
 | 
			
		||||
 | 
			
		||||
          _gtk_tree_selection_internal_select_node (tree_view->priv->selection,
 | 
			
		||||
                                                    node, tree, path, mode,
 | 
			
		||||
                                                    tree_view->priv->cursor_node,
 | 
			
		||||
                                                    tree_view->priv->cursor_tree,
 | 
			
		||||
                                                    path,
 | 
			
		||||
                                                    mode,
 | 
			
		||||
                                                    FALSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -13213,13 +13149,18 @@ gtk_tree_view_real_set_cursor (GtkTreeView     *tree_view,
 | 
			
		||||
       */
 | 
			
		||||
      _gtk_tree_view_find_node (tree_view, path, &new_tree, &new_node);
 | 
			
		||||
 | 
			
		||||
      if (tree != new_tree || node != new_node)
 | 
			
		||||
      if (tree_view->priv->cursor_node != new_node)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      if (clamp_node)
 | 
			
		||||
        {
 | 
			
		||||
	  gtk_tree_view_clamp_node_visible (tree_view, tree, node);
 | 
			
		||||
	  _gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL);
 | 
			
		||||
	  gtk_tree_view_clamp_node_visible (tree_view,
 | 
			
		||||
                                            tree_view->priv->cursor_tree,
 | 
			
		||||
                                            tree_view->priv->cursor_node);
 | 
			
		||||
	  _gtk_tree_view_queue_draw_node (tree_view,
 | 
			
		||||
                                          tree_view->priv->cursor_tree,
 | 
			
		||||
                                          tree_view->priv->cursor_node,
 | 
			
		||||
                                          NULL);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -13248,8 +13189,9 @@ gtk_tree_view_get_cursor (GtkTreeView        *tree_view,
 | 
			
		||||
 | 
			
		||||
  if (path)
 | 
			
		||||
    {
 | 
			
		||||
      if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
	*path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
      if (tree_view->priv->cursor_node)
 | 
			
		||||
        *path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                                tree_view->priv->cursor_node);
 | 
			
		||||
      else
 | 
			
		||||
	*path = NULL;
 | 
			
		||||
    }
 | 
			
		||||
@ -15081,8 +15023,6 @@ gtk_tree_view_search_activate (GtkEntry    *entry,
 | 
			
		||||
			       GtkTreeView *tree_view)
 | 
			
		||||
{
 | 
			
		||||
  GtkTreePath *path;
 | 
			
		||||
  GtkRBNode *node;
 | 
			
		||||
  GtkRBTree *tree;
 | 
			
		||||
 | 
			
		||||
  gtk_tree_view_search_dialog_hide (tree_view->priv->search_window,
 | 
			
		||||
				    tree_view,
 | 
			
		||||
@ -15090,14 +15030,13 @@ gtk_tree_view_search_activate (GtkEntry    *entry,
 | 
			
		||||
 | 
			
		||||
  /* If we have a row selected and it's the cursor row, we activate
 | 
			
		||||
   * the row XXX */
 | 
			
		||||
  if (gtk_tree_row_reference_valid (tree_view->priv->cursor))
 | 
			
		||||
  if (tree_view->priv->cursor_node &&
 | 
			
		||||
      GTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, GTK_RBNODE_IS_SELECTED))
 | 
			
		||||
    {
 | 
			
		||||
      path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 | 
			
		||||
      path = _gtk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree,
 | 
			
		||||
                                             tree_view->priv->cursor_node);
 | 
			
		||||
      
 | 
			
		||||
      _gtk_tree_view_find_node (tree_view, path, &tree, &node);
 | 
			
		||||
      
 | 
			
		||||
      if (node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
 | 
			
		||||
	gtk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column);
 | 
			
		||||
      gtk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column);
 | 
			
		||||
      
 | 
			
		||||
      gtk_tree_path_free (path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user