Go to the documentation of this file.
29 #define G_LOG_DOMAIN "Theme"
39 #include "theme-parser.h"
47 void yyerror ( YYLTYPE *yylloc,
const char *,
const char * );
56 return g_strdup ( data );
61 for (
unsigned int i = 0; i < base->
num_widgets; i++ ) {
62 if ( g_strcmp0 ( base->
widgets[i]->
name, name ) == 0 ) {
71 retv->
name = g_strdup ( name );
197 GHashTable *table = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)
rofi_theme_property_free );
204 ptc->
name = g_strdup (
"text-color" );
205 g_hash_table_replace ( table, ptc->
name, ptc );
208 ptb->
name = g_strdup (
"background-color" );
213 g_hash_table_replace ( table, ptb->
name, ptb );
220 pts->
name = g_strdup (
"size" );
221 g_hash_table_replace ( table, pts->
name, pts );
226 g_hash_table_destroy ( table );
229 psp->
name = g_strdup (
"spacing" );
232 g_hash_table_replace ( table, psp->
name, psp );
234 g_hash_table_destroy ( table );
251 if (
widget->properties ) {
252 g_hash_table_destroy (
widget->properties );
253 widget->properties = NULL;
258 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
261 g_free (
widget->widgets );
271 char buf[G_ASCII_DTOSTR_BUF_SIZE];
272 g_ascii_formatd ( buf, G_ASCII_DTOSTR_BUF_SIZE,
"%.4lf", d );
273 fputs ( buf, stdout );
279 fputs (
"( ", stdout );
286 fputs (
" + ", stdout );
289 fputs (
" - ", stdout );
292 fputs (
" / ", stdout );
295 fputs (
" * ", stdout );
298 fputs (
" % ", stdout );
306 printf (
"%upx ", (
unsigned int) unit->
distance );
310 fputs (
"mm ", stdout );
314 fputs (
"% ", stdout );
318 fputs (
"ch ", stdout );
322 fputs (
"em ", stdout );
326 fputs (
" )", stdout );
333 fputs (
"calc( ", stdout );
337 fputs (
")", stdout );
362 for ( GList *iter = p->
value.
list; iter != NULL; iter = g_list_next ( iter ) ) {
363 printf (
"%s", (
char *) ( iter->data ) );
364 if ( iter->next != NULL ) {
378 printf (
"underline " );
381 printf (
"strikethrough " );
384 printf (
"italic " );
387 printf (
"rgba ( %.0f, %.0f, %.0f, %.0f %% )",
398 printf (
"\"%s\"", p->
value.
s );
401 printf (
"%d", p->
value.
i );
404 printf (
"%.2f", p->
value.
f );
407 printf (
"%s", p->
value.
b ?
"true" :
"false" );
410 printf (
"rgba ( %.0f, %.0f, %.0f, %.0f %% )",
451 printf (
"inherit" );
460 int pl = strlen ( p->
name );
461 printf (
"%*s%s:%*s ",
depth,
"", p->
name, (
int) pnl - pl,
"" );
471 if (
widget->properties ) {
476 if ( g_strcmp0 ( w->
name,
"Root" ) == 0 ) {
479 list = g_list_prepend ( list, w->
name );
482 if ( g_list_length ( list ) > 0 ) {
484 for ( GList *iter = g_list_first ( list ); iter != NULL; iter = g_list_next ( iter ) ) {
485 char *name = (
char *) iter->data;
486 fputs ( name, stdout );
487 if ( iter->prev == NULL && iter->next ) {
490 else if ( iter->next ) {
500 size_t property_name_length = 0;
501 g_hash_table_iter_init ( &iter,
widget->properties );
502 while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
504 property_name_length = MAX ( strlen ( p->
name ), property_name_length );
506 g_hash_table_iter_init ( &iter,
widget->properties );
507 while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
512 g_list_free ( list );
514 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
521 printf (
"/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n", PACKAGE_VERSION );
548 void yyerror ( YYLTYPE *yylloc,
const char *what,
const char* s )
550 char *what_esc = what ? g_markup_escape_text ( what, -1 ) : g_strdup (
"" );
551 GString *str = g_string_new (
"" );
552 g_string_printf ( str,
"<big><b>Error while parsing theme:</b></big> <i>%s</i>\n", what_esc );
554 char *esc = g_markup_escape_text ( s, -1 );
555 g_string_append_printf ( str,
"\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n", esc );
557 if ( yylloc->filename != NULL ) {
558 g_string_append_printf ( str,
"\tLocation: line %d column %d to line %d column %d.\n" \
559 "\tFile '%s'\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column, yylloc->filename );
562 g_string_append_printf ( str,
"\tLocation: line %d column %d to line %d column %d\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column );
564 g_log (
"Parser", G_LOG_LEVEL_DEBUG,
"Failed to parse theme:\n%s", str->str );
570 GHashTable *table = (GHashTable *) user_data;
572 g_hash_table_replace ( table, p->
name, p );
576 if ( table == NULL ) {
579 if (
widget->properties == NULL ) {
591 for (
unsigned int j = 0;
widget && j <
widget->num_widgets; j++ ) {
592 if ( g_strcmp0 (
widget->widgets[j]->
name, name ) == 0 ) {
593 return widget->widgets[j];
601 if (
widget == NULL || name == NULL ) {
604 char *tname = g_strdup ( name );
605 char *saveptr = NULL;
607 for (
const char *iter = strtok_r ( tname,
".", &saveptr ); iter != NULL; iter = strtok_r ( NULL,
".", &saveptr ) ) {
619 if ( !exact || found ) {
633 g_warning (
"Found more then 20 redirects for property. Stopping." );
668 if (
widget->properties && g_hash_table_contains (
widget->properties, property ) ) {
669 Property *p = g_hash_table_lookup (
widget->properties, property );
682 if ( p->
type == type ) {
689 g_debug (
"Found property: '%s' on '%s', but type %s does not match expected type %s.",
838 return (
double) p->
value.
i;
854 cairo_set_source_rgba ( d,
902 char **r = defaults ? g_strsplit ( defaults,
",", 0 ) : NULL;
905 for (
int i = 0; r[i] != NULL; i++ ) {
906 l = g_list_append ( l, r[i] );
945 val = ( unit->
distance * height ) / ( 100.0 );
950 val = ( unit->
distance * width ) / ( 100.0 );
1004 const double dashes[1] = { 4 };
1005 cairo_set_dash ( draw, dashes, 1, 0.0 );
1008 cairo_set_dash ( draw, NULL, 0, 0.0 );
1033 #ifdef THEME_CONVERTER
1035 static char * rofi_theme_convert_color (
char *col )
1037 char *r = g_strstrip ( col );
1038 if ( *r ==
'#' && strlen ( r ) == 9 ) {
1053 void rofi_theme_convert_old (
void )
1062 const char *
const conf[] = {
1063 "* { background: %s; }",
1064 "* { border-color: %s; }",
1065 "* { separatorcolor: %s; }"
1067 for (
int i = 0; retv && i < 3 && retv[i]; i++ ) {
1068 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1072 g_strfreev ( retv );
1076 const char *
const conf[] = {
1077 "* { normal-background: %s; }",
1078 "* { foreground: %s; normal-foreground: @foreground; alternate-normal-foreground: @foreground; }",
1079 "* { alternate-normal-background: %s; }",
1080 "* { selected-normal-background: %s; }",
1081 "* { selected-normal-foreground: %s; }"
1083 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
1084 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1088 g_strfreev ( retv );
1092 const char *
const conf[] = {
1093 "* { urgent-background: %s; }",
1094 "* { urgent-foreground: %s; alternate-urgent-foreground: @urgent-foreground;}",
1095 "* { alternate-urgent-background: %s; }",
1096 "* { selected-urgent-background: %s; }",
1097 "* { selected-urgent-foreground: %s; }"
1099 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
1100 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1104 g_strfreev ( retv );
1108 const char *
const conf[] = {
1109 "* { active-background: %s; }",
1110 "* { active-foreground: %s; alternate-active-foreground: @active-foreground;}",
1111 "* { alternate-active-background: %s; }",
1112 "* { selected-active-background: %s; }",
1113 "* { selected-active-foreground: %s; }"
1115 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
1116 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1120 g_strfreev ( retv );
1125 const char *
const str =
"#listview { border: 0px; }";
1127 const char *
const str2 =
"#mode-switcher { border: 0px; }";
1129 const char *
const str3 =
"#message { border: 0px; }";
1133 const char *
const str =
"#listview { border: 2px solid 0px 0px 0px; }";
1135 const char *
const str2 =
"#mode-switcher { border: 2px solid 0px 0px 0px; }";
1137 const char *
const str3 =
"#message { border: 2px solid 0px 0px 0px; }";
1143 char *str = g_strdup_printf (
"#listview { spacing: %dpx;}",
config.
line_margin );
1149 char *str = g_strdup_printf (
"#element, inputbar, message { padding: %dpx;}",
config.
line_padding );
1154 const char *str =
"#listview { scrollbar: false; }";
1158 const char *str =
"#listview { scrollbar: true; }";
1170 #endif // THEME_CONVERTER
1176 if ( parent_file != NULL && !g_path_is_absolute ( filename ) ) {
1177 char *basedir = g_path_get_dirname ( parent_file );
1178 char *path = g_build_filename ( basedir, filename, NULL );
1179 g_free ( filename );
1183 GFile *gf = g_file_new_for_path ( filename );
1184 g_free ( filename );
1185 filename = g_file_get_path ( gf );
1186 g_object_unref ( gf );
1193 g_assert ( parent != NULL );
1194 g_assert ( child != NULL );
1196 if ( parent ==
rofi_theme && g_strcmp0 ( child->
name,
"*" ) == 0 ) {
1203 for (
unsigned int i = 0; i < child->
num_widgets; i++ ) {
1217 if (
widget->media != NULL ) {
1222 int w =
widget->media->value;
1224 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1232 int w =
widget->media->value;
1234 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1242 int h =
widget->media->value;
1244 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1252 int h =
widget->media->value;
1254 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1263 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1271 double r =
widget->media->value;
1272 if ( (
mon.
w / (
double)
mon.
h ) >= r ) {
1273 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1281 double r =
widget->media->value;
1282 if ( (
mon.
w / (
double)
mon.
h ) < r ) {
1283 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1300 if ( g_strcmp0 ( type,
"monitor-id" ) == 0 ) {
1303 else if ( g_strcmp0 ( type,
"min-width" ) == 0 ) {
1306 else if ( g_strcmp0 ( type,
"min-height" ) == 0 ) {
1309 else if ( g_strcmp0 ( type,
"max-width" ) == 0 ) {
1312 else if ( g_strcmp0 ( type,
"max-height" ) == 0 ) {
1315 else if ( g_strcmp0 ( type,
"min-aspect-ratio" ) == 0 ) {
1318 else if ( g_strcmp0 ( type,
"max-aspect-ratio" ) == 0 ) {
int rofi_theme_get_position(const widget *widget, const char *property, int def)
static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori)
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
static void rofi_theme_distance_unit_property_free(RofiDistanceUnit *unit)
static int distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori)
gboolean rofi_theme_has_property(const widget *widget, const char *property)
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
char * rofi_theme_parse_prepare_file(const char *file, const char *parent_file)
@ ROFI_DISTANCE_MODIFIER_DIVIDE
struct RofiDistanceUnit * right
double textbox_get_estimated_ch(void)
@ ROFI_ORIENTATION_VERTICAL
static void rofi_theme_distance_property_free(RofiDistance *distance)
@ THEME_MEDIA_TYPE_MAX_ASPECT_RATIO
double rofi_theme_get_double(const widget *widget, const char *property, double def)
static RofiDistanceUnit * rofi_theme_property_copy_distance_unit(RofiDistanceUnit *unit)
RofiHighlightColorStyle highlight
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
@ THEME_MEDIA_TYPE_MIN_HEIGHT
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
static void int_rofi_theme_print_property(Property *p)
static ThemeWidget * rofi_theme_find(ThemeWidget *widget, const char *name, const gboolean exact)
void rofi_theme_property_free(Property *p)
int rofi_theme_get_integer(const widget *widget, const char *property, int def)
@ ROFI_DISTANCE_MODIFIER_NONE
void rofi_view_get_current_monitor(int *width, int *height)
static void rofi_theme_print_index(ThemeWidget *widget)
RofiOrientation rofi_theme_get_orientation(const widget *widget, const char *property, RofiOrientation def)
const char *const PropertyTypeName[P_NUM_TYPES]
unsigned int fake_transparency
RofiDistanceModifier modtype
struct Property * def_value
@ ROFI_DISTANCE_MODIFIER_GROUP
void rofi_theme_print(ThemeWidget *widget)
GList * rofi_theme_get_list(const widget *widget, const char *property, const char *defaults)
@ THEME_MEDIA_TYPE_MIN_ASPECT_RATIO
static gpointer rofi_g_list_strdup(gconstpointer data, G_GNUC_UNUSED gpointer user_data)
@ ROFI_DISTANCE_MODIFIER_ADD
int monitor_active(workarea *mon)
@ ROFI_DISTANCE_MODIFIER_SUBTRACT
Property * rofi_theme_property_copy(Property *p)
void rofi_theme_free(ThemeWidget *widget)
static ThemeWidget * rofi_theme_find_single(ThemeWidget *widget, const char *name)
ThemeWidget * rofi_theme_find_widget(const char *name, const char *state, gboolean exact)
@ THEME_MEDIA_TYPE_MON_ID
@ THEME_MEDIA_TYPE_MAX_HEIGHT
void yyerror(YYLTYPE *yylloc, const char *, const char *)
gboolean rofi_theme_parse_string(const char *string)
static void rofi_theme_resolve_link_property(Property *p, int depth)
RofiPadding rofi_theme_get_padding(const widget *widget, const char *property, RofiPadding pad)
char * rofi_expand_path(const char *input)
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
void rofi_theme_parse_process_conditionals(void)
RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance)
gboolean rofi_theme_is_empty(void)
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child)
static void rofi_theme_print_property_index(size_t pnl, int depth, Property *p)
static gboolean distance_compare(RofiDistance d, RofiDistance e)
unsigned int hide_scrollbar
static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
void distance_get_linestyle(RofiDistance d, cairo_t *draw)
void rofi_add_error_message(GString *str)
static void rofi_theme_insert_listview_backwards_fix(void)
static void rofi_theme_print_distance(RofiDistance d)
static void printf_double(double d)
unsigned int scrollbar_width
struct _PropertyValue::@4 link
ThemeMediaType rofi_theme_parse_media_type(const char *type)
Property * rofi_theme_property_create(PropertyType type)
@ THEME_MEDIA_TYPE_MIN_WIDTH
RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, const char *property, RofiHighlightColorStyle th)
unsigned int line_padding
@ THEME_MEDIA_TYPE_MAX_WIDTH
@ THEME_MEDIA_TYPE_INVALID
@ ROFI_DISTANCE_MODIFIER_MODULO
double textbox_get_estimated_char_height(void)
void rofi_theme_reset(void)
@ ROFI_ORIENTATION_HORIZONTAL
struct RofiDistanceUnit * left
static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit)
const char *const WindowLocationStr[9]
@ ROFI_DISTANCE_MODIFIER_MULTIPLY