@@ -1096,6 +1096,10 @@ meta_color_spec_new (MetaColorSpecType type)
10961096 size += sizeof (dummy .data .gtk );
10971097 break ;
10981098
1099+ case META_COLOR_SPEC_GTK_CUSTOM :
1100+ size += sizeof (dummy .data .gtkcustom );
1101+ break ;
1102+
10991103 case META_COLOR_SPEC_BLEND :
11001104 size += sizeof (dummy .data .blend );
11011105 break ;
@@ -1127,6 +1131,14 @@ meta_color_spec_free (MetaColorSpec *spec)
11271131 DEBUG_FILL_STRUCT (& spec -> data .gtk );
11281132 break ;
11291133
1134+ case META_COLOR_SPEC_GTK_CUSTOM :
1135+ if (spec -> data .gtkcustom .color_name )
1136+ g_free (spec -> data .gtkcustom .color_name );
1137+ if (spec -> data .gtkcustom .fallback )
1138+ meta_color_spec_free (spec -> data .gtkcustom .fallback );
1139+ DEBUG_FILL_STRUCT (& spec -> data .gtkcustom );
1140+ break ;
1141+
11301142 case META_COLOR_SPEC_BLEND :
11311143 if (spec -> data .blend .foreground )
11321144 meta_color_spec_free (spec -> data .blend .foreground );
@@ -1153,7 +1165,67 @@ meta_color_spec_new_from_string (const char *str,
11531165
11541166 spec = NULL ;
11551167
1156- if (str [0 ] == 'g' && str [1 ] == 't' && str [2 ] == 'k' && str [3 ] == ':' )
1168+ if (str [0 ] == 'g' && str [1 ] == 't' && str [2 ] == 'k' && str [3 ] == ':' &&
1169+ str [4 ] == 'c' && str [5 ] == 'u' && str [6 ] == 's' && str [7 ] == 't' &&
1170+ str [8 ] == 'o' && str [9 ] == 'm' )
1171+ {
1172+ const char * color_name_start , * fallback_str_start , * end ;
1173+ char * color_name , * fallback_str ;
1174+ MetaColorSpec * fallback = NULL ;
1175+
1176+ if (str [10 ] != '(' )
1177+ {
1178+ g_set_error (err , META_THEME_ERROR ,
1179+ META_THEME_ERROR_FAILED ,
1180+ _ ("GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" ),
1181+ str );
1182+ return NULL ;
1183+ }
1184+
1185+ color_name_start = str + 11 ;
1186+
1187+ fallback_str_start = color_name_start ;
1188+ while (* fallback_str_start && * fallback_str_start != ',' )
1189+ {
1190+ if (!(g_ascii_isalnum (* fallback_str_start )
1191+ || * fallback_str_start == '-'
1192+ || * fallback_str_start == '_' ))
1193+ {
1194+ g_set_error (err , META_THEME_ERROR ,
1195+ META_THEME_ERROR_FAILED ,
1196+ _ ("Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" ),
1197+ * fallback_str_start );
1198+ return NULL ;
1199+ }
1200+ fallback_str_start ++ ;
1201+ }
1202+ fallback_str_start ++ ;
1203+
1204+ end = strrchr (str , ')' );
1205+
1206+ if (color_name_start == NULL || fallback_str_start == NULL || end == NULL )
1207+ {
1208+ g_set_error (err , META_THEME_ERROR ,
1209+ META_THEME_ERROR_FAILED ,
1210+ _ ("Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" ),
1211+ str );
1212+ return NULL ;
1213+ }
1214+
1215+ fallback_str = g_strndup (fallback_str_start , end - fallback_str_start );
1216+ fallback = meta_color_spec_new_from_string (fallback_str , err );
1217+ g_free (fallback_str );
1218+
1219+ if (fallback == NULL )
1220+ return NULL ;
1221+
1222+ color_name = g_strndup (color_name_start , fallback_str_start - color_name_start - 1 );
1223+
1224+ spec = meta_color_spec_new (META_COLOR_SPEC_GTK_CUSTOM );
1225+ spec -> data .gtkcustom .color_name = color_name ;
1226+ spec -> data .gtkcustom .fallback = fallback ;
1227+ }
1228+ else if (str [0 ] == 'g' && str [1 ] == 't' && str [2 ] == 'k' && str [3 ] == ':' )
11571229 {
11581230 /* GTK color */
11591231 const char * bracket ;
@@ -1497,6 +1569,16 @@ meta_set_color_from_style (GdkRGBA *color,
14971569 }
14981570}
14991571
1572+ static void
1573+ meta_set_custom_color_from_style (GdkRGBA * color ,
1574+ GtkStyleContext * context ,
1575+ char * color_name ,
1576+ MetaColorSpec * fallback )
1577+ {
1578+ if (!gtk_style_context_lookup_color (context , color_name , color ))
1579+ meta_color_spec_render (fallback , context , color );
1580+ }
1581+
15001582void
15011583meta_color_spec_render (MetaColorSpec * spec ,
15021584 GtkStyleContext * style ,
@@ -1519,6 +1601,13 @@ meta_color_spec_render (MetaColorSpec *spec,
15191601 spec -> data .gtk .component );
15201602 break ;
15211603
1604+ case META_COLOR_SPEC_GTK_CUSTOM :
1605+ meta_set_custom_color_from_style (color ,
1606+ style ,
1607+ spec -> data .gtkcustom .color_name ,
1608+ spec -> data .gtkcustom .fallback );
1609+ break ;
1610+
15221611 case META_COLOR_SPEC_BLEND :
15231612 {
15241613 GdkRGBA bg , fg ;
0 commit comments