mirror of
https://github.com/lbonn/rofi
synced 2024-11-15 08:37:17 +00:00
Hopefully fix for #268
This commit is contained in:
parent
1bd231bc3d
commit
266ee5efb7
5 changed files with 156 additions and 137 deletions
|
@ -100,7 +100,7 @@ void textbox_draw ( textbox *tb, cairo_t *draw );
|
|||
*
|
||||
* @returns if the key was handled (1), unhandled(0) or handled and return was pressed (-1)
|
||||
*/
|
||||
int textbox_keypress ( textbox *tb, XIC xic, XEvent *ev );
|
||||
int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, KeySym key, Status stat );
|
||||
|
||||
/**
|
||||
* @param tb Handle to the textbox
|
||||
|
|
|
@ -30,6 +30,9 @@ 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;
|
||||
|
||||
/**
|
||||
* LIST OF DEFAULT SETTINGS
|
||||
|
@ -142,7 +145,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 & ~( LockMask | NumlockMask | ( 1 << 13 ) | ( 1 << 14 ) ) ) == kb->modmask ) {
|
||||
if ( ( mask & ( AltMask | ControlMask | SuperRMask | SuperLMask ) ) == kb->modmask ) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1468,52 +1468,61 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
|||
// Key press event.
|
||||
else if ( ev.type == KeyPress ) {
|
||||
do {
|
||||
KeySym key = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 );
|
||||
// This is needed for letting the Input Method handle combined keys.
|
||||
// E.g. `e into è
|
||||
if ( XFilterEvent ( &ev, main_window ) ) {
|
||||
continue;
|
||||
}
|
||||
Status stat;
|
||||
char pad[32];
|
||||
KeySym key;// = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 );
|
||||
int len = Xutf8LookupString ( xic, &( ev.xkey ), pad, sizeof ( pad ), &key, &stat );
|
||||
pad[len] = 0;
|
||||
|
||||
// Handling of paste
|
||||
if ( abe_test_action ( PASTE_PRIMARY, ev.xkey.state, key ) ) {
|
||||
XConvertSelection ( display, XA_PRIMARY, netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window, CurrentTime );
|
||||
}
|
||||
else if ( abe_test_action ( PASTE_SECONDARY, ev.xkey.state, key ) ) {
|
||||
XConvertSelection ( display, netatoms[CLIPBOARD], netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window,
|
||||
CurrentTime );
|
||||
}
|
||||
else if ( abe_test_action ( MODE_PREVIOUS, ev.xkey.state, key ) ) {
|
||||
state.retv = MENU_PREVIOUS;
|
||||
*( state.selected_line ) = 0;
|
||||
state.quit = TRUE;
|
||||
break;
|
||||
}
|
||||
// Menu navigation.
|
||||
else if ( abe_test_action ( MODE_NEXT, ev.xkey.state, key ) ) {
|
||||
state.retv = MENU_NEXT;
|
||||
*( state.selected_line ) = 0;
|
||||
state.quit = TRUE;
|
||||
break;
|
||||
}
|
||||
// Toggle case sensitivity.
|
||||
else if ( abe_test_action ( TOGGLE_CASE_SENSITIVITY, ev.xkey.state, key ) ) {
|
||||
config.case_sensitive = !config.case_sensitive;
|
||||
*( state.selected_line ) = 0;
|
||||
state.refilter = TRUE;
|
||||
state.update = TRUE;
|
||||
if ( config.case_sensitive ) {
|
||||
textbox_text ( state.case_indicator, "*" );
|
||||
if ( stat == XLookupKeySym || stat == XLookupBoth ) {
|
||||
// Handling of paste
|
||||
if ( abe_test_action ( PASTE_PRIMARY, ev.xkey.state, key ) ) {
|
||||
XConvertSelection ( display, XA_PRIMARY, netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window, CurrentTime );
|
||||
}
|
||||
else {
|
||||
textbox_text ( state.case_indicator, " " );
|
||||
else if ( abe_test_action ( PASTE_SECONDARY, ev.xkey.state, key ) ) {
|
||||
XConvertSelection ( display, netatoms[CLIPBOARD], netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window,
|
||||
CurrentTime );
|
||||
}
|
||||
}
|
||||
// Special delete entry command.
|
||||
else if ( abe_test_action ( DELETE_ENTRY, ev.xkey.state, key ) ) {
|
||||
if ( state.selected < state.filtered_lines ) {
|
||||
*( state.selected_line ) = state.line_map[state.selected];
|
||||
state.retv = MENU_ENTRY_DELETE;
|
||||
else if ( abe_test_action ( MODE_PREVIOUS, ev.xkey.state, key ) ) {
|
||||
state.retv = MENU_PREVIOUS;
|
||||
*( state.selected_line ) = 0;
|
||||
state.quit = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Menu navigation.
|
||||
else if ( abe_test_action ( MODE_NEXT, ev.xkey.state, key ) ) {
|
||||
state.retv = MENU_NEXT;
|
||||
*( state.selected_line ) = 0;
|
||||
state.quit = TRUE;
|
||||
break;
|
||||
}
|
||||
// Toggle case sensitivity.
|
||||
else if ( abe_test_action ( TOGGLE_CASE_SENSITIVITY, ev.xkey.state, key ) ) {
|
||||
config.case_sensitive = !config.case_sensitive;
|
||||
*( state.selected_line ) = 0;
|
||||
state.refilter = TRUE;
|
||||
state.update = TRUE;
|
||||
if ( config.case_sensitive ) {
|
||||
textbox_text ( state.case_indicator, "*" );
|
||||
}
|
||||
else {
|
||||
textbox_text ( state.case_indicator, " " );
|
||||
}
|
||||
}
|
||||
// Special delete entry command.
|
||||
else if ( abe_test_action ( DELETE_ENTRY, ev.xkey.state, key ) ) {
|
||||
if ( state.selected < state.filtered_lines ) {
|
||||
*( state.selected_line ) = state.line_map[state.selected];
|
||||
state.retv = MENU_ENTRY_DELETE;
|
||||
state.quit = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for ( unsigned int a = CUSTOM_1; a <= CUSTOM_19; a++ ) {
|
||||
if ( abe_test_action ( a, ev.xkey.state, key ) ) {
|
||||
if ( state.selected < state.filtered_lines ) {
|
||||
|
@ -1524,17 +1533,14 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
// Skip if we detected key before.
|
||||
if ( state.quit ) {
|
||||
continue;
|
||||
}
|
||||
// This is needed for letting the Input Method handle combined keys.
|
||||
// E.g. `e into è
|
||||
if ( XFilterEvent ( &ev, main_window ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int rc = textbox_keypress ( state.text, xic, &ev );
|
||||
int rc = textbox_keypress ( state.text, &ev, pad, key, stat );
|
||||
// Row is accepted.
|
||||
if ( rc < 0 ) {
|
||||
shift = ( ( ev.xkey.state & ShiftMask ) == ShiftMask );
|
||||
|
|
154
source/textbox.c
154
source/textbox.c
|
@ -45,7 +45,9 @@
|
|||
// Use this so we can ignore numlock mask.
|
||||
// TODO: maybe use something smarter here..
|
||||
extern unsigned int NumlockMask;
|
||||
extern unsigned int ModeSwitchMask;
|
||||
extern unsigned int AltMask;
|
||||
extern unsigned int SuperRMask;
|
||||
extern unsigned int SuperLMask;
|
||||
|
||||
/**
|
||||
* Font + font color cache.
|
||||
|
@ -496,90 +498,84 @@ static void textbox_cursor_del_word ( textbox *tb )
|
|||
// 0 = unhandled
|
||||
// 1 = handled
|
||||
// -1 = handled and return pressed (finished)
|
||||
int textbox_keypress ( textbox *tb, XIC xic, XEvent *ev )
|
||||
int textbox_keypress ( textbox *tb, XEvent *ev, char *pad, KeySym key, Status stat )
|
||||
{
|
||||
KeySym key;
|
||||
Status stat;
|
||||
char pad[32];
|
||||
int len;
|
||||
|
||||
if ( !( tb->flags & TB_EDITABLE ) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( stat == XLookupKeySym || stat == XLookupBoth ) {
|
||||
// Left or Ctrl-b
|
||||
if ( abe_test_action ( MOVE_CHAR_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_dec ( tb );
|
||||
return 2;
|
||||
}
|
||||
// Right or Ctrl-F
|
||||
else if ( abe_test_action ( MOVE_CHAR_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_inc ( tb );
|
||||
return 2;
|
||||
}
|
||||
|
||||
len = Xutf8LookupString ( xic, &ev->xkey, pad, sizeof ( pad ), &key, &stat );
|
||||
pad[len] = 0;
|
||||
// Left or Ctrl-b
|
||||
if ( abe_test_action ( MOVE_CHAR_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_dec ( tb );
|
||||
return 2;
|
||||
// Ctrl-U: Kill from the beginning to the end of the line.
|
||||
else if ( abe_test_action ( CLEAR_LINE, ev->xkey.state, key ) ) {
|
||||
textbox_text ( tb, "" );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-A
|
||||
else if ( abe_test_action ( MOVE_FRONT, ev->xkey.state, key ) ) {
|
||||
textbox_cursor ( tb, 0 );
|
||||
return 2;
|
||||
}
|
||||
// Ctrl-E
|
||||
else if ( abe_test_action ( MOVE_END, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_end ( tb );
|
||||
return 2;
|
||||
}
|
||||
// Ctrl-Alt-h
|
||||
else if ( abe_test_action ( REMOVE_WORD_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_bkspc_word ( tb );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-Alt-d
|
||||
else if ( abe_test_action ( REMOVE_WORD_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_del_word ( tb );
|
||||
return 1;
|
||||
} // Delete or Ctrl-D
|
||||
else if ( abe_test_action ( REMOVE_CHAR_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_del ( tb );
|
||||
return 1;
|
||||
}
|
||||
// Alt-B
|
||||
else if ( abe_test_action ( MOVE_WORD_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_dec_word ( tb );
|
||||
return 2;
|
||||
}
|
||||
// Alt-F
|
||||
else if ( abe_test_action ( MOVE_WORD_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_inc_word ( tb );
|
||||
return 2;
|
||||
}
|
||||
// BackSpace, Ctrl-h
|
||||
else if ( abe_test_action ( REMOVE_CHAR_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_bkspc ( tb );
|
||||
return 1;
|
||||
}
|
||||
else if ( abe_test_action ( ACCEPT_CUSTOM, ev->xkey.state, key ) ) {
|
||||
return -2;
|
||||
}
|
||||
else if ( abe_test_action ( ACCEPT_ENTRY_CONTINUE, ev->xkey.state, key ) ) {
|
||||
return -3;
|
||||
}
|
||||
else if ( abe_test_action ( ACCEPT_ENTRY, ev->xkey.state, key ) ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Right or Ctrl-F
|
||||
else if ( abe_test_action ( MOVE_CHAR_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_inc ( tb );
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Ctrl-U: Kill from the beginning to the end of the line.
|
||||
else if ( abe_test_action ( CLEAR_LINE, ev->xkey.state, key ) ) {
|
||||
textbox_text ( tb, "" );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-A
|
||||
else if ( abe_test_action ( MOVE_FRONT, ev->xkey.state, key ) ) {
|
||||
textbox_cursor ( tb, 0 );
|
||||
return 2;
|
||||
}
|
||||
// Ctrl-E
|
||||
else if ( abe_test_action ( MOVE_END, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_end ( tb );
|
||||
return 2;
|
||||
}
|
||||
// Ctrl-Alt-h
|
||||
else if ( abe_test_action ( REMOVE_WORD_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_bkspc_word ( tb );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-Alt-d
|
||||
else if ( abe_test_action ( REMOVE_WORD_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_del_word ( tb );
|
||||
return 1;
|
||||
} // Delete or Ctrl-D
|
||||
else if ( abe_test_action ( REMOVE_CHAR_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_del ( tb );
|
||||
return 1;
|
||||
}
|
||||
// Alt-B
|
||||
else if ( abe_test_action ( MOVE_WORD_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_dec_word ( tb );
|
||||
return 2;
|
||||
}
|
||||
// Alt-F
|
||||
else if ( abe_test_action ( MOVE_WORD_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_inc_word ( tb );
|
||||
return 2;
|
||||
}
|
||||
// BackSpace, Ctrl-h
|
||||
else if ( abe_test_action ( REMOVE_CHAR_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_bkspc ( tb );
|
||||
return 1;
|
||||
}
|
||||
else if ( abe_test_action ( ACCEPT_CUSTOM, ev->xkey.state, key ) ) {
|
||||
return -2;
|
||||
}
|
||||
else if ( abe_test_action ( ACCEPT_ENTRY_CONTINUE, ev->xkey.state, key ) ) {
|
||||
return -3;
|
||||
}
|
||||
else if ( abe_test_action ( ACCEPT_ENTRY, ev->xkey.state, key ) ) {
|
||||
return -1;
|
||||
}
|
||||
// Filter When alt/ctrl/etc is pressed do not accept the character.
|
||||
// Ignore others (numlock, shift,..).
|
||||
else if ( !iscntrl ( *pad ) && 0 ==
|
||||
( ev->xkey.state & ~( ModeSwitchMask | NumlockMask | ( 1 << 12 ) | ( 1 << 13 ) | ShiftMask | LockMask ) ) ) {
|
||||
textbox_insert ( tb, tb->cursor, pad );
|
||||
textbox_cursor_inc ( tb );
|
||||
return 1;
|
||||
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 ) ) ) {
|
||||
textbox_insert ( tb, tb->cursor, pad );
|
||||
textbox_cursor_inc ( tb );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -57,8 +57,10 @@
|
|||
Atom netatoms[NUM_NETATOMS];
|
||||
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
|
||||
// Mask indicating num-lock.
|
||||
unsigned int NumlockMask = 0;
|
||||
unsigned int ModeSwitchMask = 0;
|
||||
unsigned int NumlockMask = 0;
|
||||
unsigned int AltMask = 0;
|
||||
unsigned int SuperRMask = 0;
|
||||
unsigned int SuperLMask = 0;
|
||||
|
||||
extern Colormap map;
|
||||
|
||||
|
@ -368,16 +370,24 @@ void x11_ungrab_key ( Display *display, unsigned int modmask, KeySym key )
|
|||
*/
|
||||
static void x11_figure_out_numlock_mask ( Display *display )
|
||||
{
|
||||
XModifierKeymap *modmap = XGetModifierMapping ( display );
|
||||
KeyCode kc = XKeysymToKeycode ( display, XK_Num_Lock );
|
||||
KeyCode kc_ms = XKeysymToKeycode ( display, XK_Mode_switch );
|
||||
XModifierKeymap *modmap = XGetModifierMapping ( display );
|
||||
KeyCode kc = XKeysymToKeycode ( display, XK_Num_Lock );
|
||||
KeyCode kc_altl = XKeysymToKeycode ( display, XK_Alt_L );
|
||||
KeyCode kc_superr = XKeysymToKeycode ( display, XK_Super_R );
|
||||
KeyCode kc_superl = XKeysymToKeycode ( display, XK_Super_L );
|
||||
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 ) {
|
||||
NumlockMask = ( 1 << i );
|
||||
}
|
||||
if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_ms ) {
|
||||
ModeSwitchMask = ( 1 << i );
|
||||
if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_altl ) {
|
||||
AltMask |= ( 1 << i );
|
||||
}
|
||||
if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_superr ) {
|
||||
SuperRMask |= ( 1 << i );
|
||||
}
|
||||
if ( modmap->modifiermap[i * modmap->max_keypermod + j] == kc_superl ) {
|
||||
SuperLMask |= ( 1 << i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,9 +412,14 @@ void x11_parse_key ( char *combo, unsigned int *mod, KeySym *key )
|
|||
}
|
||||
|
||||
if ( strcasestr ( combo, "alt" ) ) {
|
||||
modmask |= Mod1Mask;
|
||||
modmask |= AltMask;
|
||||
}
|
||||
if ( strcasestr ( combo, "superr" ) ) {
|
||||
modmask |= SuperRMask;
|
||||
}
|
||||
if ( strcasestr ( combo, "superl" ) ) {
|
||||
modmask |= SuperLMask;
|
||||
}
|
||||
|
||||
if ( strcasestr ( combo, "mod2" ) ) {
|
||||
modmask |= Mod2Mask;
|
||||
}
|
||||
|
@ -436,7 +451,6 @@ void x11_parse_key ( char *combo, unsigned int *mod, KeySym *key )
|
|||
// TODO popup
|
||||
fprintf ( stderr, "sorry, cannot understand key combination: %s\n", combo );
|
||||
}
|
||||
|
||||
*key = sym;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue