[metacity] theme: Allow using custom colors from the GTK+ theme



commit c54ab841b342e65a8d4363b5b911ccf9fac0a880
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Sep 27 18:25:31 2014 +0300

    theme: Allow using custom colors from the GTK+ theme
    
    Add an additional color type to pick up colors defined with
    @define-color in the GTK+ theme's CSS:
    
      gtk:custom(name,fallback)
    
    (where "name" refers to the name defined in GTK+'s CSS, and fallback
    refers to an alternative color spec which is used when the color
    referenced by "name" is not found)
    
    The main intent of the change is to allow designers to improve
    Adwaita's dark theme variant without having to compromise on colors
    which work in the light variant as well.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=648709
    
    NOTE: Patch copied from mutter and adapted for metacity.

 doc/theme-format.txt  |   12 ++++++
 src/ui/theme-parser.c |    2 +-
 src/ui/theme.c        |   93 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/ui/theme.h        |    5 +++
 4 files changed, 109 insertions(+), 3 deletions(-)
---
diff --git a/doc/theme-format.txt b/doc/theme-format.txt
index ba68fe1..3ecfbbc 100644
--- a/doc/theme-format.txt
+++ b/doc/theme-format.txt
@@ -22,6 +22,18 @@ This document has separate sections for each format version. You may
 want to read the document in reverse order, since the base features
 are discussed under version 1.
 
+New Features in Theme Format Version 3.4
+========================================
+
+An additional color type is added to pick up custom colors defined
+in the GTK+ theme's CSS:
+
+  gtk:custom(name,fallback)
+
+where <name> refers to a custom color defined with @define-color in
+the GTK+ theme, and <fallback> provides an alternative color definition
+in case the color referenced by <name> is not found.
+
 New Features in Theme Format Version 3.3
 ========================================
 
diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c
index a714433..5b641cd 100644
--- a/src/ui/theme-parser.c
+++ b/src/ui/theme-parser.c
@@ -36,7 +36,7 @@
  * look out for.
  */
 #define THEME_MAJOR_VERSION 3
-#define THEME_MINOR_VERSION 3
+#define THEME_MINOR_VERSION 4
 #define THEME_VERSION (1000 * THEME_MAJOR_VERSION + THEME_MINOR_VERSION)
 
 #define METACITY_THEME_FILENAME_FORMAT "metacity-theme-%d.xml"
diff --git a/src/ui/theme.c b/src/ui/theme.c
index 7a1fc12..0063855 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -1139,6 +1139,10 @@ meta_color_spec_new (MetaColorSpecType type)
       size += sizeof (dummy.data.gtk);
       break;
 
+    case META_COLOR_SPEC_GTK_CUSTOM:
+      size += sizeof (dummy.data.gtkcustom);
+      break;
+
     case META_COLOR_SPEC_BLEND:
       size += sizeof (dummy.data.blend);
       break;
@@ -1170,6 +1174,14 @@ meta_color_spec_free (MetaColorSpec *spec)
       DEBUG_FILL_STRUCT (&spec->data.gtk);
       break;
 
+    case META_COLOR_SPEC_GTK_CUSTOM:
+      if (spec->data.gtkcustom.color_name)
+        g_free (spec->data.gtkcustom.color_name);
+      if (spec->data.gtkcustom.fallback)
+        meta_color_spec_free (spec->data.gtkcustom.fallback);
+      DEBUG_FILL_STRUCT (&spec->data.gtkcustom);
+      break;
+
     case META_COLOR_SPEC_BLEND:
       if (spec->data.blend.foreground)
         meta_color_spec_free (spec->data.blend.foreground);
@@ -1195,8 +1207,68 @@ meta_color_spec_new_from_string (const char *str,
   MetaColorSpec *spec;
 
   spec = NULL;
-  
-  if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':')
+
+  if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':' &&
+      str[4] == 'c' && str[5] == 'u' && str[6] == 's' && str[7] == 't' &&
+      str[8] == 'o' && str[9] == 'm')
+    {
+      const char *color_name_start, *fallback_str_start, *end;
+      char *color_name, *fallback_str;
+      MetaColorSpec *fallback = NULL;
+
+      if (str[10] != '(')
+        {
+          g_set_error (err, META_THEME_ERROR,
+                       META_THEME_ERROR_FAILED,
+                       _("GTK custom color specification must have color name and fallback in parentheses, 
e.g. gtk:custom(foo,bar); could not parse \"%s\""),
+                       str);
+          return NULL;
+        }
+
+      color_name_start = str + 11;
+
+      fallback_str_start = color_name_start;
+      while (*fallback_str_start && *fallback_str_start != ',')
+        {
+          if (!(g_ascii_isalnum (*fallback_str_start)
+                || *fallback_str_start == '-'
+                || *fallback_str_start == '_'))
+            {
+              g_set_error (err, META_THEME_ERROR,
+                           META_THEME_ERROR_FAILED,
+                           _("Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ 
are valid"),
+                           *fallback_str_start);
+              return NULL;
+            }
+          fallback_str_start++;
+        }
+      fallback_str_start++;
+
+      end = strrchr (str, ')');
+
+      if (color_name_start == NULL || fallback_str_start == NULL || end == NULL)
+        {
+          g_set_error (err, META_THEME_ERROR,
+                       META_THEME_ERROR_FAILED,
+                       _("Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the 
format"),
+                       str);
+          return NULL;
+        }
+
+      fallback_str = g_strndup (fallback_str_start, end - fallback_str_start);
+      fallback = meta_color_spec_new_from_string (fallback_str, err);
+      g_free (fallback_str);
+
+      if (fallback == NULL)
+        return NULL;
+
+      color_name = g_strndup (color_name_start, fallback_str_start - color_name_start - 1);
+
+      spec = meta_color_spec_new (META_COLOR_SPEC_GTK_CUSTOM);
+      spec->data.gtkcustom.color_name = color_name;
+      spec->data.gtkcustom.fallback = fallback;
+    }
+  else if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':')
     {
       /* GTK color */
       const char *bracket;
@@ -1491,6 +1563,16 @@ meta_set_color_from_style (GdkRGBA               *color,
     }
 }
 
+static void
+meta_set_custom_color_from_style (GdkRGBA         *color,
+                                  GtkStyleContext *context,
+                                  char            *color_name,
+                                  MetaColorSpec   *fallback)
+{
+  if (!gtk_style_context_lookup_color (context, color_name, color))
+    meta_color_spec_render (fallback, context, color);
+}
+
 void
 meta_color_spec_render (MetaColorSpec *spec,
                         GtkStyleContext *context,
@@ -1512,6 +1594,13 @@ meta_color_spec_render (MetaColorSpec *spec,
                                  spec->data.gtk.component);
       break;
 
+    case META_COLOR_SPEC_GTK_CUSTOM:
+      meta_set_custom_color_from_style (color,
+                                        context,
+                                        spec->data.gtkcustom.color_name,
+                                        spec->data.gtkcustom.fallback);
+      break;
+
     case META_COLOR_SPEC_BLEND:
       {
         GdkRGBA bg, fg;
diff --git a/src/ui/theme.h b/src/ui/theme.h
index 3bedb8f..ac524ef 100644
--- a/src/ui/theme.h
+++ b/src/ui/theme.h
@@ -278,6 +278,7 @@ typedef enum
 {
   META_COLOR_SPEC_BASIC,
   META_COLOR_SPEC_GTK,
+  META_COLOR_SPEC_GTK_CUSTOM,
   META_COLOR_SPEC_BLEND,
   META_COLOR_SPEC_SHADE
 } MetaColorSpecType;
@@ -308,6 +309,10 @@ struct _MetaColorSpec
       GtkStateFlags state;
     } gtk;
     struct {
+      char *color_name;
+      MetaColorSpec *fallback;
+    } gtkcustom;
+    struct {
       MetaColorSpec *foreground;
       MetaColorSpec *background;
       double alpha;


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