diff options
author | Dave Davenport <DaveDavenport@users.noreply.github.com> | 2019-09-20 15:05:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-20 15:05:36 +0200 |
commit | 7c613f6a4ca4354165e2cab987d0db1e7ce32c5a (patch) | |
tree | 7cede72023c550462342a9eb13123580a6e5ddaa /lexer | |
parent | f28cf0207e7641890617e8b946977dc204e05ce2 (diff) |
Issue893: Add support for @media in the theme format. (#1015)
* [Lexer] Add support for @media.
Issue: #893
* [Theme] @media limit to px.
* [Theme@Media] add *{} support.
* [Theme@Media] Add support for monitor-id media.
* [Theme@Media] Code cleanup.
* [Theme@Media] Add min/max-aspect-ratio.
* [Theme@Media] Remove some debug output
Fixes: #893
Diffstat (limited to 'lexer')
-rw-r--r-- | lexer/theme-lexer.l | 64 | ||||
-rw-r--r-- | lexer/theme-parser.y | 102 |
2 files changed, 161 insertions, 5 deletions
diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 4ebeff7f..50a2c4e7 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -239,6 +239,8 @@ C_COMMENT_OPEN "/*" INCLUDE "@import" THEME "@theme" +MEDIA "@media" + CONFIGURATION (?i:configuration) %x INCLUDE @@ -250,6 +252,8 @@ CONFIGURATION (?i:configuration) %x NAMESTR %x SECTION %x DEFAULTS +%x MEDIA +%x MEDIA_CONTENT %% %{ @@ -424,13 +428,13 @@ if ( queue == NULL ){ /* After Namestr/Classstr we want to go to state str, then to { */ <INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_VAR>{WHITESPACE}+ ; // ignore all whitespace +<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace <SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; } <PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;} <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} +<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>@{WORD} { @@ -440,7 +444,7 @@ if ( queue == NULL ){ <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EM} { return T_UNIT_EM; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CH} { return T_UNIT_CH; } -<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PX} { return T_UNIT_PX; } +<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PX} { return T_UNIT_PX; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PERCENT} { return T_PERCENT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_SOLID} { return T_SOLID; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_DASH} { return T_DASH; } @@ -619,6 +623,50 @@ if ( queue == NULL ){ yylloc->last_line ++; }; + +<INITIAL>{MEDIA} { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(MEDIA); + return T_MEDIA; +} + +<MEDIA>{S_T_PARENT_LEFT} { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(MEDIA_CONTENT); + return T_PARENT_LEFT; +} +<MEDIA_CONTENT>{WORD} { + yylval->sval = g_strdup(yytext); + return T_STRING; +} +<MEDIA_CONTENT>":" { + return T_PSEP; +} +<MEDIA_CONTENT>{S_T_PARENT_RIGHT} { + int id = GPOINTER_TO_INT(g_queue_pop_head ( queue )); + BEGIN(id); + return T_PARENT_RIGHT; +} +<MEDIA>"\{" { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(INITIAL); + return T_BOPEN; +} + +<INITIAL>"\}" { + g_queue_pop_head ( queue ); + BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); + return T_BCLOSE; +} +<MEDIA>{WHITESPACE}+ ; // ignore all whitespace + + +<MEDIA,MEDIA_CONTENT>. { + yytext[yyleng-1] = '\0'; + fprintf(stderr,"found: |%s|\n", yytext); + return T_ERROR; +} + /** * If we just encounter a word, we assume it is a Widget name. * This makes include,theme, configuration a reserved keyword. @@ -630,9 +678,13 @@ if ( queue == NULL ){ return T_NAME_ELEMENT; } <INITIAL>. { + yytext[yyleng-1] = '\0'; + fprintf(stderr,"initial found: |%s|\n", yytext); return T_ERROR; } <SECTION>. { + yytext[yyleng-1] = '\0'; + fprintf(stderr,"section found: |%s|\n", yytext); return T_ERROR_SECTION; } <PROPERTIES_LIST,PROPERTIES_VAR>{WORD} { @@ -646,9 +698,13 @@ if ( queue == NULL ){ } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. { + yytext[yyleng-1] = '\0'; + fprintf(stderr,"prop found: |%s|\n", yytext); return T_ERROR_PROPERTY; } <NAMESTR>. { + yytext[yyleng-1] = '\0'; + fprintf(stderr,"namestr found: |%s|\n", yytext); return T_ERROR_NAMESTRING; } %% diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 23b0a5dc..c85a5bbe 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -172,6 +172,8 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b) %token T_POS_NORTH "North" %token T_POS_SOUTH "South" +%token T_MEDIA "@media" + %token T_NONE "None" %token T_BOLD "Bold" %token T_ITALIC "Italic" @@ -223,8 +225,17 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b) %token T_INHERIT "Inherit" +%token T_MEDIA_WIDTH "Width" +%token T_MEDIA_HEIGHT "Height" + +%token T_MEDIA_MIN "Min" +%token T_MEDIA_MONITOR_ID "Monitor-ID" +%token T_MEDIA_MAX "Max" +%token T_MEDIA_SEP "-" + %type <sval> t_entry %type <theme> t_entry_list +%type <theme> t_media_entry_list %type <list> t_entry_name_path %type <list> t_entry_name_path_selectors %type <property> t_property @@ -280,6 +291,56 @@ t_entry_list: } ; +t_media_entry_list: +t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE { + ThemeWidget *widget = $$ = g_slice_new0 ( ThemeWidget ); + for ( GList *liter = g_list_first ( $2); liter; liter = g_list_next ( liter ) ) { + for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) { + widget = rofi_theme_find_or_create_name ( widget, iter->data ); + } + g_list_free_full ( (GList*)liter->data, g_free ); + widget->set = TRUE; + rofi_theme_widget_add_properties ( widget, $4); + } + if ( $4 ) { + g_hash_table_destroy ( $4 ); + } + g_list_free ( $2 ); +} +| T_PDEFAULTS T_BOPEN t_property_list_optional T_BCLOSE { + ThemeWidget *widget = $$ = g_slice_new0( ThemeWidget ) ; + widget = rofi_theme_find_or_create_name ( widget, "*" ); + widget->set = TRUE; + rofi_theme_widget_add_properties ( widget, $3); + if ( $3 ) { + g_hash_table_destroy ( $3 ); + } +} +| t_media_entry_list T_PDEFAULTS T_BOPEN t_property_list_optional T_BCLOSE { + ThemeWidget *widget = $$ = $1 ; + widget = rofi_theme_find_or_create_name ( widget, "*" ); + widget->set = TRUE; + rofi_theme_widget_add_properties ( widget, $4); + if ( $4 ) { + g_hash_table_destroy ( $4 ); + } +} +| t_media_entry_list t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE { + ThemeWidget *widget = $$ = $1 ; + for ( GList *liter = g_list_first ( $3); liter; liter = g_list_next ( liter ) ) { + for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) { + widget = rofi_theme_find_or_create_name ( widget, iter->data ); + } + g_list_free_full ( (GList*)liter->data, g_free ); + widget->set = TRUE; + rofi_theme_widget_add_properties ( widget, $5); + } + if ( $5 ) { + g_hash_table_destroy ( $5 ); + } + g_list_free ( $3 ); +}; + /** * Small dummy object to make the prefix optional. */ @@ -293,7 +354,7 @@ t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optio { for ( GList *liter = g_list_first ( $2); liter; liter = g_list_next ( liter ) ) { ThemeWidget *widget = rofi_theme; - for ( GList *iter = g_list_first ( (GList*)liter->data ); iter ; iter = g_list_next ( iter ) ) { + for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) { widget = rofi_theme_find_or_create_name ( widget, iter->data ); } g_list_free_full ( (GList*)liter->data, g_free ); @@ -312,6 +373,45 @@ t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optio g_hash_table_destroy ( $3 ); } } +| T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_INT T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE { + gchar *name = g_strdup_printf("@media ( %s: %d )",$3, $5); + ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, name ); + widget->set = TRUE; + widget->media = g_malloc0(sizeof(ThemeMedia)); + widget->media->type = rofi_theme_parse_media_type ( $3 ); + widget->media->value = (double)$5; + for ( unsigned int i = 0; i < $8->num_widgets;i++) { + ThemeWidget *d = $8->widgets[i]; + rofi_theme_parse_merge_widgets(widget, d); + } + g_free ( name ); +} +| T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_DOUBLE T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE { + gchar *name = g_strdup_printf("@media ( %s: %f )",$3, $5); + ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, name ); + widget->set = TRUE; + widget->media = g_malloc0(sizeof(ThemeMedia)); + widget->media->type = rofi_theme_parse_media_type ( $3 ); + widget->media->value = $5; + for ( unsigned int i = 0; i < $8->num_widgets;i++) { + ThemeWidget *d = $8->widgets[i]; + rofi_theme_parse_merge_widgets(widget, d); + } + g_free ( name ); +} +| T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_INT T_UNIT_PX T_PARENT_RIGHT T_BOPEN t_media_entry_list T_BCLOSE { + gchar *name = g_strdup_printf("@media ( %s: %d px )",$3, $5); + ThemeWidget *widget = rofi_theme_find_or_create_name ( rofi_theme, name ); + widget->set = TRUE; + widget->media = g_malloc0(sizeof(ThemeMedia)); + widget->media->type = rofi_theme_parse_media_type ( $3 ); + widget->media->value = (double)$5; + for ( unsigned int i = 0; i < $9->num_widgets;i++) { + ThemeWidget *d = $9->widgets[i]; + rofi_theme_parse_merge_widgets(widget, d); + } + g_free ( name ); +} ; t_config_property_list_optional |