[gtk+] stylecontext: Change fallback behavior on state mismatch



commit fe51ac273c8045279a222c22a52d297d5ede4169
Author: Benjamin Otte <otte redhat com>
Date:   Mon Jun 15 04:30:50 2015 +0200

    stylecontext: Change fallback behavior on state mismatch
    
    For functions that take state flags as an argument we need to special
    case the situation where the passed in flags don't match the current
    state.
    
    Previously we would create a copy of the style info, change its state
    and do the lookup from there.
    
    Now that GtkCssNode has replaced style infos, this doesn't work as well
    anymore as copying a GtkCssNode is not possible.
    However, unike style infos, GtkCssNodes are instant-apply, so we don't
    need to copy anymore, we can just change the state of the node.
    
    This causes some invalidations to be queued, but we can take that
    performance hit as this is fallback code.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1228852

 gtk/gtkstylecontext.c |   60 +++++++++++++++++++++++++++++-------------------
 1 files changed, 36 insertions(+), 24 deletions(-)
---
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index db75a28..5c253d1 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -498,15 +498,16 @@ gtk_style_context_lookup_style (GtkStyleContext *context)
   return gtk_css_node_get_style (context->priv->cssnode);
 }
 
-static GtkCssStyle *
-gtk_style_context_lookup_style_for_state (GtkStyleContext *context,
-                                          GtkStateFlags    state)
+static GtkStateFlags
+gtk_style_context_push_state (GtkStyleContext *context,
+                              GtkStateFlags    state)
 {
-  GtkCssNode *node;
-  GtkCssStyle *values;
+  GtkStateFlags current_state;
+
+  current_state = gtk_css_node_get_state (context->priv->cssnode);
 
-  if (gtk_css_node_get_state (context->priv->cssnode) == state)
-    return g_object_ref (gtk_style_context_lookup_style (context));
+  if (current_state == state)
+    return state;
 
   if (g_getenv ("GTK_STYLE_CONTEXT_WARNING"))
     {
@@ -525,14 +526,16 @@ gtk_style_context_lookup_style_for_state (GtkStyleContext *context,
         }
     }
 
-  node = gtk_css_transient_node_new (context->priv->cssnode);
-  gtk_css_node_set_parent (node, gtk_css_node_get_parent (context->priv->cssnode));
-  gtk_css_node_set_state (node, state);
-  values = g_object_ref (gtk_css_node_get_style (node));
-  gtk_css_node_set_parent (node, NULL);
-  g_object_unref (node);
+  gtk_css_node_set_state (context->priv->cssnode, state);
 
-  return values;
+  return current_state;
+}
+
+static void
+gtk_style_context_pop_state (GtkStyleContext *context,
+                             GtkStateFlags    saved_state)
+{
+  gtk_css_node_set_state (context->priv->cssnode, saved_state);
 }
 
 /**
@@ -809,7 +812,7 @@ gtk_style_context_get_property (GtkStyleContext *context,
                                 GtkStateFlags    state,
                                 GValue          *value)
 {
-  GtkCssStyle *values;
+  GtkStateFlags saved_state;
   GtkStyleProperty *prop;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
@@ -828,9 +831,12 @@ gtk_style_context_get_property (GtkStyleContext *context,
       return;
     }
 
-  values = gtk_style_context_lookup_style_for_state (context, state);
-  _gtk_style_property_query (prop, value, gtk_style_context_query_func, values);
-  g_object_unref (values);
+  saved_state = gtk_style_context_push_state (context, state);
+  _gtk_style_property_query (prop, 
+                             value,
+                             gtk_style_context_query_func,
+                             gtk_css_node_get_style (context->priv->cssnode));
+  gtk_style_context_pop_state (context, saved_state);
 }
 
 /**
@@ -2616,12 +2622,14 @@ gtk_style_context_get_border (GtkStyleContext *context,
                               GtkBorder       *border)
 {
   GtkCssStyle *style;
+  GtkStateFlags saved_state;
   double top, left, bottom, right;
 
   g_return_if_fail (border != NULL);
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
 
-  style = gtk_style_context_lookup_style_for_state (context, state);
+  saved_state = gtk_style_context_push_state (context, state);
+  style = gtk_style_context_lookup_style (context);
 
   top = round (_gtk_css_number_value_get (gtk_css_style_get_value (style, 
GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100));
   right = round (_gtk_css_number_value_get (gtk_css_style_get_value (style, 
GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100));
@@ -2633,7 +2641,7 @@ gtk_style_context_get_border (GtkStyleContext *context,
   border->bottom = bottom;
   border->right = right;
 
-  g_object_unref (style);
+  gtk_style_context_pop_state (context, saved_state);
 }
 
 /**
@@ -2653,12 +2661,14 @@ gtk_style_context_get_padding (GtkStyleContext *context,
                                GtkBorder       *padding)
 {
   GtkCssStyle *style;
+  GtkStateFlags saved_state;
   double top, left, bottom, right;
 
   g_return_if_fail (padding != NULL);
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
 
-  style = gtk_style_context_lookup_style_for_state (context, state);
+  saved_state = gtk_style_context_push_state (context, state);
+  style = gtk_style_context_lookup_style (context);
 
   top = round (_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_PADDING_TOP), 
100));
   right = round (_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_PADDING_RIGHT), 
100));
@@ -2670,7 +2680,7 @@ gtk_style_context_get_padding (GtkStyleContext *context,
   padding->bottom = bottom;
   padding->right = right;
 
-  g_object_unref (style);
+  gtk_style_context_pop_state (context, saved_state);
 }
 
 /**
@@ -2690,12 +2700,14 @@ gtk_style_context_get_margin (GtkStyleContext *context,
                               GtkBorder       *margin)
 {
   GtkCssStyle *style;
+  GtkStateFlags saved_state;
   double top, left, bottom, right;
 
   g_return_if_fail (margin != NULL);
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
 
-  style = gtk_style_context_lookup_style_for_state (context, state);
+  saved_state = gtk_style_context_push_state (context, state);
+  style = gtk_style_context_lookup_style (context);
 
   top = round (_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_MARGIN_TOP), 
100));
   right = round (_gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_MARGIN_RIGHT), 
100));
@@ -2707,7 +2719,7 @@ gtk_style_context_get_margin (GtkStyleContext *context,
   margin->bottom = bottom;
   margin->right = right;
 
-  g_object_unref (style);
+  gtk_style_context_pop_state (context, saved_state);
 }
 
 /**


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