diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h index dd0cf8d2a9..c44d61813d 100644 --- a/gtk/gtktreeprivate.h +++ b/gtk/gtktreeprivate.h @@ -175,6 +175,8 @@ struct _GtkTreeViewPrivate GList *column_drag_info; GtkTreeViewColumnReorder *cur_reorder; + gint prev_width_before_expander; + /* Interactive Header reordering */ GdkWindow *drag_window; GdkWindow *drag_highlight_window; diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 560f35c963..1a606772f8 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -1378,6 +1378,9 @@ gtk_tree_view_init (GtkTreeView *tree_view) tree_view->priv->last_button_x = -1; tree_view->priv->last_button_y = -1; + + tree_view->priv->event_last_x = -10000; + tree_view->priv->event_last_y = -10000; } @@ -2052,6 +2055,25 @@ gtk_tree_view_size_request (GtkWidget *widget, } } +static int +gtk_tree_view_calculate_width_before_expander (GtkTreeView *tree_view) +{ + int width = 0; + GList *list; + gboolean rtl; + + rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL); + for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); + list->data != tree_view->priv->expander_column; + list = (rtl ? list->prev : list->next)) + { + GtkTreeViewColumn *column = list->data; + + width += column->width; + } + + return width; +} static void invalidate_column (GtkTreeView *tree_view, @@ -2438,14 +2460,30 @@ gtk_tree_view_size_allocate (GtkWidget *widget, } } + if (width_changed && tree_view->priv->expander_column) + { + /* Might seem awkward, but is the best heuristic I could come up + * with. Only if the width of the columns before the expander + * changes, we will update the prelight status. It is this + * width that makes the expander move vertically. Always updating + * prelight status causes trouble with hover selections. + */ + gint width_before_expander; + + width_before_expander = gtk_tree_view_calculate_width_before_expander (tree_view); + + if (tree_view->priv->prev_width_before_expander + != width_before_expander) + update_prelight (tree_view, + -tree_view->priv->event_last_x, + -tree_view->priv->event_last_y); + + tree_view->priv->prev_width_before_expander = width_before_expander; + } + /* This little hack only works if we have an LTR locale, and no column has the */ if (width_changed) { - if (tree_view->priv->tree) - update_prelight (tree_view, - tree_view->priv->event_last_x, - tree_view->priv->event_last_y); - if (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_LTR && ! has_expand_column) invalidate_last_column (tree_view); @@ -3264,6 +3302,16 @@ prelight_or_select (GtkTreeView *tree_view, do_prelight (tree_view, tree, node, x, y); } +static void +ensure_unprelighted (GtkTreeView *tree_view) +{ + do_prelight (tree_view, + NULL, NULL, + -1000, -1000); /* coords not possibly over an arrow */ + + g_assert (tree_view->priv->prelight_node == NULL); +} + static void update_prelight (GtkTreeView *tree_view, gint x, @@ -3273,6 +3321,12 @@ update_prelight (GtkTreeView *tree_view, GtkRBTree *tree; GtkRBNode *node; + if (x == -10000) + { + ensure_unprelighted (tree_view); + return; + } + new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y); if (new_y < 0) new_y = 0; @@ -3284,16 +3338,6 @@ update_prelight (GtkTreeView *tree_view, prelight_or_select (tree_view, tree, node, x, y); } -static void -ensure_unprelighted (GtkTreeView *tree_view) -{ - do_prelight (tree_view, - NULL, NULL, - -1000, -1000); /* coords not possibly over an arrow */ - - g_assert (tree_view->priv->prelight_node == NULL); -} - @@ -5507,6 +5551,9 @@ gtk_tree_view_enter_notify (GtkWidget *widget, new_y = 0; _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node); + tree_view->priv->event_last_x = event->x; + tree_view->priv->event_last_y = event->y; + if ((tree_view->priv->button_pressed_node == NULL) || (tree_view->priv->button_pressed_node == node)) prelight_or_select (tree_view, tree, node, event->x, event->y); @@ -5531,6 +5578,9 @@ gtk_tree_view_leave_notify (GtkWidget *widget, tree_view->priv->prelight_node, NULL); + tree_view->priv->event_last_x = -10000; + tree_view->priv->event_last_y = -10000; + prelight_or_select (tree_view, NULL, NULL, -1000, -1000); /* coords not possibly over an arrow */