[gnome-shell] StThemeNode: Split -st-shadow into three attributes



commit e727c184ef09a8f5662960e1c12fba630737af39
Author: Ray Strode <rstrode redhat com>
Date:   Thu Jan 13 18:27:24 2011 -0500

    StThemeNode: Split -st-shadow into three attributes
    
    Currently, "-st-shadow" can mean one of three very
    different things:
    
    1) shadow based on alpha of the background image
    2) shadow the "border box" of the node
    3) shadow applied to the content of a StIcon
    
    It isn't well defined which of the above 3 cases
    -st-shadow will mean for any given node, however.
    
    This commit splits the property into three
    different properties, "box-shadow",
    "-st-background-image-shadow", and "icon-shadow"
    to make it all very explicit.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=636976

 data/theme/gnome-shell.css     |    8 +-
 src/st/st-icon.c               |   25 +++-
 src/st/st-theme-node-drawing.c |   39 +++---
 src/st/st-theme-node-private.h |    8 +-
 src/st/st-theme-node.c         |  328 ++++++++++++++++++++++++++++++----------
 src/st/st-theme-node.h         |   10 +-
 tests/interactive/borders.js   |   34 ++--
 7 files changed, 320 insertions(+), 132 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 6104ac9..65aaaf2 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -313,7 +313,7 @@ StTooltip StLabel {
     background-image: url("close-window.svg");
     height: 24px;
     width: 24px;
-    -st-shadow: -2px 2px 6px rgba(0,0,0,0.5);
+    -st-background-image-shadow: -2px 2px 6px rgba(0,0,0,0.5);
     -shell-close-overlap: 16px;
 }
 
@@ -374,7 +374,7 @@ StTooltip StLabel {
     background-gradient-direction: vertical;
     color: rgb(64, 64, 64);
     font-weight: bold;
-    -st-shadow: 0px 0px 6px 2px rgba(255,255,255,0.9);
+    box-shadow: 0px 0px 6px 2px rgba(255,255,255,0.9);
     transition-duration: 0;
 }
 
@@ -506,7 +506,7 @@ StTooltip StLabel {
 
 .remove-favorite-icon:hover {
     color: white;
-    -st-shadow: black 0px 2px 2px;
+    icon-shadow: black 0px 2px 2px;
 }
 
 .app-well-app > .overview-icon,
@@ -851,7 +851,7 @@ StTooltip StLabel {
     color: #545454;
     background-color: #e8e8e8;
     caret-color: #545454;
-    -st-shadow: 0px 0px 6px 2px rgba(255,255,255,0.9);
+    box-shadow: 0px 0px 6px 2px rgba(255,255,255,0.9);
 }
 
 /* The spacing and padding on the summary is tricky; we want to keep
diff --git a/src/st/st-icon.c b/src/st/st-icon.c
index 78519c4..d1210f1 100644
--- a/src/st/st-icon.c
+++ b/src/st/st-icon.c
@@ -62,6 +62,7 @@ struct _StIconPrivate
   CoglHandle    shadow_material;
   float         shadow_width;
   float         shadow_height;
+  StShadow     *shadow_spec;
 };
 
 static void st_icon_update               (StIcon *icon);
@@ -164,6 +165,12 @@ st_icon_dispose (GObject *gobject)
       priv->shadow_material = COGL_INVALID_HANDLE;
     }
 
+  if (priv->shadow_spec)
+    {
+      st_shadow_unref (priv->shadow_spec);
+      priv->shadow_spec = NULL;
+    }
+
   G_OBJECT_CLASS (st_icon_parent_class)->dispose (gobject);
 }
 
@@ -249,8 +256,6 @@ st_icon_paint (ClutterActor *actor)
     {
       if (priv->shadow_material)
         {
-          StThemeNode *node = st_widget_get_theme_node (ST_WIDGET (actor));
-          StShadow *shadow_spec = st_theme_node_get_shadow (node);
           ClutterActorBox allocation;
           float width, height;
 
@@ -262,7 +267,7 @@ st_icon_paint (ClutterActor *actor)
           allocation.x2 = allocation.x1 + priv->shadow_width;
           allocation.y2 = allocation.y1 + priv->shadow_height;
 
-          _st_paint_shadow_with_opacity (shadow_spec,
+          _st_paint_shadow_with_opacity (priv->shadow_spec,
                                          priv->shadow_material,
                                          &allocation,
                                          clutter_actor_get_paint_opacity (priv->icon_texture));
@@ -279,6 +284,13 @@ st_icon_style_changed (StWidget *widget)
   StThemeNode *theme_node = st_widget_get_theme_node (widget);
   StIconPrivate *priv = self->priv;
 
+  if (priv->shadow_spec)
+    {
+      st_shadow_unref (priv->shadow_spec);
+      priv->shadow_spec = NULL;
+    }
+  priv->shadow_spec = st_theme_node_get_shadow (theme_node, "icon-shadow");
+
   priv->theme_icon_size = (int)(0.5 + st_theme_node_get_length (theme_node, "icon-size"));
   st_icon_update_icon_size (self);
   st_icon_update (self);
@@ -353,8 +365,6 @@ static void
 st_icon_update_shadow_material (StIcon *icon)
 {
   StIconPrivate *priv = icon->priv;
-  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (icon));
-  StShadow *shadow_spec = st_theme_node_get_shadow (theme_node);
 
   if (priv->shadow_material)
     {
@@ -362,14 +372,15 @@ st_icon_update_shadow_material (StIcon *icon)
       priv->shadow_material = COGL_INVALID_HANDLE;
     }
 
-  if (shadow_spec)
+  if (priv->shadow_spec)
    {
      CoglHandle material;
      gint width, height;
 
      clutter_texture_get_base_size (CLUTTER_TEXTURE (priv->icon_texture),
                                     &width, &height);
-     material = _st_create_shadow_material_from_actor (shadow_spec,
+
+     material = _st_create_shadow_material_from_actor (priv->shadow_spec,
                                                        priv->icon_texture);
      priv->shadow_material = material;
      priv->shadow_width = width;
diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c
index 6e71c98..8eb2b15 100644
--- a/src/st/st-theme-node-drawing.c
+++ b/src/st/st-theme-node-drawing.c
@@ -637,8 +637,8 @@ _st_theme_node_free_drawing_state (StThemeNode  *node)
     cogl_handle_unref (node->border_texture);
   if (node->border_material != COGL_INVALID_HANDLE)
     cogl_handle_unref (node->border_material);
-  if (node->border_shadow_material != COGL_INVALID_HANDLE)
-    cogl_handle_unref (node->border_shadow_material);
+  if (node->box_shadow_material != COGL_INVALID_HANDLE)
+    cogl_handle_unref (node->box_shadow_material);
 
   for (corner_id = 0; corner_id < 4; corner_id++)
     if (node->corner_material[corner_id] != COGL_INVALID_HANDLE)
@@ -655,7 +655,7 @@ _st_theme_node_init_drawing_state (StThemeNode *node)
   node->background_texture = COGL_INVALID_HANDLE;
   node->background_material = COGL_INVALID_HANDLE;
   node->background_shadow_material = COGL_INVALID_HANDLE;
-  node->border_shadow_material = COGL_INVALID_HANDLE;
+  node->box_shadow_material = COGL_INVALID_HANDLE;
   node->border_texture = COGL_INVALID_HANDLE;
   node->border_material = COGL_INVALID_HANDLE;
 
@@ -674,7 +674,8 @@ st_theme_node_render_resources (StThemeNode   *node,
 {
   StTextureCache *texture_cache;
   StBorderImage *border_image;
-  StShadow *shadow_spec;
+  StShadow *box_shadow_spec;
+  StShadow *background_image_shadow_spec;
   const char *background_image;
 
   texture_cache = st_texture_cache_get_default ();
@@ -691,7 +692,7 @@ st_theme_node_render_resources (StThemeNode   *node,
   _st_theme_node_ensure_background (node);
   _st_theme_node_ensure_geometry (node);
 
-  shadow_spec = st_theme_node_get_shadow (node);
+  box_shadow_spec = st_theme_node_get_box_shadow (node);
 
   /* Load referenced images from disk and draw anything we need with cairo now */
 
@@ -714,11 +715,11 @@ st_theme_node_render_resources (StThemeNode   *node,
   else
     node->border_material = COGL_INVALID_HANDLE;
 
-  if (shadow_spec)
+  if (box_shadow_spec)
     {
       if (node->border_texture != COGL_INVALID_HANDLE)
-        node->border_shadow_material = _st_create_shadow_material (shadow_spec,
-                                                                   node->border_texture);
+        node->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
+                                                                node->border_texture);
       else if (node->background_color.alpha > 0 ||
                node->border_width[ST_SIDE_TOP] > 0 ||
                node->border_width[ST_SIDE_LEFT] > 0 ||
@@ -743,23 +744,25 @@ st_theme_node_render_resources (StThemeNode   *node,
               cogl_pop_framebuffer ();
               cogl_handle_unref (offscreen);
 
-              node->border_shadow_material = _st_create_shadow_material (shadow_spec,
-                                                                         buffer);
+              node->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
+                                                                      buffer);
             }
           cogl_handle_unref (buffer);
         }
     }
 
   background_image = st_theme_node_get_background_image (node);
+  background_image_shadow_spec = st_theme_node_get_background_image_shadow (node);
+
   if (background_image != NULL)
     {
 
       node->background_texture = st_texture_cache_load_file_to_cogl_texture (texture_cache, background_image);
       node->background_material = _st_create_texture_material (node->background_texture);
 
-      if (shadow_spec)
+      if (background_image_shadow_spec)
         {
-          node->background_shadow_material = _st_create_shadow_material (shadow_spec,
+          node->background_shadow_material = _st_create_shadow_material (background_image_shadow_spec,
                                                                          node->background_texture);
         }
     }
@@ -1240,9 +1243,9 @@ st_theme_node_paint (StThemeNode           *node,
    * border_image and a single background image above it.
    */
 
-  if (node->border_shadow_material)
-    _st_paint_shadow_with_opacity (node->shadow,
-                                   node->border_shadow_material,
+  if (node->box_shadow_material)
+    _st_paint_shadow_with_opacity (node->box_shadow,
+                                   node->box_shadow_material,
                                    &allocation,
                                    paint_opacity);
 
@@ -1278,7 +1281,7 @@ st_theme_node_paint (StThemeNode           *node,
        * like boder and background color into account).
        */
       if (node->background_shadow_material != COGL_INVALID_HANDLE)
-        _st_paint_shadow_with_opacity (node->shadow,
+        _st_paint_shadow_with_opacity (node->background_image_shadow,
                                        node->background_shadow_material,
                                        &background_box,
                                        paint_opacity);
@@ -1316,8 +1319,8 @@ st_theme_node_copy_cached_paint_state (StThemeNode *node,
 
   if (other->background_shadow_material)
     node->background_shadow_material = cogl_handle_ref (other->background_shadow_material);
-  if (other->border_shadow_material)
-    node->border_shadow_material = cogl_handle_ref (other->border_shadow_material);
+  if (other->box_shadow_material)
+    node->box_shadow_material = cogl_handle_ref (other->box_shadow_material);
   if (other->background_texture)
     node->background_texture = cogl_handle_ref (other->background_texture);
   if (other->background_material)
diff --git a/src/st/st-theme-node-private.h b/src/st/st-theme-node-private.h
index 7673755..ef4839e 100644
--- a/src/st/st-theme-node-private.h
+++ b/src/st/st-theme-node-private.h
@@ -65,7 +65,8 @@ struct _StThemeNode {
 
   char *background_image;
   StBorderImage *border_image;
-  StShadow *shadow;
+  StShadow *box_shadow;
+  StShadow *background_image_shadow;
   StShadow *text_shadow;
   StIconColors *icon_colors;
 
@@ -86,7 +87,8 @@ struct _StThemeNode {
   guint background_computed : 1;
   guint foreground_computed : 1;
   guint border_image_computed : 1;
-  guint shadow_computed : 1;
+  guint box_shadow_computed : 1;
+  guint background_image_shadow_computed : 1;
   guint text_shadow_computed : 1;
   guint link_type : 2;
 
@@ -95,7 +97,7 @@ struct _StThemeNode {
   float alloc_height;
 
   CoglHandle background_shadow_material;
-  CoglHandle border_shadow_material;
+  CoglHandle box_shadow_material;
   CoglHandle background_texture;
   CoglHandle background_material;
   CoglHandle border_texture;
diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c
index 4a6a121..b57afb6 100644
--- a/src/st/st-theme-node.c
+++ b/src/st/st-theme-node.c
@@ -122,10 +122,16 @@ st_theme_node_finalize (GObject *object)
       node->font_desc = NULL;
     }
 
-  if (node->shadow)
+  if (node->box_shadow)
     {
-      st_shadow_unref (node->shadow);
-      node->shadow = NULL;
+      st_shadow_unref (node->box_shadow);
+      node->box_shadow = NULL;
+    }
+
+  if (node->background_image_shadow)
+    {
+      st_shadow_unref (node->background_image_shadow);
+      node->background_image_shadow = NULL;
     }
 
   if (node->text_shadow)
@@ -2606,16 +2612,17 @@ st_theme_node_get_vertical_padding (StThemeNode *node)
   return padding;
 }
 
-static void
-parse_shadow_property (StThemeNode   *node,
-                       CRDeclaration *decl,
-                       ClutterColor  *color,
-                       gdouble       *xoffset,
-                       gdouble       *yoffset,
-                       gdouble       *blur,
-                       gdouble       *spread)
+static GetFromTermResult
+parse_shadow_property (StThemeNode       *node,
+                       CRDeclaration     *decl,
+                       ClutterColor      *color,
+                       gdouble           *xoffset,
+                       gdouble           *yoffset,
+                       gdouble           *blur,
+                       gdouble           *spread)
 {
   /* Set value for width/color/blur in any order */
+  GetFromTermResult result;
   CRTerm *term;
   int n_offsets = 0;
 
@@ -2628,8 +2635,6 @@ parse_shadow_property (StThemeNode   *node,
 
   for (term = decl->value; term; term = term->next)
     {
-      GetFromTermResult result;
-
       if (term->type == TERM_NUMBER)
         {
           gdouble value;
@@ -2637,7 +2642,16 @@ parse_shadow_property (StThemeNode   *node,
 
           multiplier = (term->unary_op == MINUS_UOP) ? -1. : 1.;
           result = get_length_from_term (node, term, FALSE, &value);
-          if (result != VALUE_NOT_FOUND)
+
+          if (result == VALUE_INHERIT)
+            {
+              /* we only allow inherit on the line by itself */
+              if (n_offsets > 0)
+                return VALUE_NOT_FOUND;
+              else
+                return VALUE_INHERIT;
+            }
+          else if (result == VALUE_FOUND)
             {
               switch (n_offsets++)
                 {
@@ -2665,32 +2679,65 @@ parse_shadow_property (StThemeNode   *node,
         }
 
       result = get_color_from_term (node, term, color);
-      if (result != VALUE_NOT_FOUND)
+
+      if (result == VALUE_INHERIT)
+        {
+          if (n_offsets > 0)
+            return VALUE_NOT_FOUND;
+          else
+            return VALUE_INHERIT;
+        }
+      else if (result == VALUE_FOUND)
         {
           continue;
         }
     }
+
+  /* The only required terms are the x and y offsets
+   */
+  if (n_offsets >= 2)
+    return VALUE_FOUND;
+  else
+    return VALUE_NOT_FOUND;
 }
 
 /**
- * st_theme_node_get_shadow:
+ * st_theme_node_lookup_shadow:
  * @node: a #StThemeNode
+ * @property_name: The name of the shadow property
+ * @inherit: if %TRUE, if a value is not found for the property on the
+ *   node, then it will be looked up on the parent node, and then on the
+ *   parent's parent, and so forth. Note that if the property has a
+ *   value of 'inherit' it will be inherited even if %FALSE is passed
+ *   in for @inherit; this only affects the default behavior for inheritance.
+ * @shadow: (out): location to store the shadow
  *
- * Gets the value for the -st-shadow style property
+ * If the property is not found, the value in the shadow variable will not
+ * be changed.
  *
- * Return value: (transfer none): the node's shadow, or %NULL
- *   if node has no shadow
+ * Generically looks up a property containing a set of shadow values. When
+ * specific getters (like st_theme_node_get_box_shadow ()) exist, they
+ * should be used instead. They are cached, so more efficient, and have
+ * handling for shortcut properties and other details of CSS.
+ *
+ * See also st_theme_node_get_shadow(), which provides a simpler API.
+ *
+ * Return value: %TRUE if the property was found in the properties for this
+ *  theme node (or in the properties of parent nodes when inheriting.)
  */
-StShadow *
-st_theme_node_get_shadow (StThemeNode *node)
+gboolean
+st_theme_node_lookup_shadow (StThemeNode  *node,
+                             const char   *property_name,
+                             gboolean      inherit,
+                             StShadow    **shadow)
 {
-  int i;
+  ClutterColor color = { 0., };
+  gdouble xoffset = 0.;
+  gdouble yoffset = 0.;
+  gdouble blur = 0.;
+  gdouble spread = 0.;
 
-  if (node->shadow_computed)
-    return node->shadow;
-
-  node->shadow = NULL;
-  node->shadow_computed = TRUE;
+  int i;
 
   ensure_properties (node);
 
@@ -2698,24 +2745,134 @@ st_theme_node_get_shadow (StThemeNode *node)
     {
       CRDeclaration *decl = node->properties[i];
 
-      if (strcmp (decl->property->stryng->str, "-st-shadow") == 0)
+      if (strcmp (decl->property->stryng->str, property_name) == 0)
         {
-          ClutterColor color;
-          gdouble xoffset;
-          gdouble yoffset;
-          gdouble blur;
-          gdouble spread;
+          GetFromTermResult result = parse_shadow_property (node,
+                                                            decl,
+                                                            &color,
+                                                            &xoffset,
+                                                            &yoffset,
+                                                            &blur,
+                                                            &spread);
+          if (result == VALUE_FOUND)
+            {
+              *shadow = st_shadow_new (&color, xoffset, yoffset, blur, spread);
+              return TRUE;
+            }
+          else if (result == VALUE_INHERIT)
+            {
+              if (node->parent_node)
+                return st_theme_node_lookup_shadow (node->parent_node,
+                                                    property_name,
+                                                    inherit,
+                                                    shadow);
+              else
+                break;
+            }
+        }
+    }
 
-          parse_shadow_property (node, decl,
-                                 &color, &xoffset, &yoffset, &blur, &spread);
+    if (inherit && node->parent_node)
+      return st_theme_node_lookup_shadow (node->parent_node,
+                                          property_name,
+                                          inherit,
+                                          shadow);
 
-          node->shadow = st_shadow_new (&color,
-                                        xoffset, yoffset,
-                                        blur, spread);
+  return FALSE;
+}
 
-          return node->shadow;
-        }
+/**
+ * st_theme_node_get_shadow:
+ * @node: a #StThemeNode
+ * @property_name: The name of the shadow property
+ *
+ * Generically looks up a property containing a set of shadow values. When
+ * specific getters (like st_theme_node_get_box_shadow()) exist, they
+ * should be used instead. They are cached, so more efficient, and have
+ * handling for shortcut properties and other details of CSS.
+ *
+ * Like st_theme_get_length(), this does not print a warning if the property is
+ * not found; it just returns %NULL
+ *
+ * See also st_theme_node_lookup_shadow (), which provides more options.
+ *
+ * Return value: (transfer full): the shadow, or %NULL if the property was not found.
+ */
+StShadow *
+st_theme_node_get_shadow (StThemeNode  *node,
+                          const char   *property_name)
+{
+  StShadow *shadow;
+
+  if (st_theme_node_lookup_shadow (node, property_name, FALSE, &shadow))
+    return shadow;
+  else
+    return NULL;
+}
+
+/**
+ * st_theme_node_get_box_shadow:
+ * @node: a #StThemeNode
+ *
+ * Gets the value for the box-shadow style property
+ *
+ * Return value: (transfer none): the node's shadow, or %NULL
+ *   if node has no shadow
+ */
+StShadow *
+st_theme_node_get_box_shadow (StThemeNode *node)
+{
+  StShadow *shadow;
+
+  if (node->box_shadow_computed)
+    return node->box_shadow;
+
+  node->box_shadow = NULL;
+  node->box_shadow_computed = TRUE;
+
+  if (st_theme_node_lookup_shadow (node,
+                                   "box-shadow",
+                                   FALSE,
+                                   &shadow))
+    {
+      node->box_shadow = shadow;
+
+      return node->box_shadow;
+    }
+
+  return NULL;
+}
+
+/**
+ * st_theme_node_get_background_image_shadow:
+ * @node: a #StThemeNode
+ *
+ * Gets the value for the -st-background-image-shadow style property
+ *
+ * Return value: (transfer none): the node's background image shadow, or %NULL
+ *   if node has no such shadow
+ */
+StShadow *
+st_theme_node_get_background_image_shadow (StThemeNode *node)
+{
+  StShadow *shadow;
+
+  if (node->background_image_shadow_computed)
+    return node->background_image_shadow;
+
+  node->background_image_shadow = NULL;
+  node->background_image_shadow_computed = TRUE;
+
+  if (st_theme_node_lookup_shadow (node,
+                                   "-st-background-image-shadow",
+                                   FALSE,
+                                   &shadow))
+    {
+      node->background_image_shadow = shadow;
+
+      return node->background_image_shadow;
     }
+
   return NULL;
 }
 
@@ -2732,43 +2889,25 @@ StShadow *
 st_theme_node_get_text_shadow (StThemeNode *node)
 {
   StShadow *result = NULL;
-  int i;
 
   if (node->text_shadow_computed)
     return node->text_shadow;
 
   ensure_properties (node);
 
-  for (i = node->n_properties - 1; i >= 0; i--)
+  if (!st_theme_node_lookup_shadow (node,
+                                    "text-shadow",
+                                    FALSE,
+                                    &result))
     {
-      CRDeclaration *decl = node->properties[i];
-
-      if (strcmp (decl->property->stryng->str, "text-shadow") == 0)
+      if (node->parent_node)
         {
-          ClutterColor color;
-          gdouble xoffset;
-          gdouble yoffset;
-          gdouble blur;
-          gdouble spread;
-
-          parse_shadow_property (node, decl,
-                                 &color, &xoffset, &yoffset, &blur, &spread);
-
-          result = st_shadow_new (&color,
-                                  xoffset, yoffset,
-                                  blur, spread);
-
-          break;
+          result = st_theme_node_get_text_shadow (node->parent_node);
+          if (result)
+            st_shadow_ref (result);
         }
     }
 
-  if (!result && node->parent_node)
-    {
-      result = st_theme_node_get_text_shadow (node->parent_node);
-      if (result)
-        st_shadow_ref (result);
-    }
-
   node->text_shadow = result;
   node->text_shadow_computed = TRUE;
 
@@ -3102,7 +3241,8 @@ st_theme_node_get_paint_box (StThemeNode           *node,
                              const ClutterActorBox *actor_box,
                              ClutterActorBox       *paint_box)
 {
-  StShadow *shadow;
+  StShadow *box_shadow;
+  StShadow *background_image_shadow;
   ClutterActorBox shadow_box;
   int outline_width;
 
@@ -3110,26 +3250,41 @@ st_theme_node_get_paint_box (StThemeNode           *node,
   g_return_if_fail (actor_box != NULL);
   g_return_if_fail (paint_box != NULL);
 
-  shadow = st_theme_node_get_shadow (node);
+  box_shadow = st_theme_node_get_box_shadow (node);
+  background_image_shadow = st_theme_node_get_background_image_shadow (node);
   outline_width = st_theme_node_get_outline_width (node);
-  if (!shadow && !outline_width)
+
+  *paint_box = *actor_box;
+
+  if (!box_shadow && !background_image_shadow && !outline_width)
+    return;
+
+  paint_box->x1 -= outline_width;
+  paint_box->x2 += outline_width;
+  paint_box->y1 -= outline_width;
+  paint_box->y2 += outline_width;
+
+  if (box_shadow)
     {
-      *paint_box = *actor_box;
-      return;
+      st_shadow_get_box (box_shadow, actor_box, &shadow_box);
+
+      paint_box->x1 = MIN (paint_box->x1, shadow_box.x1);
+      paint_box->x2 = MAX (paint_box->x2, shadow_box.x2);
+      paint_box->y1 = MIN (paint_box->y1, shadow_box.y1);
+      paint_box->y2 = MAX (paint_box->y2, shadow_box.y2);
     }
 
-  if (shadow)
-    st_shadow_get_box (shadow, actor_box, &shadow_box);
-  else
-    shadow_box = *actor_box;
+  if (background_image_shadow)
+    {
+      st_shadow_get_box (background_image_shadow, actor_box, &shadow_box);
 
-  paint_box->x1 = MIN (actor_box->x1 - outline_width, shadow_box.x1);
-  paint_box->x2 = MAX (actor_box->x2 + outline_width, shadow_box.x2);
-  paint_box->y1 = MIN (actor_box->y1 - outline_width, shadow_box.y1);
-  paint_box->y2 = MAX (actor_box->y2 + outline_width, shadow_box.y2);
+      paint_box->x1 = MIN (paint_box->x1, shadow_box.x1);
+      paint_box->x2 = MAX (paint_box->x2, shadow_box.x2);
+      paint_box->y1 = MIN (paint_box->y1, shadow_box.y1);
+      paint_box->y2 = MAX (paint_box->y2, shadow_box.y2);
+    }
 }
 
-
 /**
  * st_theme_node_geometry_equal:
  * @node: a #StThemeNode
@@ -3240,8 +3395,17 @@ st_theme_node_paint_equal (StThemeNode *node,
   if (border_image != NULL && !st_border_image_equal (border_image, other_border_image))
     return FALSE;
 
-  shadow = st_theme_node_get_shadow (node);
-  other_shadow = st_theme_node_get_shadow (other);
+  shadow = st_theme_node_get_box_shadow (node);
+  other_shadow = st_theme_node_get_box_shadow (other);
+
+  if ((shadow == NULL) != (other_shadow == NULL))
+    return FALSE;
+
+  if (shadow != NULL && !st_shadow_equal (shadow, other_shadow))
+    return FALSE;
+
+  shadow = st_theme_node_get_background_image_shadow (node);
+  other_shadow = st_theme_node_get_background_image_shadow (other);
 
   if ((shadow == NULL) != (other_shadow == NULL))
     return FALSE;
diff --git a/src/st/st-theme-node.h b/src/st/st-theme-node.h
index 13e0bf6..ad9e4e0 100644
--- a/src/st/st-theme-node.h
+++ b/src/st/st-theme-node.h
@@ -133,6 +133,10 @@ gboolean st_theme_node_lookup_length (StThemeNode *node,
                                       const char  *property_name,
                                       gboolean     inherit,
                                       gdouble     *length);
+gboolean st_theme_node_lookup_shadow (StThemeNode  *node,
+                                      const char   *property_name,
+                                      gboolean      inherit,
+                                      StShadow    **shadow);
 
 /* Easier-to-use variants of the above, for application-level use */
 void          st_theme_node_get_color  (StThemeNode  *node,
@@ -142,6 +146,8 @@ gdouble       st_theme_node_get_double (StThemeNode  *node,
                                         const char   *property_name);
 gdouble       st_theme_node_get_length (StThemeNode  *node,
                                         const char   *property_name);
+StShadow     *st_theme_node_get_shadow (StThemeNode  *node,
+                                        const char   *property_name);
 
 /* Specific getters for particular properties: cached
  */
@@ -195,9 +201,11 @@ StTextAlign st_theme_node_get_text_align (StThemeNode *node);
 const PangoFontDescription *st_theme_node_get_font (StThemeNode *node);
 
 StBorderImage *st_theme_node_get_border_image (StThemeNode *node);
-StShadow      *st_theme_node_get_shadow       (StThemeNode *node);
+StShadow      *st_theme_node_get_box_shadow   (StThemeNode *node);
 StShadow      *st_theme_node_get_text_shadow  (StThemeNode *node);
 
+StShadow      *st_theme_node_get_background_image_shadow (StThemeNode *node);
+
 StIconColors  *st_theme_node_get_icon_colors  (StThemeNode *node);
 
 /* Helpers for get_preferred_width()/get_preferred_height() ClutterActor vfuncs */
diff --git a/tests/interactive/borders.js b/tests/interactive/borders.js
index 5c97ea1..ba8d1e0 100644
--- a/tests/interactive/borders.js
+++ b/tests/interactive/borders.js
@@ -93,14 +93,14 @@ function addGradientCase(direction, borderWidth, borderRadius, extra) {
     framedGradients.add(gradientBox, { x_fill: false, y_fill: false } );
 }
 
-addGradientCase ('horizontal', 0, 5,  '-st-shadow: 0px 0px 0px 0px rgba(0,0,0,0.5);');
-addGradientCase ('horizontal', 2, 5,  '-st-shadow: 0px 2px 0px 0px rgba(0,255,0,0.5);');
-addGradientCase ('horizontal', 5, 2,  '-st-shadow: 2px 0px 0px 0px rgba(0,0,255,0.5);');
-addGradientCase ('horizontal', 5, 20, '-st-shadow: 0px 0px 4px 0px rgba(255,0,0,0.5);');
-addGradientCase ('vertical', 0, 5,    '-st-shadow: 0px 0px 0px 4px rgba(0,0,0,0.5);');
-addGradientCase ('vertical', 2, 5,    '-st-shadow: 0px 0px 4px 4px rgba(0,0,0,0.5);');
-addGradientCase ('vertical', 5, 2,    '-st-shadow: -2px -2px 6px 0px rgba(0,0,0,0.5);');
-addGradientCase ('vertical', 5, 20,   '-st-shadow: -2px -2px 0px 6px rgba(0,0,0,0.5);');
+addGradientCase ('horizontal', 0, 5,  'box-shadow: 0px 0px 0px 0px rgba(0,0,0,0.5);');
+addGradientCase ('horizontal', 2, 5,  'box-shadow: 0px 2px 0px 0px rgba(0,255,0,0.5);');
+addGradientCase ('horizontal', 5, 2,  'box-shadow: 2px 0px 0px 0px rgba(0,0,255,0.5);');
+addGradientCase ('horizontal', 5, 20, 'box-shadow: 0px 0px 4px 0px rgba(255,0,0,0.5);');
+addGradientCase ('vertical', 0, 5,    'box-shadow: 0px 0px 0px 4px rgba(0,0,0,0.5);');
+addGradientCase ('vertical', 2, 5,    'box-shadow: 0px 0px 4px 4px rgba(0,0,0,0.5);');
+addGradientCase ('vertical', 5, 2,    'box-shadow: -2px -2px 6px 0px rgba(0,0,0,0.5);');
+addGradientCase ('vertical', 5, 20,   'box-shadow: -2px -2px 0px 6px rgba(0,0,0,0.5);');
 
 box.add(new St.Label({ text: "Rounded, framed, shadowed images" }));
 
@@ -119,15 +119,15 @@ function addBackgroundImageCase(borderWidth, borderRadius, width, height, extra)
 }
 
 addBackgroundImageCase (0, 0, 32, 32, 'background-position: 2px 5px');
-addBackgroundImageCase (0, 0, 16, 16, '-st-shadow: 1px 1px 4px 0px rgba(0,0,0,0.5); background-color: rgba(0,0,0,0)');
-addBackgroundImageCase (0, 5, 32, 32, '-st-shadow: 0px 0px 0px 0px rgba(0,0,0,0.5);');
-addBackgroundImageCase (2, 5, 32, 32, '-st-shadow: 0px 2px 0px 0px rgba(0,255,0,0.5);');
-addBackgroundImageCase (5, 2, 32, 32, '-st-shadow: 2px 0px 0px 0px rgba(0,0,255,0.5);');
-addBackgroundImageCase (5, 20, 32, 32, '-st-shadow: 0px 0px 4px 0px rgba(255,0,0,0.5);');
-addBackgroundImageCase (0, 5, 48, 48, '-st-shadow: 0px 0px 0px 4px rgba(0,0,0,0.5);');
-addBackgroundImageCase (5, 5, 48, 48, '-st-shadow: 0px 0px 4px 4px rgba(0,0,0,0.5);');
-addBackgroundImageCase (0, 5, 64, 64, '-st-shadow: -2px -2px 6px 0px rgba(0,0,0,0.5);');
-addBackgroundImageCase (5, 5, 64, 64, '-st-shadow: -2px -2px 0px 6px rgba(0,0,0,0.5);');
+addBackgroundImageCase (0, 0, 16, 16, '-st-background-image-shadow: 1px 1px 4px 0px rgba(0,0,0,0.5); background-color: rgba(0,0,0,0)');
+addBackgroundImageCase (0, 5, 32, 32, '-st-background-image-shadow: 0px 0px 0px 0px rgba(0,0,0,0.5);');
+addBackgroundImageCase (2, 5, 32, 32, '-st-background-image-shadow: 0px 2px 0px 0px rgba(0,255,0,0.5);');
+addBackgroundImageCase (5, 2, 32, 32, '-st-background-image-shadow: 2px 0px 0px 0px rgba(0,0,255,0.5);');
+addBackgroundImageCase (5, 20, 32, 32, '-st-background-image-shadow: 0px 0px 4px 0px rgba(255,0,0,0.5);');
+addBackgroundImageCase (0, 5, 48, 48, '-st-background-image-shadow: 0px 0px 0px 4px rgba(0,0,0,0.5);');
+addBackgroundImageCase (5, 5, 48, 48, '-st-background-image-shadow: 0px 0px 4px 4px rgba(0,0,0,0.5);');
+addBackgroundImageCase (0, 5, 64, 64, '-st-background-image-shadow: -2px -2px 6px 0px rgba(0,0,0,0.5);');
+addBackgroundImageCase (5, 5, 64, 64, '-st-background-image-shadow: -2px -2px 0px 6px rgba(0,0,0,0.5);');
 addBackgroundImageCase (0, 5, 32, 32, 'background-position: 2px 5px');
 
 stage.show();



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