[gtk+/native-layout] Correct problems with earlier fix for bug #480065



commit a763546c8f155aa08cf79575e4069f058a7c6bce
Author: Kristian Rietveld <kris gtk org>
Date:   Mon Dec 21 22:33:59 2009 +0100

    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 43c6e31..8a84e89 100644
--- a/gtk/gtktreeprivate.h
+++ b/gtk/gtktreeprivate.h
@@ -177,6 +177,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 ef4cb46..4be8f9e 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -1382,6 +1382,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;
 }
 
 
@@ -2056,6 +2059,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,
@@ -2473,14 +2495,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);
@@ -3300,6 +3338,16 @@ prelight_or_select (GtkTreeView *tree_view,
 }
 
 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,
                  gint         y)
@@ -3308,6 +3356,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;
@@ -3319,16 +3373,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);
-}
-
 
 
 
@@ -5542,6 +5586,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);
@@ -5566,6 +5613,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 */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]