mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
Add some better error message. Allow -theme-str option to override part of theme
This commit is contained in:
parent
6318e5024b
commit
c57e7348d2
9 changed files with 137 additions and 21 deletions
|
@ -24,6 +24,7 @@ List of names in **rofi**:
|
|||
* `#window.mainbox.inputbar.prompt`: The prompt @textbox
|
||||
* `#window.mainbox.inputbar.entry`: The main entry @textbox
|
||||
* `#window.mainbox.listview`
|
||||
* `#window.mainbox.listview.box`: The listview container.
|
||||
* `#window.mainbox.listview.scrollbar`: The listview scrollbar
|
||||
* `#window.mainbox.listview.element`: The entries in the listview
|
||||
* `#window.mainbox.sidebar`
|
||||
|
|
|
@ -82,6 +82,14 @@ int find_arg_int ( const char * const key, int *val );
|
|||
*/
|
||||
int find_arg_str ( const char * const key, char** val );
|
||||
|
||||
/**
|
||||
* @param key The key to search for
|
||||
*
|
||||
* Parse all command line options 'key' to string vector.
|
||||
*
|
||||
* @returns str vector. user should free array.
|
||||
*/
|
||||
const char ** find_arg_strv ( const char *const key );
|
||||
/**
|
||||
* @param key The key to search for
|
||||
*
|
||||
|
|
|
@ -169,8 +169,19 @@ void rofi_theme_free ( ThemeWidget *wid );
|
|||
* @param file filename to parse.
|
||||
*
|
||||
* Parse the input theme file.
|
||||
*
|
||||
* @returns returns TRUE when error.
|
||||
*/
|
||||
void rofi_theme_parse_file ( const char *file );
|
||||
gboolean rofi_theme_parse_file ( const char *file );
|
||||
|
||||
/**
|
||||
* @param string to parse.
|
||||
*
|
||||
* Parse the input string in addition to theme file.
|
||||
*
|
||||
* @returns returns TRUE when error.
|
||||
*/
|
||||
gboolean rofi_theme_parse_string ( const char *file );
|
||||
|
||||
/**
|
||||
* @param widget The widget handle.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
%option noyywrap nounput
|
||||
%option never-interactive
|
||||
%option noyywrap nounput never-interactive
|
||||
%option bison-locations
|
||||
|
||||
%{
|
||||
|
@ -13,6 +12,37 @@ GQueue *queue = NULL;
|
|||
%}
|
||||
%{
|
||||
|
||||
int str_len = 0;
|
||||
char *input_str = NULL;
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
{\
|
||||
if ( input_str == NULL ) { \
|
||||
errno =0; \
|
||||
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 {\
|
||||
yy_size_t len = MIN (max_size, str_len);\
|
||||
if ( len > 0 ){\
|
||||
memcpy (buf, input_str, len);\
|
||||
input_str+=len;\
|
||||
str_len-=len;\
|
||||
result = len;\
|
||||
} else {\
|
||||
result = YY_NULL;\
|
||||
} \
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#define YY_USER_ACTION {\
|
||||
yylloc->last_column+= yyleng;\
|
||||
}
|
||||
|
@ -119,7 +149,7 @@ if ( queue == NULL ){
|
|||
|
||||
<INITIAL>"#" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(NAMESTR);return NAME_PREFIX;}
|
||||
<NAMESTR>\.|{WHITESPACE} { return NSEP; }
|
||||
<INITIAL,ENTRY>{WORD} { yylval->sval = g_strdup(yytext); return N_STRING;}
|
||||
<ENTRY>{WORD} { yylval->sval = g_strdup(yytext); return N_STRING;}
|
||||
<NAMESTR>{WORD} { yylval->sval = g_strdup(yytext); return NAME_ELEMENT;}
|
||||
|
||||
/* After Namestr/Classstr we want to go to state str, then to { */
|
||||
|
@ -289,6 +319,13 @@ if ( queue == NULL ){
|
|||
yylloc->last_column = 1;
|
||||
yylloc->last_line ++;
|
||||
};
|
||||
<INITIAL>. {
|
||||
const char *error_msg = "Expected 'root' element or a 'named' element.\n"\
|
||||
"Place all global properties in a root element:\n"\
|
||||
" * {\n"\
|
||||
" }\n";
|
||||
YY_FATAL_ERROR( error_msg );
|
||||
}
|
||||
<*>. {
|
||||
fprintf(stderr, "Invalid character: '%c'\n", *yytext);
|
||||
yyterminate();
|
||||
|
|
|
@ -38,21 +38,21 @@ int yylex (YYSTYPE *, YYLTYPE *);
|
|||
%token <sval> T_STRING
|
||||
%token <sval> N_STRING
|
||||
%token <ival> T_POSITION;
|
||||
%token <sval> NAME_ELEMENT
|
||||
%token <sval> NAME_ELEMENT "Element name"
|
||||
%token <bval> T_BOOLEAN
|
||||
%token <colorval> T_COLOR
|
||||
%token <distance> T_PIXEL
|
||||
%token <sval> T_LINK
|
||||
%token <sval> FIRST_NAME
|
||||
|
||||
%token BOPEN "bracket open";
|
||||
%token BCLOSE "bracket close";
|
||||
%token PSEP "property separator";
|
||||
%token PCLOSE "property close";
|
||||
%token NSEP "Name separator";
|
||||
%token BOPEN "bracket open";
|
||||
%token BCLOSE "bracket close";
|
||||
%token PSEP "property separator";
|
||||
%token PCLOSE "property close";
|
||||
%token NSEP "Name separator";
|
||||
%token NAME_PREFIX "Name prefix";
|
||||
%token WHITESPACE "White space";
|
||||
%token PDEFAULTS "Default settings";
|
||||
%token WHITESPACE "White space";
|
||||
%token PDEFAULTS "Default settings";
|
||||
|
||||
%type <sval> entry
|
||||
%type <sval> pvalue
|
||||
|
@ -68,8 +68,10 @@ int yylex (YYSTYPE *, YYLTYPE *);
|
|||
entries:
|
||||
%empty {
|
||||
// There is always a base widget.
|
||||
$$ = rofi_theme = (ThemeWidget*)g_malloc0 (sizeof(ThemeWidget));
|
||||
rofi_theme->name = g_strdup ( "Root" );
|
||||
if (rofi_theme == NULL ){
|
||||
$$ = rofi_theme = (ThemeWidget*)g_malloc0 (sizeof(ThemeWidget));
|
||||
rofi_theme->name = g_strdup ( "Root" );
|
||||
}
|
||||
}
|
||||
| entries
|
||||
entry {
|
||||
|
|
|
@ -295,6 +295,27 @@ int find_arg_str ( const char * const key, char** val )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
const char ** find_arg_strv ( const char *const key )
|
||||
{
|
||||
const char **retv =NULL;
|
||||
int length = 0;
|
||||
for ( int i = 0; i < stored_argc; i++ ) {
|
||||
if ( strcasecmp ( stored_argv[i], key ) == 0 && i < (stored_argc -1 ) ){
|
||||
length++;
|
||||
}
|
||||
}
|
||||
if ( length > 0 ) {
|
||||
retv = g_malloc0((length+1)*sizeof(char*));
|
||||
int index = 0;
|
||||
for ( int i = 0; i < stored_argc; i++ ) {
|
||||
if ( strcasecmp ( stored_argv[i], key ) == 0 && i < (stored_argc -1 ) ){
|
||||
retv[index] = stored_argv[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return retv;
|
||||
}
|
||||
|
||||
int find_arg_int ( const char * const key, int *val )
|
||||
{
|
||||
int i = find_arg ( key );
|
||||
|
|
|
@ -952,6 +952,19 @@ int main ( int argc, char *argv[] )
|
|||
rofi_theme_convert_old_theme ( );
|
||||
}
|
||||
|
||||
const char ** theme_str = find_arg_strv ( "-theme-str" );
|
||||
if ( theme_str ) {
|
||||
for ( int index = 0; theme_str && theme_str[index]; index++ ){
|
||||
if ( ! rofi_theme_parse_string ( theme_str[index] ) ){
|
||||
fprintf(stderr, "Failed to parse: %s\n", theme_str[index]);
|
||||
exit ( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
g_free ( theme_str );
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( find_arg ( "-dump-theme" ) >= 0 ){
|
||||
rofi_theme_print ( rofi_theme );
|
||||
exit (EXIT_SUCCESS);
|
||||
|
|
|
@ -789,17 +789,34 @@ void rofi_theme_convert_old_theme ( void )
|
|||
}
|
||||
}
|
||||
}
|
||||
void rofi_theme_parse_file ( const char *file )
|
||||
gboolean rofi_theme_parse_file ( const char *file )
|
||||
{
|
||||
char *filename = rofi_expand_path ( file );
|
||||
yyin = fopen ( filename, "rb");
|
||||
if ( yyin == NULL ){
|
||||
fprintf(stderr, "Failed to open file: %s: '%s'\n", filename, strerror ( errno ) );
|
||||
g_free(filename);
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
extern int str_len;
|
||||
extern const char*input_str;
|
||||
str_len = 0;
|
||||
input_str = NULL;
|
||||
while ( yyparse() );
|
||||
yylex_destroy();
|
||||
g_free(filename);
|
||||
yyin = NULL;
|
||||
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 );
|
||||
while ( yyparse () );
|
||||
yylex_destroy();
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -80,6 +80,9 @@ struct _listview
|
|||
xcb_timestamp_t last_click;
|
||||
listview_mouse_activated_cb mouse_activated;
|
||||
void *mouse_activated_data;
|
||||
|
||||
|
||||
char *listview_name;
|
||||
};
|
||||
|
||||
static int listview_get_desired_height ( widget *wid );
|
||||
|
@ -92,6 +95,7 @@ static void listview_free ( widget *wid )
|
|||
}
|
||||
g_free ( lv->boxes );
|
||||
|
||||
g_free( lv->listview_name );
|
||||
widget_free ( WIDGET ( lv->scrollbar ) );
|
||||
g_free ( lv );
|
||||
}
|
||||
|
@ -234,7 +238,7 @@ static void listview_recompute_elements ( listview *lv )
|
|||
if ( newne > 0 ) {
|
||||
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
|
||||
TextboxFlags flags = ( lv->multi_select ) ? TB_INDICATOR : 0;
|
||||
char *name = g_strjoin (".", lv->widget.name,"element", NULL);
|
||||
char *name = g_strjoin (".", lv->listview_name,"element", NULL);
|
||||
lv->boxes[i] = textbox_create ( name, flags, NORMAL, "" );
|
||||
g_free ( name );
|
||||
}
|
||||
|
@ -351,8 +355,10 @@ static gboolean listview_motion_notify ( widget *wid, xcb_motion_notify_event_t
|
|||
listview *listview_create ( const char *name, listview_update_callback cb, void *udata, unsigned int eh, gboolean reverse )
|
||||
{
|
||||
listview *lv = g_malloc0 ( sizeof ( listview ) );
|
||||
|
||||
widget_init ( WIDGET ( lv ), name );
|
||||
gchar *box = g_strjoin (".", name, "box", NULL );
|
||||
widget_init ( WIDGET ( lv ), box );
|
||||
g_free(box);
|
||||
lv->listview_name = g_strdup ( name );
|
||||
lv->widget.free = listview_free;
|
||||
lv->widget.resize = listview_resize;
|
||||
lv->widget.draw = listview_draw;
|
||||
|
@ -362,7 +368,7 @@ listview *listview_create ( const char *name, listview_update_callback cb, void
|
|||
lv->widget.enabled = TRUE;
|
||||
lv->eh = eh;
|
||||
|
||||
char *n = g_strjoin(".", lv->widget.name,"scrollbar", NULL);
|
||||
char *n = g_strjoin(".", lv->listview_name,"scrollbar", NULL);
|
||||
lv->scrollbar = scrollbar_create ( n );
|
||||
// Default position on right.
|
||||
lv->scrollbar->widget.index = rofi_theme_get_integer_exact ( WIDGET (lv->scrollbar), "index", 1);
|
||||
|
@ -371,7 +377,7 @@ listview *listview_create ( const char *name, listview_update_callback cb, void
|
|||
lv->scrollbar->widget.parent = WIDGET ( lv );
|
||||
// Calculate height of an element.
|
||||
//
|
||||
char *tb_name = g_strjoin (".", lv->widget.name,"element", NULL);
|
||||
char *tb_name = g_strjoin (".", lv->listview_name,"element", NULL);
|
||||
textbox *tb = textbox_create ( tb_name, 0, NORMAL, "" );
|
||||
lv->element_height = textbox_get_estimated_height (tb, lv->eh);
|
||||
g_free(tb_name);
|
||||
|
|
Loading…
Reference in a new issue