From f59294fd938065a3b306689343bf515b8eb633d7 Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Mon, 21 Dec 2009 22:33:59 +0100 Subject: [PATCH] Correct problems with earlier fix for bug #480065 Initialize event_last_[xy] to out of range coordinates and also update these values in enter and leave notify. Fix up calls to update_prelight() from size allocate. Unconditionally doing these calls caused problems with hover selection. Now we only do this call when the "width before the expander column" has changed. (Which might be awkward, but it is the best heuristic I could come up with so far). --- gtk/gtktreeprivate.h | 2 ++ gtk/gtktreeview.c | 80 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 15 deletions(-) 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 */