mirror of
https://github.com/lbonn/rofi
synced 2024-11-23 04:13:03 +00:00
Some initial support for @import in theme and try to fall back when theme fails to load
This commit is contained in:
parent
048d601a85
commit
b7f4b7484f
6 changed files with 212 additions and 74 deletions
|
@ -410,4 +410,9 @@ ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gbool
|
||||||
*/
|
*/
|
||||||
Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property, gboolean exact );
|
Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property, gboolean exact );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a theme is set, or is empty.
|
||||||
|
* @returns TRUE when empty.
|
||||||
|
*/
|
||||||
|
gboolean rofi_theme_is_empty ( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,41 +3,82 @@
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <helper.h>
|
||||||
|
#include "rofi.h"
|
||||||
|
|
||||||
#include "lexer/theme-parser.h"
|
#include "lexer/theme-parser.h"
|
||||||
int last_state = 0;
|
int last_state = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of Object to parse.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/** Parse a file */
|
||||||
|
PT_FILE,
|
||||||
|
/** Parse a string */
|
||||||
|
PT_STRING
|
||||||
|
} ParseType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse object
|
||||||
|
*/
|
||||||
|
typedef struct _ParseObject {
|
||||||
|
/** Type */
|
||||||
|
ParseType type;
|
||||||
|
|
||||||
|
/** File pointer */
|
||||||
|
FILE *filein;
|
||||||
|
|
||||||
|
/** Length of string */
|
||||||
|
int str_len;
|
||||||
|
/** String */
|
||||||
|
const char *input_str;
|
||||||
|
|
||||||
|
} ParseObject;
|
||||||
|
|
||||||
|
GQueue *file_queue = NULL;
|
||||||
GQueue *queue = NULL;
|
GQueue *queue = NULL;
|
||||||
|
|
||||||
|
ParseObject *current = NULL;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
%{
|
%{
|
||||||
|
|
||||||
int str_len = 0;
|
|
||||||
char *input_str = NULL;
|
|
||||||
|
|
||||||
#define YY_INPUT(buf,result,max_size) \
|
#define YY_INPUT(buf,result,max_size) \
|
||||||
{\
|
{\
|
||||||
if ( input_str == NULL ) { \
|
if ( current == NULL ) {\
|
||||||
errno =0; \
|
result = YY_NULL;\
|
||||||
while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
|
|
||||||
{ \
|
|
||||||
if( errno != EINTR) \
|
|
||||||
{ \
|
|
||||||
YY_FATAL_ERROR( "input in flex scanner failed" ); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
errno=0; \
|
|
||||||
clearerr(yyin); \
|
|
||||||
} \
|
|
||||||
} else {\
|
} else {\
|
||||||
yy_size_t len = MIN (max_size, str_len);\
|
switch ( current->type ) { \
|
||||||
if ( len > 0 ){\
|
case PT_FILE:\
|
||||||
memcpy (buf, input_str, len);\
|
{\
|
||||||
input_str+=len;\
|
errno =0; \
|
||||||
str_len-=len;\
|
while ( (result = (int) fread(buf, 1, max_size, current->filein))==0 && ferror(current->filein)) \
|
||||||
result = len;\
|
{ \
|
||||||
} else {\
|
if( errno != EINTR) \
|
||||||
result = YY_NULL;\
|
{ \
|
||||||
} \
|
YY_FATAL_ERROR( "input in flex scanner failed" ); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
errno=0; \
|
||||||
|
clearerr(current->filein); \
|
||||||
|
} \
|
||||||
|
break;\
|
||||||
|
}\
|
||||||
|
case PT_STRING:\
|
||||||
|
{\
|
||||||
|
yy_size_t len = MIN (max_size, current->str_len);\
|
||||||
|
if ( len > 0 ){\
|
||||||
|
memcpy (buf, current->input_str, len);\
|
||||||
|
current->input_str+=len;\
|
||||||
|
current->str_len-=len;\
|
||||||
|
result = len;\
|
||||||
|
} else {\
|
||||||
|
result = YY_NULL;\
|
||||||
|
} \
|
||||||
|
}\
|
||||||
|
}\
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +118,9 @@ ITALIC "italic"
|
||||||
LS_DASH "dash"
|
LS_DASH "dash"
|
||||||
LS_SOLID "solid"
|
LS_SOLID "solid"
|
||||||
|
|
||||||
|
INCLUDE "@import"
|
||||||
|
|
||||||
|
%x INCLUDE
|
||||||
%x PROPERTIES
|
%x PROPERTIES
|
||||||
%x NAMESTR
|
%x NAMESTR
|
||||||
%x ENTRY
|
%x ENTRY
|
||||||
|
@ -94,7 +138,7 @@ if ( queue == NULL ){
|
||||||
|
|
||||||
<*>"//" {
|
<*>"//" {
|
||||||
int c;
|
int c;
|
||||||
while ((c = input()) != EOF){
|
while ((c = input()) != 0){
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
yylloc->last_column = 1;
|
yylloc->last_column = 1;
|
||||||
yylloc->last_line ++;
|
yylloc->last_line ++;
|
||||||
|
@ -118,7 +162,7 @@ if ( queue == NULL ){
|
||||||
yylloc->last_line ++;
|
yylloc->last_line ++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOF: nesting_depth = 0; break;
|
case 0: nesting_depth = 0; break;
|
||||||
default:
|
default:
|
||||||
yylloc->last_column++;
|
yylloc->last_column++;
|
||||||
;
|
;
|
||||||
|
@ -127,6 +171,42 @@ if ( queue == NULL ){
|
||||||
YY_LLOC_START
|
YY_LLOC_START
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HANDLE INCLUDES
|
||||||
|
*/
|
||||||
|
<INITIAL>{INCLUDE} {
|
||||||
|
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
||||||
|
BEGIN(INCLUDE);
|
||||||
|
}
|
||||||
|
<INCLUDE>{WHITESPACE} {}
|
||||||
|
|
||||||
|
<INCLUDE>\"{STRING}\" {
|
||||||
|
yytext[yyleng-1] = '\0';
|
||||||
|
char *filename = rofi_expand_path ( &yytext[1] );
|
||||||
|
FILE *f = fopen ( filename, "rb" );
|
||||||
|
if ( f ) {
|
||||||
|
ParseObject *po = g_malloc0(sizeof(ParseObject));
|
||||||
|
po->type = PT_FILE;
|
||||||
|
po->filein = f;
|
||||||
|
current = po;
|
||||||
|
g_queue_push_head ( file_queue, po );
|
||||||
|
|
||||||
|
yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
|
||||||
|
} else {
|
||||||
|
char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
|
||||||
|
filename, strerror ( errno ) );
|
||||||
|
rofi_add_error_message ( g_string_new ( str ) );
|
||||||
|
g_free ( str );
|
||||||
|
}
|
||||||
|
g_free(filename);
|
||||||
|
// Pop out of include. */
|
||||||
|
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* END INCLUDES
|
||||||
|
*/
|
||||||
|
|
||||||
<INITIAL>{ASTERIX} {
|
<INITIAL>{ASTERIX} {
|
||||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
||||||
BEGIN(DEFAULTS);
|
BEGIN(DEFAULTS);
|
||||||
|
@ -324,10 +404,24 @@ if ( queue == NULL ){
|
||||||
return T_HIGHLIGHT_STYLE;
|
return T_HIGHLIGHT_STYLE;
|
||||||
}
|
}
|
||||||
<INITIAL><<EOF>> {
|
<INITIAL><<EOF>> {
|
||||||
g_queue_free ( queue );
|
ParseObject *po = g_queue_pop_head ( file_queue );
|
||||||
// Reset pointer to NULL
|
if ( po ) {
|
||||||
queue = NULL;
|
if ( po->type == PT_FILE ){
|
||||||
yyterminate();
|
fclose ( po->filein );
|
||||||
|
}
|
||||||
|
g_free ( po );
|
||||||
|
}
|
||||||
|
po = g_queue_peek_head ( file_queue );
|
||||||
|
if ( po == NULL ) {
|
||||||
|
g_queue_free ( queue );
|
||||||
|
// Reset pointer to NULL
|
||||||
|
queue = NULL;
|
||||||
|
yyterminate();
|
||||||
|
} else {
|
||||||
|
yypop_buffer_state();
|
||||||
|
current = po;
|
||||||
|
BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue )));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<*>\n {
|
<*>\n {
|
||||||
|
@ -356,5 +450,63 @@ if ( queue == NULL ){
|
||||||
<*>. {
|
<*>. {
|
||||||
return T_ERROR;
|
return T_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
gboolean rofi_theme_parse_file ( const char *file )
|
||||||
|
{
|
||||||
|
char *filename = rofi_expand_path ( file );
|
||||||
|
yyin = fopen ( filename, "rb" );
|
||||||
|
if ( yyin == NULL ) {
|
||||||
|
char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
|
||||||
|
filename, strerror ( errno ) );
|
||||||
|
rofi_add_error_message ( g_string_new ( str ) );
|
||||||
|
g_free ( str );
|
||||||
|
g_free ( filename );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add Parse object */
|
||||||
|
file_queue = g_queue_new ();
|
||||||
|
ParseObject *po = g_malloc0(sizeof(ParseObject));
|
||||||
|
po->type = PT_FILE;
|
||||||
|
po->filein = yyin;
|
||||||
|
current = po;
|
||||||
|
g_queue_push_head ( file_queue, po );
|
||||||
|
|
||||||
|
int parser_retv = yyparse ( file );
|
||||||
|
yylex_destroy ();
|
||||||
|
g_free ( filename );
|
||||||
|
yyin = NULL;
|
||||||
|
|
||||||
|
// Free up.
|
||||||
|
g_queue_free ( file_queue );
|
||||||
|
file_queue = NULL;
|
||||||
|
if ( parser_retv != 0 ) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
gboolean rofi_theme_parse_string ( const char *string )
|
||||||
|
{
|
||||||
|
yyin = NULL;
|
||||||
|
|
||||||
|
/** Add Parse object */
|
||||||
|
file_queue = g_queue_new ();
|
||||||
|
ParseObject *po = g_malloc0(sizeof(ParseObject));
|
||||||
|
po->type = PT_STRING;
|
||||||
|
po->input_str = string;
|
||||||
|
po->str_len = strlen(string);
|
||||||
|
current = po;
|
||||||
|
g_queue_push_head ( file_queue, po );
|
||||||
|
|
||||||
|
int parser_retv = yyparse ( string );
|
||||||
|
yylex_destroy ();
|
||||||
|
|
||||||
|
// Free up.
|
||||||
|
g_queue_free ( file_queue );
|
||||||
|
file_queue = NULL;
|
||||||
|
if ( parser_retv != 0 ) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -1090,9 +1090,6 @@ int main ( int argc, char *argv[] )
|
||||||
}
|
}
|
||||||
TICK_N ( "Parsed theme" );
|
TICK_N ( "Parsed theme" );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
rofi_theme_convert_old_theme ( );
|
|
||||||
}
|
|
||||||
|
|
||||||
const char ** theme_str = find_arg_strv ( "-theme-str" );
|
const char ** theme_str = find_arg_strv ( "-theme-str" );
|
||||||
if ( theme_str ) {
|
if ( theme_str ) {
|
||||||
|
@ -1104,6 +1101,9 @@ int main ( int argc, char *argv[] )
|
||||||
}
|
}
|
||||||
g_free ( theme_str );
|
g_free ( theme_str );
|
||||||
}
|
}
|
||||||
|
if ( rofi_theme_is_empty ( ) ) {
|
||||||
|
rofi_theme_convert_old_theme ( );
|
||||||
|
}
|
||||||
|
|
||||||
if ( find_arg ( "-dump-theme" ) >= 0 ) {
|
if ( find_arg ( "-dump-theme" ) >= 0 ) {
|
||||||
rofi_theme_print ( rofi_theme );
|
rofi_theme_print ( rofi_theme );
|
||||||
|
|
|
@ -556,6 +556,18 @@ void distance_get_linestyle ( Distance d, cairo_t *draw )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean rofi_theme_is_empty ( void )
|
||||||
|
{
|
||||||
|
if ( rofi_theme == NULL ) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if ( rofi_theme->properties == NULL && rofi_theme->num_widgets == 0 ) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef THEME_CONVERTER
|
#ifdef THEME_CONVERTER
|
||||||
|
|
||||||
static Property* rofi_theme_convert_get_color ( const char *color, const char *name )
|
static Property* rofi_theme_convert_get_color ( const char *color, const char *name )
|
||||||
|
@ -580,7 +592,7 @@ static void rofi_theme_convert_create_property_ht ( ThemeWidget *widget )
|
||||||
void rofi_theme_convert_old_theme ( void )
|
void rofi_theme_convert_old_theme ( void )
|
||||||
{
|
{
|
||||||
if ( rofi_theme != NULL ) {
|
if ( rofi_theme != NULL ) {
|
||||||
return;
|
rofi_theme_free ( rofi_theme );
|
||||||
}
|
}
|
||||||
rofi_theme = (ThemeWidget *) g_slice_new0 ( ThemeWidget );
|
rofi_theme = (ThemeWidget *) g_slice_new0 ( ThemeWidget );
|
||||||
rofi_theme->name = g_strdup ( "Root" );
|
rofi_theme->name = g_strdup ( "Root" );
|
||||||
|
@ -857,43 +869,4 @@ void rofi_theme_convert_old_theme ( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gboolean rofi_theme_parse_file ( const char *file )
|
|
||||||
{
|
|
||||||
char *filename = rofi_expand_path ( file );
|
|
||||||
yyin = fopen ( filename, "rb" );
|
|
||||||
if ( yyin == NULL ) {
|
|
||||||
char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
|
|
||||||
filename, strerror ( errno ) );
|
|
||||||
rofi_add_error_message ( g_string_new ( str ) );
|
|
||||||
g_free ( str );
|
|
||||||
g_free ( filename );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
extern int str_len;
|
|
||||||
extern const char*input_str;
|
|
||||||
str_len = 0;
|
|
||||||
input_str = NULL;
|
|
||||||
int parser_retv = yyparse ( file );
|
|
||||||
yylex_destroy ();
|
|
||||||
g_free ( filename );
|
|
||||||
yyin = NULL;
|
|
||||||
if ( parser_retv != 0 ) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
gboolean rofi_theme_parse_string ( const char *string )
|
|
||||||
{
|
|
||||||
extern int str_len;
|
|
||||||
extern const char*input_str;
|
|
||||||
yyin = NULL;
|
|
||||||
input_str = string;
|
|
||||||
str_len = strlen ( string );
|
|
||||||
int parser_retv = yyparse ( string );
|
|
||||||
yylex_destroy ();
|
|
||||||
if ( parser_retv != 0 ) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,10 @@ unsigned int test =0;
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * rofi_expand_path ( const char *path )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
void rofi_add_error_message ( GString *msg )
|
void rofi_add_error_message ( GString *msg )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ unsigned int test =0;
|
||||||
void rofi_add_error_message ( GString *msg )
|
void rofi_add_error_message ( GString *msg )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
char * rofi_expand_path ( const char *path )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
int textbox_get_estimated_char_height ( void );
|
int textbox_get_estimated_char_height ( void );
|
||||||
int textbox_get_estimated_char_height ( void )
|
int textbox_get_estimated_char_height ( void )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue