From 0f21541327418e7aaa99a8192eb79ed9c6438b88 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Mon, 14 Jun 2021 19:29:05 +0200 Subject: [PATCH] [Configuration] Add start of more 'theme' based configuration. Nested CSS blocks in configuration {} are parsed into rofi_configuration. --- include/theme.h | 9 +++++++++ lexer/theme-lexer.l | 8 ++++++++ lexer/theme-parser.y | 19 ++++++++++++++++++- source/dialogs/combi.c | 2 +- source/rofi.c | 5 +++++ source/theme.c | 8 ++++++++ source/xrmoptions.c | 2 ++ 7 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/theme.h b/include/theme.h index 37a5a09c..94a7c1d7 100644 --- a/include/theme.h +++ b/include/theme.h @@ -87,6 +87,14 @@ typedef struct ThemeWidget */ extern ThemeWidget *rofi_theme; +/** + * Used to store config options. + */ +extern ThemeWidget *rofi_theme; + + +extern ThemeWidget *rofi_configuration; + /** * @param base Handle to the current level in the theme. * @param name Name of the new element. @@ -333,6 +341,7 @@ void distance_get_linestyle ( RofiDistance d, cairo_t *draw ); * @returns the ThemeWidget if found, otherwise NULL. */ ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gboolean exact ); +ThemeWidget *rofi_config_find_widget ( const char *name, const char *state, gboolean exact ); /** * @param widget The widget to find the property on. diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 6a291a00..394afa98 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -474,6 +474,14 @@ if ( queue == NULL ){ return T_LINK; } +
"\{" { + // Double to fit in scheme. + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + g_queue_push_head ( queue, GINT_TO_POINTER (SECTION) ); + BEGIN(SECTION); + return T_BOPEN; +} + {EM} { return T_UNIT_EM; } {CH} { return T_UNIT_CH; } {PX} { return T_UNIT_PX; } diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 94bf3cd3..a7031161 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -318,7 +318,12 @@ t_main ; t_configuration_list: - %empty {} + %empty { + if ( rofi_configuration == NULL ) { + rofi_configuration = g_slice_new0 ( ThemeWidget ); + rofi_configuration->name = g_strdup ( "Configuration" ); + } +} | t_configuration_list T_CONFIGURATION T_BOPEN t_config_property_list_optional T_BCLOSE {}; @@ -429,6 +434,18 @@ t_config_property // We don't keep any reference to this after this point, so the property can be free'ed. rofi_theme_property_free ( $1 ); } +| t_property_name T_BOPEN t_property_list_optional T_BCLOSE +{ + ThemeWidget *widget = rofi_configuration; + widget = rofi_theme_find_or_create_name ( widget, $1 ); + widget->set = TRUE; + rofi_theme_widget_add_properties ( widget, $3); + if ( $3 ) { + g_hash_table_destroy ( $3 ); + } + g_free ( $1 ); +} +; /** * properties diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c index 552ab36d..231b7f0f 100644 --- a/source/dialogs/combi.c +++ b/source/dialogs/combi.c @@ -223,7 +223,7 @@ static char * combi_mgrv ( const Mode *sw, unsigned int selected_line, int *stat } if ( attr_list != NULL ) { - ThemeWidget *wid = rofi_theme_find_widget ( sw->name, NULL, TRUE ); + ThemeWidget *wid = rofi_config_find_widget ( sw->name, NULL, TRUE ); Property *p = rofi_theme_find_property ( wid, P_COLOR, pd->switchers[i].mode->name, TRUE ); if ( p != NULL ) { PangoAttribute *pa = pango_attr_foreground_new ( diff --git a/source/rofi.c b/source/rofi.c index 202ff378..b2e62805 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -472,6 +472,11 @@ static void cleanup () TIMINGS_STOP (); rofi_collect_modi_destroy ( ); rofi_icon_fetcher_destroy ( ); + + if ( rofi_configuration ) { + rofi_theme_free ( rofi_configuration ); + rofi_configuration = NULL; + } } /** diff --git a/source/theme.c b/source/theme.c index f70f0c45..fa8ac220 100644 --- a/source/theme.c +++ b/source/theme.c @@ -798,6 +798,14 @@ Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, con } return NULL; } +ThemeWidget *rofi_config_find_widget ( const char *name, const char *state, gboolean exact ) +{ + // First find exact match based on name. + ThemeWidget *widget = rofi_theme_find_single ( rofi_configuration, name ); + widget = rofi_theme_find ( widget, state, exact ); + + return widget; +} ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gboolean exact ) { // First find exact match based on name. diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 6eb03c62..6b5226bc 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -44,6 +44,8 @@ #include "rofi-types.h" +ThemeWidget *rofi_configuration = NULL; + /** Different sources of configuration. */ const char * const ConfigSourceStr[] = {