diff --git a/include/theme.h b/include/theme.h index d8d7a6e6..34e43257 100644 --- a/include/theme.h +++ b/include/theme.h @@ -412,6 +412,11 @@ char *rofi_theme_parse_prepare_file(const char *file, const char *parent_file); */ void rofi_theme_parse_process_conditionals(void); +/** + * Process links. + */ +void rofi_theme_parse_process_links(void); + /** * @param parent target theme tree * @param child source theme three diff --git a/source/rofi.c b/source/rofi.c index 6bc0272c..43899881 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -1069,6 +1069,7 @@ int main(int argc, char *argv[]) { TICK_N("Setup late Display"); rofi_theme_parse_process_conditionals(); + rofi_theme_parse_process_links(); TICK_N("Theme setup"); // Setup signal handling sources. @@ -1091,6 +1092,7 @@ int main(int argc, char *argv[]) { extern GList *list_of_error_msgs; int rofi_theme_rasi_validate(const char *filename) { rofi_theme_parse_file(filename); + rofi_theme_parse_process_links(); if (list_of_error_msgs == NULL) { return EXIT_SUCCESS; } @@ -1098,6 +1100,7 @@ int rofi_theme_rasi_validate(const char *filename) { for (GList *iter = g_list_first(list_of_error_msgs); iter != NULL; iter = g_list_next(iter)) { fputs(((GString *)iter->data)->str, stderr); + fputs("\n", stderr); } return EXIT_FAILURE; diff --git a/source/theme.c b/source/theme.c index 55d6e4ac..ecf68d37 100644 --- a/source/theme.c +++ b/source/theme.c @@ -715,7 +715,6 @@ static void rofi_theme_resolve_link_property(Property *p, int depth) { return; } } - g_warning("Failed to resolve variable '%s'", name); // No found and we have default value. if (p->value.link.def_value) { p->value.link.ref = p->value.link.def_value; @@ -1543,6 +1542,56 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon, } } } + +static char *rofi_theme_widget_get_name(ThemeWidget *wid) { + GString *str = g_string_new(wid->name); + for (ThemeWidget *i = wid->parent; i->parent != NULL; i = i->parent) { + g_string_prepend_c(str, ' '); + g_string_prepend(str, i->name); + } + char *retv = str->str; + g_string_free(str, FALSE); + return retv; +} + +static void rofi_theme_parse_process_links_int(ThemeWidget *wid) { + if (wid == NULL) { + return; + } + + for (unsigned int i = 0; i < wid->num_widgets; i++) { + ThemeWidget *widget = wid->widgets[i]; + rofi_theme_parse_process_links_int(widget); + if (widget->properties == NULL) { + continue; + } + GHashTableIter iter; + gpointer key, value; + g_hash_table_iter_init(&iter, widget->properties); + while (g_hash_table_iter_next(&iter, &key, &value)) { + Property *pv = (Property *)value; + if (pv->type == P_LINK) { + if (pv->value.link.ref == NULL) { + rofi_theme_resolve_link_property(pv, 0); + if (pv->value.link.ref == pv) { + char *n = rofi_theme_widget_get_name(widget); + GString *str = g_string_new(NULL); + g_string_printf(str, "Failed to resolve: `%s { %s: var(%s);}`", n, + pv->name, pv->value.link.name); + + rofi_add_error_message(str); + g_free(n); + } + } + } + } + } +} + +void rofi_theme_parse_process_links(void) { + rofi_theme_parse_process_links_int(rofi_theme); +} + void rofi_theme_parse_process_conditionals(void) { workarea mon; monitor_active(&mon);