From 66bd837c9eb26c4770d38cb5b91479f04d6dfdc3 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Fri, 20 Nov 2015 22:00:37 +0100 Subject: [PATCH] Second cleanup in the fix to #268 --- source/keyb.c | 11 ++--- source/rofi.c | 24 +++++++---- source/textbox.c | 9 +---- source/x11-helper.c | 97 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 101 insertions(+), 40 deletions(-) diff --git a/source/keyb.c b/source/keyb.c index 975e16bd..1288fe75 100644 --- a/source/keyb.c +++ b/source/keyb.c @@ -26,13 +26,8 @@ typedef struct _DefaultBinding char *keybinding; } DefaultBinding; -ActionBindingEntry abe[NUM_ABE]; -// Use this so we can ignore numlock mask. -// TODO: maybe use something smarter here.. -extern unsigned int NumlockMask; -extern unsigned int AltMask; -extern unsigned int SuperRMask; -extern unsigned int SuperLMask; +ActionBindingEntry abe[NUM_ABE]; +extern unsigned int CombinedMask; /** * LIST OF DEFAULT SETTINGS @@ -145,7 +140,7 @@ int abe_test_action ( KeyBindingAction action, unsigned int mask, KeySym key ) if ( kb->keysym == key ) { // Bits 13 and 14 of the modifiers together are the group number, and // should be ignored when looking up key bindings - if ( ( mask & ( AltMask | ControlMask | SuperRMask | SuperLMask ) ) == kb->modmask ) { + if ( ( mask & ( CombinedMask ) ) == kb->modmask ) { return TRUE; } } diff --git a/source/rofi.c b/source/rofi.c index 461d4b13..a26e1ee0 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -578,24 +578,26 @@ static int locate_switcher ( KeySym key, unsigned int modstate ) * * Keyboard navigation through the elements. */ -static void menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned int modstate ) +static int menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned int modstate ) { // pressing one of the global key bindings closes the switcher. This allows fast closing of the // menu if an item is not selected if ( locate_switcher ( key, modstate ) != -1 || abe_test_action ( CANCEL, modstate, key ) ) { state->retv = MENU_CANCEL; state->quit = TRUE; + return 1; } // Up, Ctrl-p or Shift-Tab else if ( abe_test_action ( ROW_UP, modstate, key ) ) { menu_nav_up ( state ); + return 1; } else if ( abe_test_action ( ROW_TAB, modstate, key ) ) { if ( state->filtered_lines == 1 ) { state->retv = MENU_OK; *( state->selected_line ) = state->line_map[state->selected]; state->quit = 1; - return; + return 1; } // Double tab! @@ -607,28 +609,36 @@ static void menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned in else{ menu_nav_down ( state ); } + return 1; } // Down, Ctrl-n else if ( abe_test_action ( ROW_DOWN, modstate, key ) ) { menu_nav_down ( state ); + return 1; } else if ( abe_test_action ( ROW_LEFT, modstate, key ) ) { menu_nav_left ( state ); + return 1; } else if ( abe_test_action ( ROW_RIGHT, modstate, key ) ) { menu_nav_right ( state ); + return 1; } else if ( abe_test_action ( PAGE_PREV, modstate, key ) ) { menu_nav_page_prev ( state ); + return 1; } else if ( abe_test_action ( PAGE_NEXT, modstate, key ) ) { menu_nav_page_next ( state ); + return 1; } else if ( abe_test_action ( ROW_FIRST, modstate, key ) ) { menu_nav_first ( state ); + return 1; } else if ( abe_test_action ( ROW_LAST, modstate, key ) ) { menu_nav_last ( state ); + return 1; } else if ( abe_test_action ( ROW_SELECT, modstate, key ) ) { // If a valid item is selected, return that.. @@ -638,8 +648,10 @@ static void menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned in state->update = TRUE; state->refilter = TRUE; } + return 1; } state->prev_key = key; + return 0; } /** @@ -1533,6 +1545,9 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select break; } } + if ( menu_keyboard_navigation ( &state, key, ev.xkey.state ) ) { + continue; + } } { // Skip if we detected key before. @@ -1574,11 +1589,6 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select // redraw. state.update = TRUE; } - // Other keys. - else{ - // unhandled key - menu_keyboard_navigation ( &state, key, ev.xkey.state ); - } } } while ( XCheckTypedEvent ( display, KeyPress, &ev ) ); } diff --git a/source/textbox.c b/source/textbox.c index 81a0b3ca..94ddc0a7 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -42,13 +42,6 @@ #define SIDE_MARGIN 1 -// Use this so we can ignore numlock mask. -// TODO: maybe use something smarter here.. -extern unsigned int NumlockMask; -extern unsigned int AltMask; -extern unsigned int SuperRMask; -extern unsigned int SuperLMask; - /** * Font + font color cache. * Avoid re-loading font on every change on every textbox. @@ -571,7 +564,7 @@ int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, KeySym key, Status st } if ( *pad != 0 && ( stat == XLookupBoth || stat == XLookupChars ) ) { // Filter When alt/ctrl is pressed do not accept the character. - if ( !g_ascii_iscntrl ( *pad ) && 0 == ( ev->xkey.state & ( ControlMask | AltMask | SuperRMask | SuperLMask ) ) ) { + if ( !g_ascii_iscntrl ( *pad ) ) { textbox_insert ( tb, tb->cursor, pad ); textbox_cursor_inc ( tb ); return 1; diff --git a/source/x11-helper.c b/source/x11-helper.c index 1edbcc4e..0fa40471 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -57,10 +57,16 @@ Atom netatoms[NUM_NETATOMS]; const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; // Mask indicating num-lock. -unsigned int NumlockMask = 0; -unsigned int AltMask = 0; -unsigned int SuperRMask = 0; -unsigned int SuperLMask = 0; +unsigned int NumlockMask = 0; +unsigned int AltMask = 0; +unsigned int AltRMask = 0; +unsigned int SuperRMask = 0; +unsigned int SuperLMask = 0; +unsigned int HyperRMask = 0; +unsigned int HyperLMask = 0; +unsigned int MetaRMask = 0; +unsigned int MetaLMask = 0; +unsigned int CombinedMask = 0; extern Colormap map; @@ -373,24 +379,48 @@ static void x11_figure_out_numlock_mask ( Display *display ) XModifierKeymap *modmap = XGetModifierMapping ( display ); KeyCode kc = XKeysymToKeycode ( display, XK_Num_Lock ); KeyCode kc_altl = XKeysymToKeycode ( display, XK_Alt_L ); + KeyCode kc_altr = XKeysymToKeycode ( display, XK_Alt_R ); KeyCode kc_superr = XKeysymToKeycode ( display, XK_Super_R ); KeyCode kc_superl = XKeysymToKeycode ( display, XK_Super_L ); + KeyCode kc_hyperl = XKeysymToKeycode ( display, XK_Hyper_L ); + KeyCode kc_hyperr = XKeysymToKeycode ( display, XK_Hyper_R ); + KeyCode kc_metal = XKeysymToKeycode ( display, XK_Meta_L ); + KeyCode kc_metar = XKeysymToKeycode ( display, XK_Meta_R ); for ( int i = 0; i < 8; i++ ) { for ( int j = 0; j < ( int ) modmap->max_keypermod; j++ ) { - if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc ) { + if ( kc && modmap->modifiermap[i * modmap->max_keypermod + j] == kc ) { NumlockMask = ( 1 << i ); } - if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_altl ) { + if ( kc_altl && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_altl ) { AltMask |= ( 1 << i ); } - if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_superr ) { + if ( kc_altr && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_altr ) { + AltRMask |= ( 1 << i ); + } + if ( kc_superr && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_superr ) { SuperRMask |= ( 1 << i ); } - if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_superl ) { + if ( kc_superl && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_superl ) { SuperLMask |= ( 1 << i ); } + if ( kc_hyperr && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_hyperr ) { + HyperRMask |= ( 1 << i ); + } + if ( kc_hyperl && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_hyperl ) { + HyperLMask |= ( 1 << i ); + } + if ( kc_metar && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_metar ) { + MetaRMask |= ( 1 << i ); + } + if ( kc_metal && modmap->modifiermap[i * modmap->max_keypermod + j] == kc_metal ) { + MetaLMask |= ( 1 << i ); + } } } + // Combined mask, without NumLock + CombinedMask = ShiftMask | MetaLMask | MetaRMask | AltMask | AltRMask | SuperRMask | SuperLMask | HyperLMask | HyperRMask | + ControlMask; + CombinedMask |= Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask; XFreeModifiermap ( modmap ); } @@ -402,36 +432,69 @@ void x11_parse_key ( char *combo, unsigned int *mod, KeySym *key ) if ( strcasestr ( combo, "shift" ) ) { modmask |= ShiftMask; } - if ( strcasestr ( combo, "control" ) ) { modmask |= ControlMask; } - - if ( strcasestr ( combo, "mod1" ) ) { - modmask |= Mod1Mask; - } - if ( strcasestr ( combo, "alt" ) ) { modmask |= AltMask; + if ( AltMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an Alt key.\n" ); + } + } + if ( strcasestr ( combo, "altgr" ) ) { + modmask |= AltRMask; + if ( AltRMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an AltGR key.\n" ); + } } if ( strcasestr ( combo, "superr" ) ) { modmask |= SuperRMask; + if ( SuperRMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an SuperR key.\n" ); + } } if ( strcasestr ( combo, "superl" ) ) { modmask |= SuperLMask; + if ( SuperLMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an SuperL key.\n" ); + } + } + if ( strcasestr ( combo, "metal" ) ) { + modmask |= MetaLMask; + if ( MetaLMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an MetaL key.\n" ); + } + } + if ( strcasestr ( combo, "metar" ) ) { + modmask |= MetaRMask; + if ( MetaRMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an MetaR key.\n" ); + } + } + if ( strcasestr ( combo, "hyperl" ) ) { + modmask |= HyperLMask; + if ( HyperLMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an HyperL key.\n" ); + } + } + if ( strcasestr ( combo, "hyperr" ) ) { + modmask |= HyperRMask; + if ( HyperRMask == 0 ) { + fprintf ( stderr, "X11 Did not report having an HyperR key.\n" ); + } + } + if ( strcasestr ( combo, "mod1" ) ) { + modmask |= Mod1Mask; } if ( strcasestr ( combo, "mod2" ) ) { modmask |= Mod2Mask; } - if ( strcasestr ( combo, "mod3" ) ) { modmask |= Mod3Mask; } - if ( strcasestr ( combo, "mod4" ) ) { modmask |= Mod4Mask; } - if ( strcasestr ( combo, "mod5" ) ) { modmask |= Mod5Mask; }