[gtk+/wip/cssvalue: 138/164] widget: Don't cache widget paths all the time



commit c5ce99257c146fc7802e482033b9079dae7a286d
Author: Benjamin Otte <otte redhat com>
Date:   Sat Apr 7 14:15:35 2012 +0200

    widget: Don't cache widget paths all the time
    
    Add an internal API that allows GtkStyleContext to create a widget path
    for the widget and with that bypassing gtk_widget_get_path() and that
      function caching the path.

 gtk/gtkbox.c           |    2 +-
 gtk/gtkcombobox.c      |    2 +-
 gtk/gtkcontainer.c     |    2 +-
 gtk/gtkmenu.c          |    2 +-
 gtk/gtkpathbar.c       |    2 +-
 gtk/gtkspinbutton.c    |    3 +-
 gtk/gtkstylecontext.c  |   16 ++++++++----
 gtk/gtktoolbar.c       |    2 +-
 gtk/gtkwidget.c        |   61 ++++++++++++++++++++++++++---------------------
 gtk/gtkwidgetprivate.h |    1 +
 10 files changed, 53 insertions(+), 40 deletions(-)
---
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c
index 9276a71..cc0cb8a 100644
--- a/gtk/gtkbox.c
+++ b/gtk/gtkbox.c
@@ -899,7 +899,7 @@ gtk_box_get_path_for_child (GtkContainer *container,
   box = GTK_BOX (container);
   private = box->priv;
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
 
   if (gtk_widget_get_visible (child))
     {
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index 0272924..b83412e 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -1415,7 +1415,7 @@ gtk_combo_box_get_path_for_child (GtkContainer *container,
   GtkWidgetPath *sibling_path;
   int pos;
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
 
   if (gtk_widget_get_visible (child))
     {
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 6253ab7..425eea8 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -2338,7 +2338,7 @@ gtk_container_real_get_path_for_child (GtkContainer *container,
   GList *classes;
 
   context = gtk_widget_get_style_context (GTK_WIDGET (container));
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
 
   /* Copy any permanent classes to the path */
   classes = gtk_style_context_list_classes (context);
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 88be4e3..ef871ee 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -3198,7 +3198,7 @@ gtk_menu_get_preferred_width (GtkWidget *widget,
       context = gtk_style_context_new ();
 
       /* Create a GtkCheckMenuItem path, only to query indicator spacing */
-      check_path = gtk_widget_path_copy (gtk_widget_get_path (widget));
+      check_path = _gtk_widget_create_path (widget);
       gtk_widget_path_append_type (check_path, GTK_TYPE_CHECK_MENU_ITEM);
 
       gtk_style_context_set_path (context, check_path);
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index fdcd337..0cdcde4 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -876,7 +876,7 @@ gtk_path_bar_get_path_for_child (GtkContainer *container,
   GtkPathBar *path_bar = GTK_PATH_BAR (container);
   GtkWidgetPath *path;
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (path_bar)));
+  path = _gtk_widget_create_path (GTK_WIDGET (path_bar));
 
   if (gtk_widget_get_visible (child) &&
       gtk_widget_get_child_visible (child))
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index 5c7dbc1..f1334c0 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -46,6 +46,7 @@
 #include "gtkstock.h"
 #include "gtktypebuiltins.h"
 #include "gtkwidgetpath.h"
+#include "gtkwidgetprivate.h"
 
 #include "a11y/gtkspinbuttonaccessible.h"
 
@@ -746,7 +747,7 @@ gtk_spin_button_panel_nthchildize_context (GtkSpinButton *spin_button,
    * have to emulate what gtk_container_get_path_for_child() would do
    * for the button panels
    */
-  path = gtk_widget_path_copy (gtk_widget_get_path (widget));
+  path = _gtk_widget_create_path (widget);
   direction = gtk_widget_get_direction (widget);
   siblings_path = gtk_widget_path_new ();
 
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 80bf78e..103f235 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -745,7 +745,7 @@ create_query_path (GtkStyleContext *context)
   guint i, pos;
 
   priv = context->priv;
-  path = gtk_widget_path_copy (priv->widget ? gtk_widget_get_path (priv->widget) : priv->widget_path);
+  path = priv->widget ? _gtk_widget_create_path (priv->widget) : gtk_widget_path_copy (priv->widget_path);
   pos = gtk_widget_path_length (path) - 1;
 
   info = priv->info_stack->data;
@@ -2042,9 +2042,6 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context,
   key.state = state;
   key.pspec = pspec;
 
-  if (priv->widget)
-    gtk_widget_get_path (priv->widget);
-
   /* need value cache array */
   if (!data->property_cache)
     data->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
@@ -2071,9 +2068,10 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context,
 
   if (priv->widget || priv->widget_path)
     {
+      GtkWidgetPath *widget_path = priv->widget ? _gtk_widget_create_path (priv->widget) : priv->widget_path;
+
       if (gtk_style_provider_get_style_property (GTK_STYLE_PROVIDER (priv->cascade),
-                                                 priv->widget ? gtk_widget_get_path (priv->widget)
-                                                              : priv->widget_path,
+                                                 widget_path,
                                                  state, pspec, &pcache->value))
         {
           /* Resolve symbolic colors to GdkColor/GdkRGBA */
@@ -2112,8 +2110,14 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context,
               gtk_symbolic_color_unref (color);
             }
 
+          if (priv->widget)
+            gtk_widget_path_free (widget_path);
+
           return &pcache->value;
         }
+
+      if (priv->widget)
+        gtk_widget_path_free (widget_path);
     }
 
   /* not supplied by any provider, revert to default */
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index be66900..a83f52a 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -3946,7 +3946,7 @@ gtk_toolbar_get_path_for_child (GtkContainer *container,
   g_list_foreach (children, add_widget_to_path, sibling_path);
   g_list_free (children);
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
   if (gtk_widget_get_visible (child))
     {
       vis_index = gtk_toolbar_get_visible_position (toolbar, child);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 066380b..2e6dd45 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -13897,6 +13897,39 @@ gtk_widget_path_append_for_widget (GtkWidgetPath *path,
   return pos;
 }
 
+GtkWidgetPath *
+_gtk_widget_create_path (GtkWidget *widget)
+{
+  GtkWidget *parent;
+
+  parent = widget->priv->parent;
+
+  if (parent)
+    return gtk_container_get_path_for_child (GTK_CONTAINER (parent), widget);
+  else
+    {
+      /* Widget is either toplevel or unparented, treat both
+       * as toplevels style wise, since there are situations
+       * where style properties might be retrieved on that
+       * situation.
+       */
+      GtkWidget *attach_widget = NULL;
+      GtkWidgetPath *result;
+
+      if (GTK_IS_WINDOW (widget))
+        attach_widget = gtk_window_get_attached_to (GTK_WINDOW (widget));
+
+      if (attach_widget != NULL)
+        result = gtk_widget_path_copy (gtk_widget_get_path (attach_widget));
+      else
+        result = gtk_widget_path_new ();
+
+      gtk_widget_path_append_for_widget (result, widget);
+
+      return result;
+    }
+}
+
 /**
  * gtk_widget_get_path:
  * @widget: a #GtkWidget
@@ -13913,33 +13946,7 @@ gtk_widget_get_path (GtkWidget *widget)
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
   if (!widget->priv->path)
-    {
-      GtkWidget *parent;
-
-      parent = widget->priv->parent;
-
-      if (parent)
-        widget->priv->path = gtk_container_get_path_for_child (GTK_CONTAINER (parent), widget);
-      else
-        {
-          /* Widget is either toplevel or unparented, treat both
-           * as toplevels style wise, since there are situations
-           * where style properties might be retrieved on that
-           * situation.
-           */
-          GtkWidget *attach_widget = NULL;
-
-          if (GTK_IS_WINDOW (widget))
-            attach_widget = gtk_window_get_attached_to (GTK_WINDOW (widget));
-
-          if (attach_widget != NULL)
-            widget->priv->path = gtk_widget_path_copy (gtk_widget_get_path (attach_widget));
-          else
-            widget->priv->path = gtk_widget_path_new ();
-    
-          gtk_widget_path_append_for_widget (widget->priv->path, widget);
-        }
-    }
+    widget->priv->path = _gtk_widget_create_path (widget);
 
   return widget->priv->path;
 }
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 5cf44dd..fa5e9b8 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -176,6 +176,7 @@ void              _gtk_widget_set_captured_event_handler (GtkWidget
 gboolean          _gtk_widget_captured_event               (GtkWidget *widget,
                                                             GdkEvent  *event);
 
+GtkWidgetPath *   _gtk_widget_create_path                  (GtkWidget    *widget);
 void              _gtk_widget_invalidate_style_context     (GtkWidget    *widget,
                                                             GtkCssChange  change);
 void              _gtk_widget_style_context_invalidated    (GtkWidget    *widget);



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