mirror of
https://github.com/brl/mutter.git
synced 2025-06-13 16:59:30 +00:00
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
This commit is contained in:
@ -38,7 +38,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"
|
||||
|
@ -281,6 +281,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;
|
||||
@ -310,6 +311,10 @@ struct _MetaColorSpec
|
||||
MetaGtkColorComponent component;
|
||||
GtkStateFlags state;
|
||||
} gtk;
|
||||
struct {
|
||||
char *color_name;
|
||||
MetaColorSpec *fallback;
|
||||
} gtkcustom;
|
||||
struct {
|
||||
MetaColorSpec *foreground;
|
||||
MetaColorSpec *background;
|
||||
|
@ -1118,6 +1118,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;
|
||||
@ -1149,6 +1153,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);
|
||||
@ -1179,7 +1191,68 @@ meta_color_spec_new_from_string (const char *str,
|
||||
|
||||
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;
|
||||
@ -1479,6 +1552,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,
|
||||
@ -1500,6 +1583,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;
|
||||
|
Reference in New Issue
Block a user