mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -05:00
Fix #128: Better handling of keybindings and remove deprecated launching.
See manpage.
This commit is contained in:
parent
b6652a0221
commit
dee0bfb821
11 changed files with 251 additions and 263 deletions
|
@ -1,9 +1,11 @@
|
|||
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.)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
|
68
doc/rofi.1
68
doc/rofi.1
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
@ -9,6 +19,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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
137
source/rofi.c
137
source/rofi.c
|
@ -73,10 +73,6 @@ 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;
|
||||
|
||||
|
||||
/**
|
||||
* Structure defining a switcher.
|
||||
* It consists of a name, callback and if enabled
|
||||
|
@ -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" );
|
||||
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 ( ( 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" );
|
||||
}
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
// Setup handler for sighub (reload config)
|
||||
const struct sigaction hup_action = {
|
||||
.sa_handler = hup_action_handler
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
config_parser_set ( &( xrmOptions[i] ), &xrmValue );
|
||||
}
|
||||
*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;
|
||||
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;
|
||||
xresource_dump_entry ( namePrefix, &( xrmOptions[i] ) );
|
||||
}
|
||||
printf ( "\n" );
|
||||
for ( unsigned int i = 0; i < num_extra_options; i++ ) {
|
||||
xresource_dump_entry ( namePrefix, &( extra_options[i] ) );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue