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)
|
0.15.2: (unreleased)
|
||||||
Removed features:
|
Removed features:
|
||||||
- Remove (broken) hmode
|
- Remove (broken) hmode
|
||||||
|
- Old style key binding and mode launcher.
|
||||||
New features:
|
New features:
|
||||||
- Word movement in entry box. (#126)
|
- Word movement in entry box. (#126)
|
||||||
- PID file to avoid duplicate Rofi.
|
- PID file to avoid duplicate Rofi.
|
||||||
|
- Generic keybinding and launching for modi. (#128)
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
- Shift left/right movement between swtichers (#125)
|
- Shift left/right movement between swtichers (#125)
|
||||||
- Document updates (#123,#116,#124,etc.)
|
- Document updates (#123,#116,#124,etc.)
|
||||||
|
|
|
@ -69,12 +69,6 @@ Settings config = {
|
||||||
.run_list_command = "",
|
.run_list_command = "",
|
||||||
/** Command executed when running application in terminal */
|
/** Command executed when running application in terminal */
|
||||||
.run_shell_command = "{terminal} -e {cmd}",
|
.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.
|
* Location of the window.
|
||||||
* Enumeration indicating location or gravity of window.
|
* Enumeration indicating location or gravity of window.
|
||||||
|
|
|
@ -16,9 +16,7 @@ rofi - A window switcher, run dialog and dmenu replacement
|
||||||
[ -bgalt *color* ]
|
[ -bgalt *color* ]
|
||||||
[ -hlfg *color* ]
|
[ -hlfg *color* ]
|
||||||
[ -hlbg *color* ]
|
[ -hlbg *color* ]
|
||||||
[ -key *combo* ]
|
[ -key-**mode** *combo* ]
|
||||||
[ -dkey *comdo* ]
|
|
||||||
[ -rkey *comdo* ]
|
|
||||||
[ -terminal *terminal* ]
|
[ -terminal *terminal* ]
|
||||||
[ -location *position* ]
|
[ -location *position* ]
|
||||||
[ -fixed-num-lines ]
|
[ -fixed-num-lines ]
|
||||||
|
@ -79,51 +77,14 @@ The default key combinations are:
|
||||||
## OPTIONS
|
## 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-run F12
|
||||||
rofi -key control+shift+s
|
rofi -key-ssh control+shift+s
|
||||||
rofi -key mod1+Tab
|
rofi -key-window 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.
|
|
||||||
|
|
||||||
`-dmenu`
|
`-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 ]
|
[ \-bgalt \fIcolor\fP ]
|
||||||
[ \-hlfg \fIcolor\fP ]
|
[ \-hlfg \fIcolor\fP ]
|
||||||
[ \-hlbg \fIcolor\fP ]
|
[ \-hlbg \fIcolor\fP ]
|
||||||
[ \-key \fIcombo\fP ]
|
[ \-key\-\fBmode\fP \fIcombo\fP ]
|
||||||
[ \-dkey \fIcomdo\fP ]
|
|
||||||
[ \-rkey \fIcomdo\fP ]
|
|
||||||
[ \-terminal \fIterminal\fP ]
|
[ \-terminal \fIterminal\fP ]
|
||||||
[ \-location \fIposition\fP ]
|
[ \-location \fIposition\fP ]
|
||||||
[ \-fixed\-num\-lines ]
|
[ \-fixed\-num\-lines ]
|
||||||
|
@ -77,59 +75,17 @@ The default key combinations are:
|
||||||
Show ssh\-dialog.
|
Show ssh\-dialog.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
\fB\fC\-key\fR
|
\fB\fC\-key\-**mode**\fR \fBKEY\fP
|
||||||
.IP
|
.IP
|
||||||
Change the key combination to display all windows.
|
Change the key combination to display a \fBmode\fP
|
||||||
.PP
|
.PP
|
||||||
.RS
|
.RS
|
||||||
.nf
|
.nf
|
||||||
rofi \-key F12
|
rofi \-key\-run F12
|
||||||
rofi \-key control+shift+s
|
rofi \-key\-ssh control+shift+s
|
||||||
rofi \-key mod1+Tab
|
rofi \-key\-window mod1+Tab
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.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
|
.PP
|
||||||
\fB\fC\-dmenu\fR
|
\fB\fC\-dmenu\fR
|
||||||
.IP
|
.IP
|
||||||
|
@ -649,14 +605,18 @@ Check quotes used on the commandline: e.g. used “ instead of ".
|
||||||
.SH WEBSITE
|
.SH WEBSITE
|
||||||
.PP
|
.PP
|
||||||
\fBrofi\fP website can be found at here
|
\fBrofi\fP website can be found at here
|
||||||
\[la]https://davedavenport.github.io/rofi/\[ra]
|
.UR https://davedavenport.github.io/rofi/
|
||||||
|
.UE
|
||||||
.PP
|
.PP
|
||||||
\fBrofi\fP bugtracker can be found here
|
\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
|
.SH AUTHOR
|
||||||
.PP
|
.PP
|
||||||
Qball Cow
|
Qball Cow
|
||||||
\[la]qball@gmpclient.org\[ra]
|
.MT qball@gmpclient.org
|
||||||
|
.ME
|
||||||
.PP
|
.PP
|
||||||
Original code based on work by: Sean Pringle
|
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 */
|
/** Command for listing executables */
|
||||||
char * run_list_command;
|
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 */
|
/** Windows location/gravity */
|
||||||
WindowLocation location;
|
WindowLocation location;
|
||||||
/** Padding between elements */
|
/** Padding between elements */
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
#ifndef __XRMOPTIONS_H__
|
#ifndef __XRMOPTIONS_H__
|
||||||
#define __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.
|
* @param display Handler of the display to fetch the settings from.
|
||||||
*
|
*
|
||||||
|
@ -9,6 +19,14 @@
|
||||||
*/
|
*/
|
||||||
void config_parse_xresource_options ( Display *display );
|
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.
|
* Free any allocated memory.
|
||||||
*/
|
*/
|
||||||
|
@ -20,4 +38,5 @@ void config_xresource_free ( void );
|
||||||
*/
|
*/
|
||||||
void xresource_dump ( void );
|
void xresource_dump ( void );
|
||||||
|
|
||||||
|
void config_parser_add_option ( XrmOptionType type, const char *key, void **value );
|
||||||
#endif
|
#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-list-command", &( config.run_list_command ) );
|
||||||
find_arg_str ( argc, argv, "-run-shell-command", &( config.run_shell_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_char ( argc, argv, "-sep", &( config.separator ) );
|
||||||
|
|
||||||
|
|
||||||
find_arg_int ( argc, argv, "-eh", &( config.element_height ) );
|
find_arg_int ( argc, argv, "-eh", &( config.element_height ) );
|
||||||
|
|
||||||
find_arg_uint ( argc, argv, "-lazy-filter-limit", &( config.lazy_filter_limit ) );
|
find_arg_uint ( argc, argv, "-lazy-filter-limit", &( config.lazy_filter_limit ) );
|
||||||
|
|
155
source/rofi.c
155
source/rofi.c
|
@ -65,17 +65,13 @@ typedef enum _MainLoopEvent
|
||||||
} MainLoopEvent;
|
} MainLoopEvent;
|
||||||
|
|
||||||
// Pidfile.
|
// Pidfile.
|
||||||
char *pidfile = NULL;
|
char *pidfile = NULL;
|
||||||
const char *cache_dir = NULL;
|
const char *cache_dir = NULL;
|
||||||
Display *display = NULL;
|
Display *display = NULL;
|
||||||
char *display_str = 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;
|
|
||||||
|
|
||||||
|
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
|
||||||
|
Atom netatoms[NUM_NETATOMS];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure defining a switcher.
|
* Structure defining a switcher.
|
||||||
|
@ -93,6 +89,11 @@ typedef struct _Switcher
|
||||||
switcher_callback_free_data cb_data_free;
|
switcher_callback_free_data cb_data_free;
|
||||||
// Textbox used in the sidebar-mode.
|
// Textbox used in the sidebar-mode.
|
||||||
textbox *tb;
|
textbox *tb;
|
||||||
|
// Keybindings (keysym and modmask)
|
||||||
|
char * keycfg;
|
||||||
|
char * keystr;
|
||||||
|
KeySym keysym;
|
||||||
|
unsigned int modmask;
|
||||||
} Switcher;
|
} Switcher;
|
||||||
|
|
||||||
// Array of switchers.
|
// 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 )
|
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
|
||||||
// pressing one of the global key bindings closes the switcher. this allows fast closing of the menu if an item is not selected
|
// menu if an item is not selected
|
||||||
|| ( ( windows_modmask == AnyModifier || modstate & windows_modmask ) && key == windows_keysym )
|
for ( unsigned int i = 0; i < num_switchers; i++ ) {
|
||||||
|| ( ( rundialog_modmask == AnyModifier || modstate & rundialog_modmask ) && key == rundialog_keysym )
|
if ( switchers[i].keystr != NULL ) {
|
||||||
|| ( ( sshdialog_modmask == AnyModifier || modstate & sshdialog_modmask ) && key == sshdialog_keysym )
|
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->retv = MENU_CANCEL;
|
||||||
state->quit = TRUE;
|
state->quit = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1418,19 +1427,13 @@ static void handle_keypress ( XEvent *ev )
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
KeySym key = XkbKeycodeToKeysym ( display, ev->xkey.keycode, 0, 0 );
|
KeySym key = XkbKeycodeToKeysym ( display, ev->xkey.keycode, 0, 0 );
|
||||||
if ( ( windows_modmask == AnyModifier || ev->xkey.state & windows_modmask ) &&
|
for ( unsigned int i = 0; i < num_switchers; i++ ) {
|
||||||
key == windows_keysym ) {
|
if ( switchers[i].keystr != NULL ) {
|
||||||
index = switcher_get ( "window" );
|
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 ) {
|
if ( index >= 0 ) {
|
||||||
run_switcher ( TRUE, index );
|
run_switcher ( TRUE, index );
|
||||||
|
@ -1468,12 +1471,19 @@ static void cleanup ()
|
||||||
|
|
||||||
// Cleaning up memory allocated by the Xresources file.
|
// Cleaning up memory allocated by the Xresources file.
|
||||||
config_xresource_free ();
|
config_xresource_free ();
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < num_switchers; i++ ) {
|
for ( unsigned int i = 0; i < num_switchers; i++ ) {
|
||||||
// only used for script dialog.
|
// only used for script dialog.
|
||||||
if ( switchers[i].cb_data_free != NULL ) {
|
if ( switchers[i].cb_data_free != NULL ) {
|
||||||
switchers[i].cb_data_free ( switchers[i].cb_data );
|
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 );
|
g_free ( switchers );
|
||||||
|
|
||||||
|
@ -1501,9 +1511,14 @@ static void setup_switchers ( void )
|
||||||
token != NULL;
|
token != NULL;
|
||||||
token = strtok_r ( NULL, ",", &savept ) ) {
|
token = strtok_r ( NULL, ",", &savept ) ) {
|
||||||
// Resize and add entry.
|
// 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 = NULL;
|
||||||
switchers[num_switchers].cb_data_free = 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.
|
// Window switcher.
|
||||||
if ( strcasecmp ( token, "window" ) == 0 ) {
|
if ( strcasecmp ( token, "window" ) == 0 ) {
|
||||||
|
@ -1540,9 +1555,19 @@ static void setup_switchers ( void )
|
||||||
token = NULL;
|
token = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Keybinding.
|
||||||
}
|
}
|
||||||
// Free string that was modified by strtok_r
|
// Free string that was modified by strtok_r
|
||||||
g_free ( switcher_str );
|
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.
|
// Parse command line for settings.
|
||||||
config_parse_cmd_options ( stored_argc, stored_argv );
|
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
|
// Sanity check
|
||||||
config_sanity_check ();
|
config_sanity_check ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle sighub request.
|
* Handle sighub request.
|
||||||
* Currently we just reload the configuration.
|
* Currently we just reload the configuration.
|
||||||
|
@ -1582,6 +1620,7 @@ static void hup_action_handler ( int num )
|
||||||
Display *display = XOpenDisplay ( display_str );
|
Display *display = XOpenDisplay ( display_str );
|
||||||
if ( display ) {
|
if ( display ) {
|
||||||
load_configuration ( display );
|
load_configuration ( display );
|
||||||
|
load_configuration_dynamic ( display );
|
||||||
XCloseDisplay ( display );
|
XCloseDisplay ( display );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1647,6 +1686,10 @@ int main ( int argc, char *argv[] )
|
||||||
|
|
||||||
|
|
||||||
load_configuration ( display );
|
load_configuration ( display );
|
||||||
|
// setup_switchers
|
||||||
|
setup_switchers ();
|
||||||
|
// Reload for dynamic part.
|
||||||
|
load_configuration_dynamic ( display );
|
||||||
|
|
||||||
// Dump.
|
// Dump.
|
||||||
if ( find_arg ( argc, argv, "-dump-xresources" ) >= 0 ) {
|
if ( find_arg ( argc, argv, "-dump-xresources" ) >= 0 ) {
|
||||||
|
@ -1654,9 +1697,6 @@ int main ( int argc, char *argv[] )
|
||||||
exit ( EXIT_SUCCESS );
|
exit ( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup_switchers
|
|
||||||
setup_switchers ();
|
|
||||||
|
|
||||||
// Set up X interaction.
|
// Set up X interaction.
|
||||||
signal ( SIGCHLD, catch_exit );
|
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 );
|
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{
|
else{
|
||||||
// Daemon mode, Listen to key presses..
|
// Daemon mode, Listen to key presses..
|
||||||
if ( switcher_get ( "window" ) >= 0 ) {
|
for ( unsigned int i = 0; i < num_switchers; i++ ) {
|
||||||
x11_parse_key ( config.window_key, &windows_modmask, &windows_keysym );
|
if ( switchers[i].keystr != NULL ) {
|
||||||
x11_grab_key ( display, windows_modmask, windows_keysym );
|
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)
|
// Setup handler for sighub (reload config)
|
||||||
const struct sigaction hup_action = {
|
const struct sigaction hup_action = {
|
||||||
.sa_handler = hup_action_handler
|
.sa_handler = hup_action_handler
|
||||||
|
|
|
@ -312,7 +312,7 @@ void textbox_draw ( textbox *tb )
|
||||||
// cursor handling for edit mode
|
// cursor handling for edit mode
|
||||||
void textbox_cursor ( textbox *tb, int pos )
|
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 ) );
|
tb->cursor = MAX ( 0, MIN ( length, pos ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ void textbox_cursor_dec ( textbox *tb )
|
||||||
// Move word right
|
// Move word right
|
||||||
void textbox_cursor_inc_word ( textbox *tb )
|
void textbox_cursor_inc_word ( textbox *tb )
|
||||||
{
|
{
|
||||||
if(tb->text == NULL) {
|
if ( tb->text == NULL ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Find word boundaries, with pango_Break?
|
// Find word boundaries, with pango_Break?
|
||||||
|
@ -351,7 +351,7 @@ void textbox_cursor_inc_word ( textbox *tb )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c == NULL) {
|
if ( c == NULL ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ( ( c = g_utf8_next_char ( c ) ) ) {
|
while ( ( c = g_utf8_next_char ( c ) ) ) {
|
||||||
|
@ -452,7 +452,7 @@ void textbox_delete ( textbox *tb, int pos, int dlen )
|
||||||
// delete on character
|
// delete on character
|
||||||
void textbox_cursor_del ( textbox *tb )
|
void textbox_cursor_del ( textbox *tb )
|
||||||
{
|
{
|
||||||
if(tb->text == NULL) {
|
if ( tb->text == NULL ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int index = g_utf8_next_char ( &( tb->text[tb->cursor] ) ) - tb->text;
|
int index = g_utf8_next_char ( &( tb->text[tb->cursor] ) ) - tb->text;
|
||||||
|
|
|
@ -412,7 +412,7 @@ void x11_setup ( Display *display )
|
||||||
|
|
||||||
extern Colormap map;
|
extern Colormap map;
|
||||||
extern XVisualInfo vinfo;
|
extern XVisualInfo vinfo;
|
||||||
int truecolor = FALSE;
|
int truecolor = FALSE;
|
||||||
void create_visual_and_colormap ( Display *display )
|
void create_visual_and_colormap ( Display *display )
|
||||||
{
|
{
|
||||||
int screen = DefaultScreen ( display );
|
int screen = DefaultScreen ( display );
|
||||||
|
|
|
@ -33,25 +33,16 @@
|
||||||
#include "rofi.h"
|
#include "rofi.h"
|
||||||
#include "xrmoptions.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
|
typedef struct
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
char * name;
|
const char * name;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned int * num;
|
unsigned int * num;
|
||||||
int * snum;
|
int * snum;
|
||||||
char ** str;
|
char ** str;
|
||||||
|
void *pointer;
|
||||||
};
|
};
|
||||||
char *mem;
|
char *mem;
|
||||||
} XrmOption;
|
} XrmOption;
|
||||||
|
@ -108,13 +99,58 @@ static XrmOption xrmOptions[] = {
|
||||||
{ xrm_Boolean, "levenshtein-sort", { .num = &config.levenshtein_sort }, NULL },
|
{ xrm_Boolean, "levenshtein-sort", { .num = &config.levenshtein_sort }, NULL },
|
||||||
{ xrm_Boolean, "case-sensitive", { .num = &config.case_sensitive }, NULL },
|
{ xrm_Boolean, "case-sensitive", { .num = &config.case_sensitive }, NULL },
|
||||||
/* Key bindings */
|
/* 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_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL },
|
||||||
{ xrm_Number, "lazy-filter-limit", { .num = &config.lazy_filter_limit }, 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 )
|
void config_parse_xresource_options ( Display *display )
|
||||||
{
|
{
|
||||||
|
@ -133,37 +169,46 @@ void config_parse_xresource_options ( Display *display )
|
||||||
const char * namePrefix = "rofi";
|
const char * namePrefix = "rofi";
|
||||||
const char * classPrefix = "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;
|
char *name, *class;
|
||||||
|
|
||||||
name = g_strdup_printf ( "%s.%s", namePrefix, xrmOptions[i].name );
|
name = g_strdup_printf ( "%s.%s", namePrefix, xrmOptions[i].name );
|
||||||
class = g_strdup_printf ( "%s.%s", classPrefix, xrmOptions[i].name );
|
class = g_strdup_printf ( "%s.%s", classPrefix, xrmOptions[i].name );
|
||||||
|
|
||||||
if ( XrmGetResource ( xDB, name, class, &xrmType, &xrmValue ) ) {
|
if ( XrmGetResource ( xDB, name, class, &xrmType, &xrmValue ) ) {
|
||||||
if ( xrmOptions[i].type == xrm_String ) {
|
config_parser_set ( &( xrmOptions[i] ), &xrmValue );
|
||||||
if ( xrmOptions[i].mem != NULL ) {
|
}
|
||||||
g_free ( xrmOptions[i].mem );
|
|
||||||
xrmOptions[i].mem = NULL;
|
|
||||||
}
|
|
||||||
*xrmOptions[i].str = g_strndup ( xrmValue.addr, xrmValue.size );
|
|
||||||
|
|
||||||
// Memory
|
g_free ( class );
|
||||||
xrmOptions[i].mem = ( *xrmOptions[i].str );
|
g_free ( name );
|
||||||
}
|
}
|
||||||
else if ( xrmOptions[i].type == xrm_Number ) {
|
XrmDestroyDatabase ( xDB );
|
||||||
*xrmOptions[i].num = (unsigned int) strtoul ( xrmValue.addr, NULL, 10 );
|
}
|
||||||
}
|
|
||||||
else if ( xrmOptions[i].type == xrm_SNumber ) {
|
void config_parse_xresource_options_dynamic ( Display *display )
|
||||||
*xrmOptions[i].snum = (int) strtol ( xrmValue.addr, NULL, 10 );
|
{
|
||||||
}
|
char *xRMS;
|
||||||
else if ( xrmOptions[i].type == xrm_Boolean ) {
|
// Map Xresource entries to rofi config options.
|
||||||
if ( xrmValue.size > 0 && g_ascii_strncasecmp ( xrmValue.addr, "true", xrmValue.size ) == 0 ) {
|
XrmInitialize ();
|
||||||
*xrmOptions[i].num = TRUE;
|
xRMS = XResourceManagerString ( display );
|
||||||
}
|
|
||||||
else{
|
if ( xRMS == NULL ) {
|
||||||
*xrmOptions[i].num = FALSE;
|
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 );
|
g_free ( class );
|
||||||
|
@ -174,12 +219,47 @@ void config_parse_xresource_options ( Display *display )
|
||||||
|
|
||||||
void config_xresource_free ( void )
|
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 ) {
|
if ( xrmOptions[i].mem != NULL ) {
|
||||||
g_free ( xrmOptions[i].mem );
|
g_free ( xrmOptions[i].mem );
|
||||||
xrmOptions[i].mem = NULL;
|
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 )
|
void xresource_dump ( void )
|
||||||
|
@ -193,26 +273,9 @@ void xresource_dump ( void )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xresource_dump_entry ( namePrefix, &( xrmOptions[i] ) );
|
||||||
printf ( "%s.%s: %*s", namePrefix, xrmOptions[i].name, (int) ( 20 - strlen ( xrmOptions[i].name ) ),
|
}
|
||||||
"" );
|
for ( unsigned int i = 0; i < num_extra_options; i++ ) {
|
||||||
switch ( xrmOptions[i].type )
|
xresource_dump_entry ( namePrefix, &( extra_options[i] ) );
|
||||||
{
|
|
||||||
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" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue