[gtk/gtk3-remove-pixel-cache-from-treeview] treeview: Remove the pixel cache



commit 184424ae40c332da12f871298d303ee01dd8c11a
Author: Timm Bäder <mail baedert org>
Date:   Tue May 21 19:09:18 2019 +0200

    treeview: Remove the pixel cache
    
    This has caused numerous issues for users, especially in the
    filechooser, which have not been fixed in all the years since the pixel
    cache has been introduced.
    
    If anyone seriously has complaints about the treeview performance (and
    those did not exist with the pixel cache), feel free to revert this
    commit *and* fix the pixel cache issues.
    
    Closes #503
    Closes #1691
    Closes #466

 gtk/gtktreeview.c | 155 ++++++++++--------------------------------------------
 1 file changed, 28 insertions(+), 127 deletions(-)
---
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 3ba7a63594..d673356fe2 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -54,7 +54,6 @@
 #include "gtkmain.h"
 #include "gtksettingsprivate.h"
 #include "gtkwidgetpath.h"
-#include "gtkpixelcacheprivate.h"
 #include "a11y/gtktreeviewaccessibleprivate.h"
 
 
@@ -310,8 +309,6 @@ struct _GtkTreeViewPrivate
   GdkWindow *bin_window;
   GdkWindow *header_window;
 
-  GtkPixelCache *pixel_cache;
-
   /* CSS nodes */
   GtkCssNode *header_node;
 
@@ -495,8 +492,6 @@ struct _GtkTreeViewPrivate
   guint hover_expand : 1;
   guint imcontext_changed : 1;
 
-  guint in_scroll : 1;
-
   guint rubber_banding_enable : 1;
 
   guint in_grab : 1;
@@ -589,7 +584,6 @@ static void     gtk_tree_view_destroy              (GtkWidget        *widget);
 static void     gtk_tree_view_realize              (GtkWidget        *widget);
 static void     gtk_tree_view_unrealize            (GtkWidget        *widget);
 static void     gtk_tree_view_map                  (GtkWidget        *widget);
-static void     gtk_tree_view_unmap                (GtkWidget        *widget);
 static void     gtk_tree_view_get_preferred_width  (GtkWidget        *widget,
                                                    gint             *minimum,
                                                    gint             *natural);
@@ -788,9 +782,6 @@ static void     gtk_tree_view_stop_rubber_band               (GtkTreeView
 static void     update_prelight                              (GtkTreeView        *tree_view,
                                                               int                 x,
                                                               int                 y);
-static void     gtk_tree_view_queue_draw_region              (GtkWidget          *widget,
-                                                             const cairo_region_t *region);
-
 static inline gint gtk_tree_view_get_effective_header_height (GtkTreeView *tree_view);
 
 static inline gint gtk_tree_view_get_cell_area_y_offset      (GtkTreeView *tree_view,
@@ -981,7 +972,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   /* GtkWidget signals */
   widget_class->destroy = gtk_tree_view_destroy;
   widget_class->map = gtk_tree_view_map;
-  widget_class->unmap = gtk_tree_view_unmap;
   widget_class->realize = gtk_tree_view_realize;
   widget_class->unrealize = gtk_tree_view_unrealize;
   widget_class->get_preferred_width = gtk_tree_view_get_preferred_width;
@@ -1005,7 +995,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   widget_class->focus = gtk_tree_view_focus;
   widget_class->grab_focus = gtk_tree_view_grab_focus;
   widget_class->style_updated = gtk_tree_view_style_updated;
-  widget_class->queue_draw_region = gtk_tree_view_queue_draw_region;
 
   /* GtkContainer signals */
   container_class->remove = gtk_tree_view_remove;
@@ -1792,8 +1781,6 @@ gtk_tree_view_init (GtkTreeView *tree_view)
   priv->headers_visible = TRUE;
   priv->activate_on_single_click = FALSE;
 
-  priv->pixel_cache = _gtk_pixel_cache_new ();
-
   /* We need some padding */
   priv->dy = 0;
   priv->cursor_offset = 0;
@@ -2275,10 +2262,6 @@ gtk_tree_view_destroy (GtkWidget *widget)
       tree_view->priv->vadjustment = NULL;
     }
 
-  if (tree_view->priv->pixel_cache)
-    _gtk_pixel_cache_free (tree_view->priv->pixel_cache);
-  tree_view->priv->pixel_cache = NULL;
-
   g_clear_object (&tree_view->priv->multipress_gesture);
   g_clear_object (&tree_view->priv->drag_gesture);
   g_clear_object (&tree_view->priv->column_multipress_gesture);
@@ -2338,8 +2321,6 @@ gtk_tree_view_map (GtkWidget *widget)
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GList *tmp_list;
 
-  _gtk_pixel_cache_map (tree_view->priv->pixel_cache);
-
   gtk_widget_set_mapped (widget, TRUE);
 
   tmp_list = tree_view->priv->children;
@@ -2361,57 +2342,6 @@ gtk_tree_view_map (GtkWidget *widget)
   gdk_window_show (gtk_widget_get_window (widget));
 }
 
-static void
-gtk_tree_view_unmap (GtkWidget *widget)
-{
-  GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-
-  GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->unmap (widget);
-
-  _gtk_pixel_cache_unmap (tree_view->priv->pixel_cache);
-}
-
-static void
-gtk_tree_view_bin_window_invalidate_handler (GdkWindow *window,
-                                            cairo_region_t *region)
-{
-  gpointer widget;
-  GtkTreeView *tree_view;
-  int y;
-
-  gdk_window_get_user_data (window, &widget);
-  tree_view = GTK_TREE_VIEW (widget);
-
-  /* Scrolling will invalidate everything in the bin window,
-     but we already have it in the cache, so we can ignore that */
-  if (tree_view->priv->in_scroll)
-    return;
-
-  y = gtk_adjustment_get_value (tree_view->priv->vadjustment);
-  cairo_region_translate (region,
-                         0, y);
-  _gtk_pixel_cache_invalidate (tree_view->priv->pixel_cache, region);
-  cairo_region_translate (region,
-                         0, -y);
-}
-
-static void
-gtk_tree_view_queue_draw_region (GtkWidget *widget,
-                                const cairo_region_t *region)
-{
-  GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-
-  /* There is no way we can know if a region targets the
-     not-currently-visible but in pixel cache region, so we
-     always just invalidate the whole thing whenever the
-     tree view gets a queue draw. This doesn't normally happen
-     in normal scrolling cases anyway. */
-  _gtk_pixel_cache_invalidate (tree_view->priv->pixel_cache, NULL);
-
-  GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->queue_draw_region (widget,
-                                                                   region);
-}
-
 static void
 gtk_tree_view_realize (GtkWidget *widget)
 {
@@ -2462,8 +2392,6 @@ gtk_tree_view_realize (GtkWidget *widget)
   tree_view->priv->bin_window = gdk_window_new (window,
                                                &attributes, attributes_mask);
   gtk_widget_register_window (widget, tree_view->priv->bin_window);
-  gdk_window_set_invalidate_handler (tree_view->priv->bin_window,
-                                    gtk_tree_view_bin_window_invalidate_handler);
 
   gtk_widget_get_allocation (widget, &allocation);
 
@@ -5055,6 +4983,8 @@ gtk_tree_view_bin_draw (GtkWidget      *widget,
 
   bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
   bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
+  cairo_rectangle (cr, 0, 0, bin_window_width, bin_window_height);
+  cairo_clip (cr);
   if (!gdk_cairo_get_clip_rectangle (cr, &clip))
     return TRUE;
 
@@ -5591,35 +5521,6 @@ done:
   return FALSE;
 }
 
-static void
-draw_bin (cairo_t *cr,
-         gpointer user_data)
-{
-  GtkWidget *widget = GTK_WIDGET (user_data);
-  GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-  GList *tmp_list;
-
-  cairo_save (cr);
-
-  gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
-  gtk_tree_view_bin_draw (widget, cr);
-
-  cairo_restore (cr);
-
-  /* We can't just chain up to Container::draw as it will try to send the
-   * event to the headers, so we handle propagating it to our children
-   * (eg. widgets being edited) ourselves.
-   */
-  tmp_list = tree_view->priv->children;
-  while (tmp_list)
-    {
-      GtkTreeViewChild *child = tmp_list->data;
-      tmp_list = tmp_list->next;
-
-      gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
-    }
-}
-
 static gboolean
 gtk_tree_view_draw (GtkWidget *widget,
                     cairo_t   *cr)
@@ -5632,22 +5533,27 @@ gtk_tree_view_draw (GtkWidget *widget,
 
   if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window))
     {
-      cairo_rectangle_int_t view_rect;
-      cairo_rectangle_int_t canvas_rect;
+      GList *tmp_list;
+
+      cairo_save (cr);
+      gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
+      gtk_tree_view_bin_draw (widget, cr);
+      cairo_restore (cr);
+
 
-      view_rect.x = 0;
-      view_rect.y = gtk_tree_view_get_effective_header_height (tree_view);
-      view_rect.width = gtk_widget_get_allocated_width (widget);
-      view_rect.height = gtk_widget_get_allocated_height (widget) - view_rect.y;
+      /* We can't just chain up to Container::draw asit will try to send the
+       * event to the headers, so we handle propagating it to our children
+       * (e.g. widgets being edited) ourselves.
+       */
+      tmp_list = tree_view->priv->children;
+      while (tmp_list)
+        {
+          GtkTreeViewChild *child = tmp_list->data;
+          tmp_list = tmp_list->next;
 
-      gdk_window_get_position (tree_view->priv->bin_window, &canvas_rect.x, &canvas_rect.y);
-      canvas_rect.y = -gtk_adjustment_get_value (tree_view->priv->vadjustment);
-      canvas_rect.width = gdk_window_get_width (tree_view->priv->bin_window);
-      canvas_rect.height = gtk_tree_view_get_height (tree_view);
+          gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
+        }
 
-      _gtk_pixel_cache_draw (tree_view->priv->pixel_cache, cr, tree_view->priv->bin_window,
-                            &view_rect, &canvas_rect,
-                            draw_bin, widget);
     }
   else if (tree_view->priv->drag_highlight_window &&
            gtk_cairo_should_draw_window (cr, tree_view->priv->drag_highlight_window))
@@ -6247,17 +6153,17 @@ gtk_tree_view_node_queue_redraw (GtkTreeView *tree_view,
                                 GtkRBTree   *tree,
                                 GtkRBNode   *node)
 {
-  GdkRectangle rect;
+  GtkAllocation allocation;
+  int y;
 
-  rect.x = 0;
-  rect.y =
-    _gtk_rbtree_node_find_offset (tree, node)
+  y = _gtk_rbtree_node_find_offset (tree, node)
     - gtk_adjustment_get_value (tree_view->priv->vadjustment);
-  rect.width = gtk_widget_get_allocated_width (GTK_WIDGET (tree_view));
-  rect.height = GTK_RBNODE_GET_HEIGHT (node);
 
-  gdk_window_invalidate_rect (tree_view->priv->bin_window,
-                             &rect, TRUE);
+  gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
+  gtk_widget_queue_draw_area (GTK_WIDGET (tree_view),
+                              0, y,
+                              allocation.width,
+                              GTK_RBNODE_GET_HEIGHT (node));
 }
 
 static gboolean
@@ -11361,9 +11267,7 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
                       - gtk_adjustment_get_value (tree_view->priv->hadjustment),
                       0);
       dy = tree_view->priv->dy - (int) gtk_adjustment_get_value (tree_view->priv->vadjustment);
-      tree_view->priv->in_scroll = TRUE;
       gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
-      tree_view->priv->in_scroll = FALSE;
 
       if (dy != 0)
         {
@@ -11582,9 +11486,6 @@ gtk_tree_view_set_model (GtkTreeView  *tree_view,
   if (tree_view->priv->selection)
   _gtk_tree_selection_emit_changed (tree_view->priv->selection);
 
-  if (tree_view->priv->pixel_cache != NULL)
-    _gtk_pixel_cache_set_always_cache (tree_view->priv->pixel_cache, (model != NULL));
-
   if (gtk_widget_get_realized (GTK_WIDGET (tree_view)))
     gtk_widget_queue_resize (GTK_WIDGET (tree_view));
 }


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