1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

rofi: Drop daemon mode

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
This commit is contained in:
Quentin Glidic 2016-02-21 22:03:13 +01:00
parent 88ddb7f04e
commit 990914d20f
16 changed files with 11 additions and 394 deletions

View file

@ -20,7 +20,6 @@
[ -bgalt *color* ] [ -bgalt *color* ]
[ -hlfg *color* ] [ -hlfg *color* ]
[ -hlbg *color* ] [ -hlbg *color* ]
[ -key-**mode** *combo* ]
[ -terminal *terminal* ] [ -terminal *terminal* ]
[ -location *position* ] [ -location *position* ]
[ -fixed-num-lines ] [ -fixed-num-lines ]
@ -73,8 +72,7 @@ filter, tokenized search and more.
## USAGE ## USAGE
**rofi** can be used in three ways, single-shot; executes once and directly exits when done, as a **rofi** can be used in two ways, single-shot (runs a mode then exits) or emulating dmenu.
daemon listening to specific key-combination or emulating dmenu.
### Single-shot mode ### Single-shot mode
@ -83,15 +81,6 @@ To show the run dialog:
rofi -show run rofi -show run
### Daemon mode
To launch **rofi** in daemon mode don't specify any mode, instead keys can be bound
to launch a certain mode. To show run-mode by pressing `F2` start **rofi** like this:
rofi -key-run F2
Keybindings can also be specified in the `Xresources` file.
### Emulating dmenu ### Emulating dmenu
**rofi** can emulate `dmenu` (a dynamic menu for X) when launched with the `-dmenu` flag. **rofi** can emulate `dmenu` (a dynamic menu for X) when launched with the `-dmenu` flag.
@ -155,14 +144,6 @@ This does not validate all passed values (e.g. colors).
Dump the current color schme in Xresources format to the command-line. Dump the current color schme in Xresources format to the command-line.
`-key-{mode}` **KEY**
Set the key combination to display a {mode} in daemon mode.
rofi -key-run F12
rofi -key-ssh control+shift+s
rofi -key-window SuperL+Tab
`-threads` *num* `-threads` *num*
Specify the number of threads **rofi** should use: Specify the number of threads **rofi** should use:
@ -213,10 +194,6 @@ Example: Have a mode 'Workspaces' using the `i3_switch_workspace.sh` script:
Start in case sensitive mode. Start in case sensitive mode.
`-quiet`
Do not print any message when starting in daemon mode.
`-fuzzy` `-fuzzy`
Enable experimental fuzzy matching. Enable experimental fuzzy matching.
@ -702,21 +679,6 @@ This way it can be used as a drop-in replacement for dmenu. just copy or symlink
ln -s /usr/bin/rofi /usr/bin/dmenu ln -s /usr/bin/rofi /usr/bin/dmenu
## SIGNALS
`HUP`
If in daemon mode, reload the configuration from Xresources. (commandline arguments still -override
Xresources). This will also reload configured key-bindings.
`INT`
If in daemon mode, quits **rofi**.
`USR1`
If in daemon mode, dumps the current configuration to stdout. Similar to `-xresources-dump`
## THEMING ## THEMING
With **rofi** 0.15.4 we have a new way of specifying colors, the old settings still apply (for now). With **rofi** 0.15.4 we have a new way of specifying colors, the old settings still apply (for now).

View file

@ -37,14 +37,9 @@ typedef int ( *_mode_is_not_ascii )( const Mode *sw, unsigned int index );
struct _Mode struct _Mode
{ {
/** Name (max 31 char long) */ /** Name (max 31 char long) */
char name[32]; char name[32];
char cfg_name_key[128]; char cfg_name_key[128];
char *display_name; char *display_name;
/** Keybindings (keysym and modmask) */
char * keycfg;
char * keystr;
xkb_keysym_t keysym;
unsigned int modmask;
/** /**
* A switcher normally consists of the following parts: * A switcher normally consists of the following parts:

View file

@ -140,17 +140,6 @@ int mode_token_match ( const Mode *mode, char **tokens, int not_ascii, int case_
*/ */
const char * mode_get_name ( const Mode *mode ); const char * mode_get_name ( const Mode *mode );
/**
* @param mode The mode to query
* @param key The KeySym to match
* @param state The Modmask to match
*
* Match keybinding of mode.
*
* return TRUE when matching, FALSE otherwise
*/
int mode_check_keybinding ( const Mode *mode, KeySym key, unsigned int modstate );
/** /**
* @param mode The mode to query * @param mode The mode to query
* *
@ -158,39 +147,6 @@ int mode_check_keybinding ( const Mode *mode, KeySym key, unsigned int modstate
*/ */
void mode_free ( Mode **mode ); void mode_free ( Mode **mode );
/**
* @param mode The mode to query
*
* Setup the keybinding for this mode.
*/
void mode_setup_keybinding ( Mode *mode );
/**
* @param mode The mode to query
* @param display The X Server display handle.
*
* Grab the key on the display.
* This first parses the key string and if successful asks X11 for a grab.
*
* return FALSE when key could not be grabbed.
*/
int mode_grab_key ( Mode *mode, Display *display );
/**
* @param mode The mode to query
* @param display The X Server display handle.
*
* Releases previously grabbed key.
*/
void mode_ungrab_key ( Mode *mode, Display *display );
/**
* @param mode The mode to query
*
* Print the current keybing for this mode to stdout.
*/
void mode_print_keybindings ( const Mode *mode );
/** /**
* @param mode The mode to query * @param mode The mode to query
* *

View file

@ -37,17 +37,6 @@ unsigned int rofi_get_num_enabled_modi ( void );
*/ */
const Mode * rofi_get_mode ( unsigned int index ); const Mode * rofi_get_mode ( unsigned int index );
/**
* @param key the Key to match
* @param modstate the modifier state to match
*
* Match key and modifier state against modi.
*
* @return the index of the switcher that matches the key combination
* specified by key and modstate. Returns -1 if none was found
*/
int locate_switcher ( xkb_keysym_t key, unsigned int modstate );
void rofi_set_return_code ( int code ); void rofi_set_return_code ( int code );
/** Reset terminal */ /** Reset terminal */
#define color_reset "\033[0m" #define color_reset "\033[0m"

View file

@ -99,24 +99,6 @@ void release_keyboard ( Display *display );
*/ */
int take_keyboard ( Display *display, Window w ); int take_keyboard ( Display *display, Window w );
/**
* @param display Connection to the X server.
* @param modmask Modifier mask.
* @param key Key.
*
* Grab key on display.
*/
void x11_grab_key ( Display *display, unsigned int modmask, KeySym key );
/**
* @param display Connection to the X server.
* @param modmask Modifier mask.
* @param key Key.
*
* Ungrab key on display.
*/
void x11_ungrab_key ( Display *display, unsigned int modmask, KeySym key );
/** /**
* @param combo String representing the key combo * @param combo String representing the key combo
* @param mod [out] The modifier specified (or AnyModifier if not specified) * @param mod [out] The modifier specified (or AnyModifier if not specified)

View file

@ -258,9 +258,6 @@ Mode combi_mode =
{ {
.name = "combi", .name = "combi",
.cfg_name_key = "display-combi", .cfg_name_key = "display-combi",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = combi_mode_init, ._init = combi_mode_init,
._get_num_entries = combi_mode_get_num_entries, ._get_num_entries = combi_mode_get_num_entries,
._result = combi_mode_result, ._result = combi_mode_result,

View file

@ -341,9 +341,6 @@ Mode dmenu_mode =
{ {
.name = "dmenu", .name = "dmenu",
.cfg_name_key = "display-combi", .cfg_name_key = "display-combi",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = dmenu_mode_init, ._init = dmenu_mode_init,
._get_num_entries = dmenu_mode_get_num_entries, ._get_num_entries = dmenu_mode_get_num_entries,
._result = NULL, ._result = NULL,

View file

@ -431,9 +431,6 @@ Mode drun_mode =
{ {
.name = "drun", .name = "drun",
.cfg_name_key = "display-drun", .cfg_name_key = "display-drun",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = drun_mode_init, ._init = drun_mode_init,
._get_num_entries = drun_mode_get_num_entries, ._get_num_entries = drun_mode_get_num_entries,
._result = drun_mode_result, ._result = drun_mode_result,

View file

@ -432,9 +432,6 @@ Mode run_mode =
{ {
.name = "run", .name = "run",
.cfg_name_key = "display-run", .cfg_name_key = "display-run",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = run_mode_init, ._init = run_mode_init,
._get_num_entries = run_mode_get_num_entries, ._get_num_entries = run_mode_get_num_entries,
._result = run_mode_result, ._result = run_mode_result,

View file

@ -195,8 +195,6 @@ Mode *script_switcher_parse_setup ( const char *str )
g_free ( parse ); g_free ( parse );
if ( index == 2 ) { if ( index == 2 ) {
sw->free = script_switcher_free; sw->free = script_switcher_free;
sw->keysym = None;
sw->modmask = AnyModifier;
sw->_init = script_mode_init; sw->_init = script_mode_init;
sw->_get_num_entries = script_mode_get_num_entries; sw->_get_num_entries = script_mode_get_num_entries;
sw->_result = script_mode_result; sw->_result = script_mode_result;

View file

@ -493,9 +493,6 @@ Mode ssh_mode =
{ {
.name = "ssh", .name = "ssh",
.cfg_name_key = "display-ssh", .cfg_name_key = "display-ssh",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = ssh_mode_init, ._init = ssh_mode_init,
._get_num_entries = ssh_mode_get_num_entries, ._get_num_entries = ssh_mode_get_num_entries,
._result = ssh_mode_result, ._result = ssh_mode_result,

View file

@ -592,9 +592,6 @@ Mode window_mode =
{ {
.name = "window", .name = "window",
.cfg_name_key = "display-window", .cfg_name_key = "display-window",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = window_mode_init, ._init = window_mode_init,
._get_num_entries = window_mode_get_num_entries, ._get_num_entries = window_mode_get_num_entries,
._result = window_mode_result, ._result = window_mode_result,
@ -610,9 +607,6 @@ Mode window_mode_cd =
{ {
.name = "windowcd", .name = "windowcd",
.cfg_name_key = "display-windowcd", .cfg_name_key = "display-windowcd",
.keycfg = NULL,
.keystr = NULL,
.modmask = AnyModifier,
._init = window_mode_init_cd, ._init = window_mode_init_cd,
._get_num_entries = window_mode_get_num_entries, ._get_num_entries = window_mode_get_num_entries,
._result = window_mode_result, ._result = window_mode_result,

View file

@ -84,73 +84,16 @@ const char *mode_get_name ( const Mode *mode )
return mode->name; return mode->name;
} }
void mode_setup_keybinding ( Mode *mode )
{
g_assert ( mode != NULL );
mode->keycfg = g_strdup_printf ( "key-%s", mode->name );
config_parser_add_option ( xrm_String, mode->keycfg, (void * *) &( mode->keystr ), "Keybinding" );
}
int mode_check_keybinding ( const Mode *mode, KeySym key, unsigned int modstate )
{
g_assert ( mode != NULL );
if ( mode->keystr != NULL ) {
if ( mode->modmask == modstate && mode->keysym == key ) {
return TRUE;
}
}
return FALSE;
}
void mode_free ( Mode **mode ) void mode_free ( Mode **mode )
{ {
g_assert ( mode != NULL ); g_assert ( mode != NULL );
g_assert ( ( *mode ) != NULL ); g_assert ( ( *mode ) != NULL );
if ( ( *mode )->keycfg != NULL ) {
g_free ( ( *mode )->keycfg );
( *mode )->keycfg = NULL;
}
if ( ( *mode )->free != NULL ) { if ( ( *mode )->free != NULL ) {
( *mode )->free ( *mode ); ( *mode )->free ( *mode );
} }
( *mode ) = NULL; ( *mode ) = NULL;
} }
int mode_grab_key ( Mode *mode, Display *display )
{
g_assert ( mode != NULL );
g_assert ( display != NULL );
if ( mode->keystr != NULL ) {
x11_parse_key ( mode->keystr, &( mode->modmask ), &( mode->keysym ) );
if ( mode->keysym != NoSymbol ) {
x11_grab_key ( display, mode->modmask, mode->keysym );
return TRUE;
}
}
return FALSE;
}
void mode_ungrab_key ( Mode *mode, Display *display )
{
g_assert ( mode != NULL );
g_assert ( display != NULL );
if ( mode->keystr != NULL ) {
if ( mode->keysym != NoSymbol ) {
x11_ungrab_key ( display, mode->modmask, mode->keysym );
}
}
}
void mode_print_keybindings ( const Mode *mode )
{
g_assert ( mode != NULL );
if ( mode->keystr != NULL ) {
fprintf ( stdout, "\t* "color_bold "%s"color_reset " on %s\n", mode->name, mode->keystr );
}
else {
fprintf ( stdout, "\t* "color_bold "%s"color_reset " on <unspecified>\n", mode->name );
}
}
void *mode_get_private_data ( const Mode *mode ) void *mode_get_private_data ( const Mode *mode )
{ {
g_assert ( mode != NULL ); g_assert ( mode != NULL );

View file

@ -70,7 +70,6 @@
#include "view-internal.h" #include "view-internal.h"
#include "xkb-internal.h" #include "xkb-internal.h"
gboolean daemon_mode = FALSE;
// Pidfile. // Pidfile.
char *pidfile = NULL; char *pidfile = NULL;
const char *cache_dir = NULL; const char *cache_dir = NULL;
@ -131,19 +130,6 @@ static int switcher_get ( const char *name )
return -1; return -1;
} }
extern unsigned int NumlockMask;
int locate_switcher ( xkb_keysym_t key, unsigned int modstate )
{
// ignore annoying modifiers
unsigned int modstate_filtered = modstate & ~( LockMask | NumlockMask );
for ( unsigned int i = 0; i < num_modi; i++ ) {
if ( mode_check_keybinding ( modi[i], key, modstate_filtered ) ) {
return i;
}
}
return -1;
}
/** /**
* Do needed steps to start showing the gui * Do needed steps to start showing the gui
*/ */
@ -285,26 +271,6 @@ int show_error_message ( const char *msg, int markup )
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/**
* Function that listens for global key-presses.
* This is only used when in daemon mode.
*/
static void handle_keypress ( xcb_key_press_event_t *ev, struct xkb_stuff *xkb )
{
xkb_keysym_t key = xkb_state_key_get_one_sym ( xkb->state, ev->detail );
int index;
index = locate_switcher ( key, ev->state );
if ( index >= 0 ) {
run_switcher ( index );
}
else {
fprintf ( stderr,
"Warning: Unhandled keypress in global keyhandler, keycode = %u mask = %u\n",
ev->detail,
ev->state );
}
}
/** /**
* Help function. * Help function.
*/ */
@ -340,23 +306,6 @@ static void help ( G_GNUC_UNUSED int argc, char **argv )
printf ( "Bugreports: "PACKAGE_BUGREPORT "\n" ); printf ( "Bugreports: "PACKAGE_BUGREPORT "\n" );
} }
static void release_global_keybindings ()
{
for ( unsigned int i = 0; i < num_modi; i++ ) {
mode_ungrab_key ( modi[i], display );
}
}
static int grab_global_keybindings ()
{
int key_bound = FALSE;
for ( unsigned int i = 0; i < num_modi; i++ ) {
if ( mode_grab_key ( modi[i], display ) ) {
key_bound = TRUE;
}
}
return key_bound;
}
/** /**
* Function bound by 'atexit'. * Function bound by 'atexit'.
* Cleanup globally allocated memory. * Cleanup globally allocated memory.
@ -371,12 +320,6 @@ static void cleanup ()
g_main_loop_unref ( main_loop ); g_main_loop_unref ( main_loop );
main_loop = NULL; main_loop = NULL;
} }
if ( daemon_mode ) {
release_global_keybindings ();
if ( !quiet ) {
fprintf ( stdout, "Quit from daemon mode.\n" );
}
}
// Cleanup // Cleanup
if ( display != NULL ) { if ( display != NULL ) {
if ( sncontext != NULL ) { if ( sncontext != NULL ) {
@ -479,9 +422,6 @@ static void setup_modi ( void )
g_free ( switcher_str ); g_free ( switcher_str );
// We cannot do this in main loop, as we create pointer to string, // We cannot do this in main loop, as we create pointer to string,
// and re-alloc moves that pointer. // and re-alloc moves that pointer.
for ( unsigned int i = 0; i < num_modi; i++ ) {
mode_setup_keybinding ( modi[i] );
}
mode_set_config ( &ssh_mode ); mode_set_config ( &ssh_mode );
mode_set_config ( &run_mode ); mode_set_config ( &run_mode );
mode_set_config ( &drun_mode ); mode_set_config ( &drun_mode );
@ -515,42 +455,6 @@ static inline void load_configuration_dynamic ( Display *display )
config_parse_cmd_options_dynamic ( ); config_parse_cmd_options_dynamic ( );
} }
static void print_global_keybindings ()
{
if ( quiet ) {
fprintf ( stdout, "listening to the following keys:\n" );
}
for ( unsigned int i = 0; i < num_modi; i++ ) {
mode_print_keybindings ( modi[i] );
}
}
static void reload_configuration ()
{
if ( find_arg ( "-no-config" ) < 0 ) {
TICK ();
// Reset the color cache
color_cache_reset ();
// We need to open a new connection to X11, otherwise we get old
// configuration
Display *temp_display = XOpenDisplay ( display_str );
if ( temp_display ) {
load_configuration ( temp_display );
load_configuration_dynamic ( temp_display );
// Sanity check
config_sanity_check ( temp_display );
parse_keys_abe ();
XCloseDisplay ( temp_display );
}
else {
fprintf ( stderr, "Failed to get a new connection to the X11 server. No point in continuing.\n" );
abort ();
}
TICK_N ( "Load config" );
}
}
/** /**
* Process X11 events in the main-loop (gui-thread) of the application. * Process X11 events in the main-loop (gui-thread) of the application.
*/ */
@ -568,21 +472,10 @@ static gboolean main_loop_x11_event_handler ( xcb_generic_event_t *ev, G_GNUC_UN
// cleanup // cleanup
if ( rofi_view_get_active () == NULL ) { if ( rofi_view_get_active () == NULL ) {
teardown ( pfd ); teardown ( pfd );
if ( !daemon_mode ) { g_main_loop_quit ( main_loop );
g_main_loop_quit ( main_loop );
}
} }
} }
} }
else {
// X11 produced an event. Consume them.
// If we get an event that does not belong to a window:
// Ignore it.
// If keypress, handle it.
if ( ( ev->response_type & ~0x80 ) == XCB_KEY_PRESS ) {
handle_keypress ( (xcb_key_press_event_t *) ev, &xkb );
}
}
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
@ -591,22 +484,6 @@ static gboolean main_loop_x11_event_handler ( xcb_generic_event_t *ev, G_GNUC_UN
* *
* returns TRUE when mainloop should be stopped. * returns TRUE when mainloop should be stopped.
*/ */
static gboolean main_loop_signal_handler_hup ( G_GNUC_UNUSED gpointer data )
{
if ( !quiet ) {
fprintf ( stdout, "Reload configuration\n" );
}
// Release the keybindings.
release_global_keybindings ();
// Reload config
reload_configuration ();
// Grab the possibly new keybindings.
grab_global_keybindings ();
// We need to flush, otherwise the first key presses are not caught.
xcb_flush ( xcb_connection );
XFlush ( display );
return G_SOURCE_CONTINUE;
}
static gboolean main_loop_signal_handler_int ( G_GNUC_UNUSED gpointer data ) static gboolean main_loop_signal_handler_int ( G_GNUC_UNUSED gpointer data )
{ {
@ -615,12 +492,6 @@ static gboolean main_loop_signal_handler_int ( G_GNUC_UNUSED gpointer data )
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
static gboolean main_loop_signal_handler_usr1 ( G_GNUC_UNUSED gpointer data )
{
config_parse_xresource_dump ();
return G_SOURCE_CONTINUE;
}
static int error_trap_depth = 0; static int error_trap_depth = 0;
static void error_trap_push ( G_GNUC_UNUSED SnDisplay *display, G_GNUC_UNUSED Display *xdisplay ) static void error_trap_push ( G_GNUC_UNUSED SnDisplay *display, G_GNUC_UNUSED Display *xdisplay )
{ {
@ -697,32 +568,9 @@ static gboolean startup ( G_GNUC_UNUSED gpointer data )
} }
} }
else{ else{
// Daemon mode, Listen to key presses.. // Daemon mode
if ( !grab_global_keybindings () ) { fprintf ( stderr, "Rofi daemon mode is now removed.\n" );
fprintf ( stderr, "Rofi was launched in daemon mode, but no key-binding was specified.\n" ); fprintf ( stderr, "Please use your window manager binding functionality or xbindkeys to replace it.\n" );
fprintf ( stderr, "Please check the manpage on how to specify a key-binding.\n" );
fprintf ( stderr, "The following modi are enabled and keys can be specified:\n" );
for ( unsigned int i = 0; i < num_modi; i++ ) {
const char *name = mode_get_name ( modi[i] );
fprintf ( stderr, "\t* "color_bold "%s"color_reset ": -key-%s <key>\n", name, name );
}
// Cleanup
return G_SOURCE_REMOVE;
}
if ( !quiet ) {
fprintf ( stdout, "Rofi is launched in daemon mode.\n" );
print_global_keybindings ();
}
// done starting deamon.
if ( sncontext != NULL ) {
sn_launchee_context_complete ( sncontext );
}
daemon_mode = TRUE;
uint32_t mask[] = { XCB_EVENT_MASK_KEY_PRESS };
xcb_change_window_attributes ( xcb_connection, xcb_screen->root, XCB_CW_EVENT_MASK, mask );
xcb_flush ( xcb_connection );
} }
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
@ -927,12 +775,8 @@ int main ( int argc, char *argv[] )
rofi_view_workers_initialize (); rofi_view_workers_initialize ();
// Setup signal handling sources. // Setup signal handling sources.
// SIGHup signal.
g_unix_signal_add ( SIGHUP, main_loop_signal_handler_hup, NULL );
// SIGINT // SIGINT
g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL ); g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL );
// SIGUSR1
g_unix_signal_add ( SIGUSR1, main_loop_signal_handler_usr1, NULL );
g_idle_add ( startup, NULL ); g_idle_add ( startup, NULL );

View file

@ -1018,7 +1018,7 @@ static int rofi_view_keyboard_navigation ( RofiViewState *state, xkb_keysym_t ke
{ {
// 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
if ( locate_switcher ( key, modstate ) != -1 || abe_test_action ( CANCEL, modstate, key ) ) { if ( abe_test_action ( CANCEL, modstate, key ) ) {
state->retv = MENU_CANCEL; state->retv = MENU_CANCEL;
state->quit = TRUE; state->quit = TRUE;
return 1; return 1;

View file

@ -345,38 +345,7 @@ void release_keyboard ( Display *display )
{ {
XUngrabKeyboard ( display, CurrentTime ); XUngrabKeyboard ( display, CurrentTime );
} }
// bind a key combination on a root window, compensating for Lock* states
void x11_grab_key ( Display *display, unsigned int modmask, KeySym key )
{
Screen *screen = DefaultScreenOfDisplay ( display );
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
KeyCode keycode = XKeysymToKeycode ( display, key );
// bind to combinations of mod and lock masks, so caps and numlock don't confuse people
XGrabKey ( display, keycode, modmask, root, True, GrabModeAsync, GrabModeAsync );
XGrabKey ( display, keycode, modmask | LockMask, root, True, GrabModeAsync, GrabModeAsync );
if ( NumlockMask ) {
XGrabKey ( display, keycode, modmask | NumlockMask, root, True, GrabModeAsync, GrabModeAsync );
XGrabKey ( display, keycode, modmask | NumlockMask | LockMask, root, True, GrabModeAsync, GrabModeAsync );
}
}
void x11_ungrab_key ( Display *display, unsigned int modmask, KeySym key )
{
Screen *screen = DefaultScreenOfDisplay ( display );
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
KeyCode keycode = XKeysymToKeycode ( display, key );
// unbind to combinations of mod and lock masks, so caps and numlock don't confuse people
XUngrabKey ( display, keycode, modmask, root );
XUngrabKey ( display, keycode, modmask | LockMask, root );
if ( NumlockMask ) {
XUngrabKey ( display, keycode, modmask | NumlockMask, root );
XUngrabKey ( display, keycode, modmask | NumlockMask | LockMask, root );
}
}
/** /**
* @param display The connection to the X server. * @param display The connection to the X server.
* *