diff options
author | QC <qball@gmpclient.org> | 2015-02-15 21:15:16 +0100 |
---|---|---|
committer | QC <qball@gmpclient.org> | 2015-02-15 21:15:16 +0100 |
commit | dee0bfb821df56a58fbc006cbe28954b1a2b5008 (patch) | |
tree | 910543f1ae090c90a4aab3d9d88a5375da7574ef | |
parent | b6652a022114b3c5982523637d30551d16f31553 (diff) |
Fix #128: Better handling of keybindings and remove deprecated launching.
See manpage.
-rw-r--r-- | Changelog | 6 | ||||
-rw-r--r-- | config/config.def.c | 6 | ||||
-rw-r--r-- | doc/rofi-manpage.markdown | 51 | ||||
-rw-r--r-- | doc/rofi.1 | 68 | ||||
-rw-r--r-- | include/rofi.h | 6 | ||||
-rw-r--r-- | include/xrmoptions.h | 19 | ||||
-rw-r--r-- | source/helper.c | 8 | ||||
-rw-r--r-- | source/rofi.c | 155 | ||||
-rw-r--r-- | source/textbox.c | 8 | ||||
-rw-r--r-- | source/x11-helper.c | 2 | ||||
-rw-r--r-- | source/xrmoptions.c | 187 |
11 files changed, 252 insertions, 264 deletions
@@ -1,12 +1,14 @@ 0.15.2: (unreleased) Removed features: - Remove (broken) hmode + - Old style key binding and mode launcher. New features: - Word movement in entry box. (#126) - PID file to avoid duplicate Rofi. + - Generic keybinding and launching for modi. (#128) Bug fixes: - Shift left/right movement between swtichers (#125) - - Document updates (#123,#116,#124,etc.) + - Document updates (#123,#116,#124,etc.) - DMenu mode based on executable name with full path (#119) - Fix missing keystrokes. - On broken UTF-8 show everything up to the broken character. (#121) @@ -17,7 +19,7 @@ 0.15.1: New features: - - Improved transparency + - Improved transparency - Changelog - Case sensitivity support, with indicator. (Edwin Pujols) - Mouse scroll wheel support diff --git a/config/config.def.c b/config/config.def.c index 02efb7c9..6ddea334 100644 --- a/config/config.def.c +++ b/config/config.def.c @@ -69,12 +69,6 @@ Settings config = { .run_list_command = "", /** Command executed when running application in terminal */ .run_shell_command = "{terminal} -e {cmd}", - /** Key binding */ - .window_key = "F12", - /** Key to open run dialog */ - .run_key = "mod1+F2", - /** Key to open ssh dialog */ - .ssh_key = "mod1+F3", /** * Location of the window. * Enumeration indicating location or gravity of window. diff --git a/doc/rofi-manpage.markdown b/doc/rofi-manpage.markdown index 66dde05d..41e8931a 100644 --- a/doc/rofi-manpage.markdown +++ b/doc/rofi-manpage.markdown @@ -16,9 +16,7 @@ rofi - A window switcher, run dialog and dmenu replacement [ -bgalt *color* ] [ -hlfg *color* ] [ -hlbg *color* ] -[ -key *combo* ] -[ -dkey *comdo* ] -[ -rkey *comdo* ] +[ -key-**mode** *combo* ] [ -terminal *terminal* ] [ -location *position* ] [ -fixed-num-lines ] @@ -79,51 +77,14 @@ The default key combinations are: ## OPTIONS -`-key` +`-key-**mode**` **KEY** - Change the key combination to display all windows. + Change the key combination to display a **mode** - rofi -key F12 - rofi -key control+shift+s - rofi -key mod1+Tab - - Default: *F12* - - -`-rkey` - - Change the key combination to display the run dialog. - - - rofi -rkey F11 - rofi -rkey control+shift+d - rofi -rkey mod1+grave (grave=backtick) - - Default: *Alt-F2* - -`-skey` - - Change the key combination to display the ssh dialog. - - - rofi -skey F10 - rofi -skey control+shift+s - rofi -skey mod1+grave (grave=backtick) - - Default: *Alt-F3* - -`-now` - - Run rofi in all-windows mode once then exit. Does not bind any keys. - -`-rnow` - - Run rofi in run-dialog mode once then exit. Does not bind any keys. - -`-snow` - - Run rofi in ssh mode once then exit. Does not bind any keys. + rofi -key-run F12 + rofi -key-ssh control+shift+s + rofi -key-window mod1+Tab `-dmenu` @@ -14,9 +14,7 @@ rofi \- A window switcher, run dialog and dmenu replacement [ \-bgalt \fIcolor\fP ] [ \-hlfg \fIcolor\fP ] [ \-hlbg \fIcolor\fP ] -[ \-key \fIcombo\fP ] -[ \-dkey \fIcomdo\fP ] -[ \-rkey \fIcomdo\fP ] +[ \-key\-\fBmode\fP \fIcombo\fP ] [ \-terminal \fIterminal\fP ] [ \-location \fIposition\fP ] [ \-fixed\-num\-lines ] @@ -77,59 +75,17 @@ The default key combinations are: Show ssh\-dialog. .SH OPTIONS .PP -\fB\fC\-key\fR +\fB\fC\-key\-**mode**\fR \fBKEY\fP .IP -Change the key combination to display all windows. +Change the key combination to display a \fBmode\fP .PP .RS .nf - rofi \-key F12 - rofi \-key control+shift+s - rofi \-key mod1+Tab + rofi \-key\-run F12 + rofi \-key\-ssh control+shift+s + rofi \-key\-window mod1+Tab .fi .RE -.IP -Default: \fIF12\fP -.PP -\fB\fC\-rkey\fR -.IP -Change the key combination to display the run dialog. -.PP -.RS -.nf - rofi \-rkey F11 - rofi \-rkey control+shift+d - rofi \-rkey mod1+grave (grave=backtick) -.fi -.RE -.IP -Default: \fIAlt\-F2\fP -.PP -\fB\fC\-skey\fR -.IP -Change the key combination to display the ssh dialog. -.PP -.RS -.nf - rofi \-skey F10 - rofi \-skey control+shift+s - rofi \-skey mod1+grave (grave=backtick) -.fi -.RE -.IP -Default: \fIAlt\-F3\fP -.PP -\fB\fC\-now\fR -.IP -Run rofi in all\-windows mode once then exit. Does not bind any keys. -.PP -\fB\fC\-rnow\fR -.IP -Run rofi in run\-dialog mode once then exit. Does not bind any keys. -.PP -\fB\fC\-snow\fR -.IP -Run rofi in ssh mode once then exit. Does not bind any keys. .PP \fB\fC\-dmenu\fR .IP @@ -649,14 +605,18 @@ Check quotes used on the commandline: e.g. used “ instead of ". .SH WEBSITE .PP \fBrofi\fP website can be found at here -\[la]https://davedavenport.github.io/rofi/\[ra] +.UR https://davedavenport.github.io/rofi/ +.UE .PP \fBrofi\fP bugtracker can be found here -\[la]https://github.com/DaveDavenport/rofi/issues\[ra] +.UR https://github.com/DaveDavenport/rofi/issues +.UE .SH AUTHOR .PP Qball Cow -\[la]qball@gmpclient.org\[ra] +.MT qball@gmpclient.org +.ME .PP Original code based on work by: Sean Pringle -\[la]sean.pringle@gmail.com\[ra] +.MT sean.pringle@gmail.com +.ME diff --git a/include/rofi.h b/include/rofi.h index 7a844a77..1e5b0a7d 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -174,12 +174,6 @@ typedef struct _Settings /** Command for listing executables */ char * run_list_command; - /** Key to open window switcher */ - char * window_key; - /** Key to open run dialog */ - char * run_key; - /** Key to open ssh dialog */ - char * ssh_key; /** Windows location/gravity */ WindowLocation location; /** Padding between elements */ diff --git a/include/xrmoptions.h b/include/xrmoptions.h index 3b9a3e31..b7efae8e 100644 --- a/include/xrmoptions.h +++ b/include/xrmoptions.h @@ -1,6 +1,16 @@ #ifndef __XRMOPTIONS_H__ #define __XRMOPTIONS_H__ +// Big thanks to Sean Pringle for this code. +// This maps xresource options to config structure. +typedef enum +{ + xrm_String = 0, + xrm_Number = 1, + xrm_SNumber = 2, + xrm_Boolean = 3 +} XrmOptionType; + /** * @param display Handler of the display to fetch the settings from. * @@ -10,6 +20,14 @@ void config_parse_xresource_options ( Display *display ); /** + * @param display Handler of the display to fetch the settings from. + * + * Parse the rofi related X resource options of the + * connected X server. + */ +void config_parse_xresource_options_dynamic ( Display *display ); + +/** * Free any allocated memory. */ void config_xresource_free ( void ); @@ -20,4 +38,5 @@ void config_xresource_free ( void ); */ void xresource_dump ( void ); +void config_parser_add_option ( XrmOptionType type, const char *key, void **value ); #endif diff --git a/source/helper.c b/source/helper.c index 3de37208..57de94e1 100644 --- a/source/helper.c +++ b/source/helper.c @@ -452,16 +452,8 @@ void config_parse_cmd_options ( int argc, char ** argv ) find_arg_str ( argc, argv, "-run-list-command", &( config.run_list_command ) ); find_arg_str ( argc, argv, "-run-shell-command", &( config.run_shell_command ) ); - // Keybindings - find_arg_str ( argc, argv, "-key", &( config.window_key ) ); - find_arg_str ( argc, argv, "-rkey", &( config.run_key ) ); - find_arg_str ( argc, argv, "-skey", &( config.ssh_key ) ); - - - find_arg_char ( argc, argv, "-sep", &( config.separator ) ); - find_arg_int ( argc, argv, "-eh", &( config.element_height ) ); find_arg_uint ( argc, argv, "-lazy-filter-limit", &( config.lazy_filter_limit ) ); diff --git a/source/rofi.c b/source/rofi.c index 226c062c..ba734741 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -65,17 +65,13 @@ typedef enum _MainLoopEvent } MainLoopEvent; // Pidfile. -char *pidfile = NULL; -const char *cache_dir = NULL; -Display *display = NULL; -char *display_str = NULL; - -const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; -Atom netatoms[NUM_NETATOMS]; - -unsigned int windows_modmask, rundialog_modmask, sshdialog_modmask; -KeySym rundialog_keysym, sshdialog_keysym, windows_keysym; +char *pidfile = NULL; +const char *cache_dir = NULL; +Display *display = NULL; +char *display_str = NULL; +const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; +Atom netatoms[NUM_NETATOMS]; /** * Structure defining a switcher. @@ -93,6 +89,11 @@ typedef struct _Switcher switcher_callback_free_data cb_data_free; // Textbox used in the sidebar-mode. textbox *tb; + // Keybindings (keysym and modmask) + char * keycfg; + char * keystr; + KeySym keysym; + unsigned int modmask; } Switcher; // Array of switchers. @@ -551,12 +552,20 @@ inline static void menu_nav_down ( MenuState *state ) */ static void menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned int modstate ) { - if ( key == XK_Escape - // pressing one of the global key bindings closes the switcher. this allows fast closing of the menu if an item is not selected - || ( ( windows_modmask == AnyModifier || modstate & windows_modmask ) && key == windows_keysym ) - || ( ( rundialog_modmask == AnyModifier || modstate & rundialog_modmask ) && key == rundialog_keysym ) - || ( ( sshdialog_modmask == AnyModifier || modstate & sshdialog_modmask ) && key == sshdialog_keysym ) - ) { + // pressing one of the global key bindings closes the switcher. this allows fast closing of the + // menu if an item is not selected + for ( unsigned int i = 0; i < num_switchers; i++ ) { + if ( switchers[i].keystr != NULL ) { + if ( ( switchers[i].modmask == AnyModifier || modstate & ( switchers[i].keysym ) ) && + switchers[i].keysym == key ) { + state->retv = MENU_CANCEL; + state->quit = TRUE; + state->prev_key = key; + return; + } + } + } + if ( key == XK_Escape ) { state->retv = MENU_CANCEL; state->quit = TRUE; } @@ -1418,19 +1427,13 @@ static void handle_keypress ( XEvent *ev ) { int index = -1; KeySym key = XkbKeycodeToKeysym ( display, ev->xkey.keycode, 0, 0 ); - if ( ( windows_modmask == AnyModifier || ev->xkey.state & windows_modmask ) && - key == windows_keysym ) { - index = switcher_get ( "window" ); - } - - if ( ( rundialog_modmask == AnyModifier || ev->xkey.state & rundialog_modmask ) && - key == rundialog_keysym ) { - index = switcher_get ( "run" ); - } - - if ( ( sshdialog_modmask == AnyModifier || ev->xkey.state & sshdialog_modmask ) && - key == sshdialog_keysym ) { - index = switcher_get ( "ssh" ); + for ( unsigned int i = 0; i < num_switchers; i++ ) { + if ( switchers[i].keystr != NULL ) { + if ( ( switchers[i].modmask == AnyModifier || ( ev->xkey.state ) & ( switchers[i].keysym ) ) && + switchers[i].keysym == key ) { + index = i; + } + } } if ( index >= 0 ) { run_switcher ( TRUE, index ); @@ -1468,12 +1471,19 @@ static void cleanup () // Cleaning up memory allocated by the Xresources file. config_xresource_free (); - for ( unsigned int i = 0; i < num_switchers; i++ ) { // only used for script dialog. if ( switchers[i].cb_data_free != NULL ) { switchers[i].cb_data_free ( switchers[i].cb_data ); } + if ( switchers[i].keystr != NULL ) { + g_free ( switchers[i].keystr ); + switchers[i].keystr = NULL; + } + if ( switchers[i].keycfg != NULL ) { + g_free ( switchers[i].keycfg ); + switchers[i].keycfg = NULL; + } } g_free ( switchers ); @@ -1501,9 +1511,14 @@ static void setup_switchers ( void ) token != NULL; token = strtok_r ( NULL, ",", &savept ) ) { // Resize and add entry. - switchers = (Switcher *) g_realloc ( switchers, sizeof ( Switcher ) * ( num_switchers + 1 ) ); + switchers = (Switcher *) g_realloc ( switchers, + sizeof ( Switcher ) * ( num_switchers + 1 ) ); switchers[num_switchers].cb_data = NULL; switchers[num_switchers].cb_data_free = NULL; + switchers[num_switchers].keystr = NULL; + switchers[num_switchers].keycfg = NULL; + switchers[num_switchers].keysym = None; + switchers[num_switchers].modmask = AnyModifier; // Window switcher. if ( strcasecmp ( token, "window" ) == 0 ) { @@ -1540,9 +1555,19 @@ static void setup_switchers ( void ) token = NULL; } } + // Keybinding. } // Free string that was modified by strtok_r g_free ( switcher_str ); + // We cannot do this in main loop, as we create pointer to string, + // and re-alloc moves that pointer. + for ( unsigned int i = 0; i < num_switchers; i++ ) { + switchers[i].keycfg = g_strdup_printf ( "key-%s", + switchers[i].name ); + config_parser_add_option ( xrm_String, + switchers[i].keycfg, + (void * *) &( switchers[i].keystr ) ); + } } /** @@ -1563,11 +1588,24 @@ static inline void load_configuration ( Display *display ) // Parse command line for settings. config_parse_cmd_options ( stored_argc, stored_argv ); +} +static inline void load_configuration_dynamic ( Display *display ) +{ + // Load in config from X resources. + config_parse_xresource_options_dynamic ( display ); + for ( unsigned int i = 0; i < num_switchers; i++ ) { + if ( switchers[i].keycfg != NULL ) { + char *flag = g_strdup_printf ( "-%s", switchers[i].keycfg ); + find_arg_str_alloc ( stored_argc, stored_argv, flag, &( switchers[i].keystr ) ); + g_free ( flag ); + } + } // Sanity check config_sanity_check (); } + /** * Handle sighub request. * Currently we just reload the configuration. @@ -1582,6 +1620,7 @@ static void hup_action_handler ( int num ) Display *display = XOpenDisplay ( display_str ); if ( display ) { load_configuration ( display ); + load_configuration_dynamic ( display ); XCloseDisplay ( display ); } } @@ -1647,6 +1686,10 @@ int main ( int argc, char *argv[] ) load_configuration ( display ); + // setup_switchers + setup_switchers (); + // Reload for dynamic part. + load_configuration_dynamic ( display ); // Dump. if ( find_arg ( argc, argv, "-dump-xresources" ) >= 0 ) { @@ -1654,9 +1697,6 @@ int main ( int argc, char *argv[] ) exit ( EXIT_SUCCESS ); } - // setup_switchers - setup_switchers (); - // Set up X interaction. signal ( SIGCHLD, catch_exit ); @@ -1711,51 +1751,14 @@ int main ( int argc, char *argv[] ) fprintf ( stderr, "The %s switcher has not been enabled\n", sname ); } } - // Old modi. - else if ( find_arg ( argc, argv, "-now" ) >= 0 ) { - int index = switcher_get ( "window" ); - if ( index >= 0 ) { - run_switcher ( FALSE, index ); - } - else { - fprintf ( stderr, "The window switcher has not been enabled\n" ); - } - } - else if ( find_arg ( argc, argv, "-rnow" ) >= 0 ) { - int index = switcher_get ( "run" ); - if ( index >= 0 ) { - run_switcher ( FALSE, index ); - } - else { - fprintf ( stderr, "The run dialog has not been enabled\n" ); - } - } - else if ( find_arg ( argc, argv, "-snow" ) >= 0 ) { - int index = switcher_get ( "ssh" ); - if ( index >= 0 ) { - run_switcher ( FALSE, index ); - } - else { - fprintf ( stderr, "The ssh dialog has not been enabled\n" ); - } - } else{ // Daemon mode, Listen to key presses.. - if ( switcher_get ( "window" ) >= 0 ) { - x11_parse_key ( config.window_key, &windows_modmask, &windows_keysym ); - x11_grab_key ( display, windows_modmask, windows_keysym ); - } - - if ( switcher_get ( "run" ) >= 0 ) { - x11_parse_key ( config.run_key, &rundialog_modmask, &rundialog_keysym ); - x11_grab_key ( display, rundialog_modmask, rundialog_keysym ); - } - - if ( switcher_get ( "ssh" ) >= 0 ) { - x11_parse_key ( config.ssh_key, &sshdialog_modmask, &sshdialog_keysym ); - x11_grab_key ( display, sshdialog_modmask, sshdialog_keysym ); + for ( unsigned int i = 0; i < num_switchers; i++ ) { + if ( switchers[i].keystr != NULL ) { + x11_parse_key ( switchers[i].keystr, &( switchers[i].modmask ), &( switchers[i].keysym ) ); + x11_grab_key ( display, switchers[i].modmask, switchers[i].keysym ); + } } - // Setup handler for sighub (reload config) const struct sigaction hup_action = { .sa_handler = hup_action_handler diff --git a/source/textbox.c b/source/textbox.c index 665bd900..dd2e202f 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -312,7 +312,7 @@ void textbox_draw ( textbox *tb ) // cursor handling for edit mode void textbox_cursor ( textbox *tb, int pos ) { - int length = (tb->text == NULL)? 0: strlen(tb->text); + int length = ( tb->text == NULL ) ? 0 : strlen ( tb->text ); tb->cursor = MAX ( 0, MIN ( length, pos ) ); } @@ -333,7 +333,7 @@ void textbox_cursor_dec ( textbox *tb ) // Move word right void textbox_cursor_inc_word ( textbox *tb ) { - if(tb->text == NULL) { + if ( tb->text == NULL ) { return; } // Find word boundaries, with pango_Break? @@ -351,7 +351,7 @@ void textbox_cursor_inc_word ( textbox *tb ) break; } } - if(c == NULL) { + if ( c == NULL ) { return; } while ( ( c = g_utf8_next_char ( c ) ) ) { @@ -452,7 +452,7 @@ void textbox_delete ( textbox *tb, int pos, int dlen ) // delete on character void textbox_cursor_del ( textbox *tb ) { - if(tb->text == NULL) { + if ( tb->text == NULL ) { return; } int index = g_utf8_next_char ( &( tb->text[tb->cursor] ) ) - tb->text; diff --git a/source/x11-helper.c b/source/x11-helper.c index a187810e..4f2de7b6 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -412,7 +412,7 @@ void x11_setup ( Display *display ) extern Colormap map; extern XVisualInfo vinfo; -int truecolor = FALSE; +int truecolor = FALSE; void create_visual_and_colormap ( Display *display ) { int screen = DefaultScreen ( display ); diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 609bf379..3dea144f 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -33,25 +33,16 @@ #include "rofi.h" #include "xrmoptions.h" -// Big thanks to Sean Pringle for this code. -// This maps xresource options to config structure. -typedef enum -{ - xrm_String = 0, - xrm_Number = 1, - xrm_SNumber = 2, - xrm_Boolean = 3 -} XrmOptionType; - typedef struct { - int type; - char * name; + int type; + const char * name; union { unsigned int * num; int * snum; char ** str; + void *pointer; }; char *mem; } XrmOption; @@ -108,13 +99,58 @@ static XrmOption xrmOptions[] = { { xrm_Boolean, "levenshtein-sort", { .num = &config.levenshtein_sort }, NULL }, { xrm_Boolean, "case-sensitive", { .num = &config.case_sensitive }, NULL }, /* Key bindings */ - { xrm_String, "key", { .str = &config.window_key }, NULL }, - { xrm_String, "rkey", { .str = &config.run_key }, NULL }, - { xrm_String, "skey", { .str = &config.ssh_key }, NULL }, { xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL }, { xrm_Number, "lazy-filter-limit", { .num = &config.lazy_filter_limit }, NULL } }; +// Dynamic options. +XrmOption *extra_options = NULL; +unsigned int num_extra_options = 0; + +void config_parser_add_option ( XrmOptionType type, const char *key, void **value ) +{ + extra_options = g_realloc ( extra_options, ( num_extra_options + 1 ) * sizeof ( XrmOption ) ); + + extra_options[num_extra_options].type = type; + extra_options[num_extra_options].name = key; + extra_options[num_extra_options].pointer = value; + if ( type == xrm_String ) { + extra_options[num_extra_options].mem = ( (char *) ( *value ) ); + } + else { + extra_options[num_extra_options].mem = NULL; + } + + num_extra_options++; +} + +static void config_parser_set ( XrmOption *option, XrmValue *xrmValue ) +{ + if ( option->type == xrm_String ) { + if ( ( option )->mem != NULL ) { + g_free ( option->mem ); + option->mem = NULL; + } + *( option->str ) = g_strndup ( xrmValue->addr, xrmValue->size ); + + // Memory + ( option )->mem = *( option->str ); + } + else if ( option->type == xrm_Number ) { + *( option->num ) = (unsigned int) strtoul ( xrmValue->addr, NULL, 10 ); + } + else if ( option->type == xrm_SNumber ) { + *( option->snum ) = (int) strtol ( xrmValue->addr, NULL, 10 ); + } + else if ( option->type == xrm_Boolean ) { + if ( xrmValue->size > 0 && g_ascii_strncasecmp ( xrmValue->addr, "true", xrmValue->size ) == 0 ) { + *( option->num ) = TRUE; + } + else{ + *( option->num ) = FALSE; + } + } +} void config_parse_xresource_options ( Display *display ) { @@ -133,37 +169,46 @@ void config_parse_xresource_options ( Display *display ) const char * namePrefix = "rofi"; const char * classPrefix = "rofi"; - for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( *xrmOptions ); ++i ) { + for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( XrmOption ); ++i ) { char *name, *class; name = g_strdup_printf ( "%s.%s", namePrefix, xrmOptions[i].name ); class = g_strdup_printf ( "%s.%s", classPrefix, xrmOptions[i].name ); if ( XrmGetResource ( xDB, name, class, &xrmType, &xrmValue ) ) { - if ( xrmOptions[i].type == xrm_String ) { - if ( xrmOptions[i].mem != NULL ) { - g_free ( xrmOptions[i].mem ); - xrmOptions[i].mem = NULL; - } - *xrmOptions[i].str = g_strndup ( xrmValue.addr, xrmValue.size ); - - // Memory - xrmOptions[i].mem = ( *xrmOptions[i].str ); - } - else if ( xrmOptions[i].type == xrm_Number ) { - *xrmOptions[i].num = (unsigned int) strtoul ( xrmValue.addr, NULL, 10 ); - } - else if ( xrmOptions[i].type == xrm_SNumber ) { - *xrmOptions[i].snum = (int) strtol ( xrmValue.addr, NULL, 10 ); - } - else if ( xrmOptions[i].type == xrm_Boolean ) { - if ( xrmValue.size > 0 && g_ascii_strncasecmp ( xrmValue.addr, "true", xrmValue.size ) == 0 ) { - *xrmOptions[i].num = TRUE; - } - else{ - *xrmOptions[i].num = FALSE; - } - } + config_parser_set ( &( xrmOptions[i] ), &xrmValue ); + } + + g_free ( class ); + g_free ( name ); + } + XrmDestroyDatabase ( xDB ); +} + +void config_parse_xresource_options_dynamic ( Display *display ) +{ + char *xRMS; + // Map Xresource entries to rofi config options. + XrmInitialize (); + xRMS = XResourceManagerString ( display ); + + if ( xRMS == NULL ) { + return; + } + XrmDatabase xDB = XrmGetStringDatabase ( xRMS ); + + char * xrmType; + XrmValue xrmValue; + const char * namePrefix = "rofi"; + const char * classPrefix = "rofi"; + + for ( unsigned int i = 0; i < num_extra_options; ++i ) { + char *name, *class; + + name = g_strdup_printf ( "%s.%s", namePrefix, extra_options[i].name ); + class = g_strdup_printf ( "%s.%s", classPrefix, extra_options[i].name ); + if ( XrmGetResource ( xDB, name, class, &xrmType, &xrmValue ) ) { + config_parser_set ( &( extra_options[i] ), &xrmValue ); } g_free ( class ); @@ -174,12 +219,47 @@ void config_parse_xresource_options ( Display *display ) void config_xresource_free ( void ) { - for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( *xrmOptions ); ++i ) { + for ( unsigned int i = 0; i < ( sizeof ( xrmOptions ) / sizeof ( *xrmOptions ) ); ++i ) { if ( xrmOptions[i].mem != NULL ) { g_free ( xrmOptions[i].mem ); xrmOptions[i].mem = NULL; } } + for ( unsigned int i = 0; i < num_extra_options; ++i ) { + if ( extra_options[i].mem != NULL ) { + g_free ( extra_options[i].mem ); + extra_options[i].mem = NULL; + } + } + if ( extra_options != NULL ) { + g_free ( extra_options ); + } +} + +void xresource_dump_entry ( const char *namePrefix, XrmOption *option ) +{ + printf ( "%s.%s: %*s", namePrefix, option->name, + (int) ( 20 - strlen ( option->name ) ), "" ); + switch ( option->type ) + { + case xrm_Number: + printf ( "%u", *( option->num ) ); + break; + case xrm_SNumber: + printf ( "%i", *( option->snum ) ); + break; + case xrm_String: + if ( ( *( option->str ) ) != NULL ) { + printf ( "%s", *( option->str ) ); + } + break; + case xrm_Boolean: + printf ( "%s", ( *( option->num ) == TRUE ) ? "true" : "false" ); + break; + default: + break; + } + printf ( "\n" ); } void xresource_dump ( void ) @@ -193,26 +273,9 @@ void xresource_dump ( void ) continue; } } - - printf ( "%s.%s: %*s", namePrefix, xrmOptions[i].name, (int) ( 20 - strlen ( xrmOptions[i].name ) ), - "" ); - switch ( xrmOptions[i].type ) - { - case xrm_Number: - printf ( "%u", *xrmOptions[i].num ); - break; - case xrm_SNumber: - printf ( "%i", *xrmOptions[i].snum ); - break; - case xrm_String: - printf ( "%s", *xrmOptions[i].str ); - break; - case xrm_Boolean: - printf ( "%s", ( ( *xrmOptions[i].num ) == TRUE ) ? "true" : "false" ); - break; - default: - break; - } - printf ( "\n" ); + xresource_dump_entry ( namePrefix, &( xrmOptions[i] ) ); + } + for ( unsigned int i = 0; i < num_extra_options; i++ ) { + xresource_dump_entry ( namePrefix, &( extra_options[i] ) ); } } |