Translate properly a KeyCode to a KeySym and a string (XKB support
missing ATM).
This commit is contained in:
parent
64edc7c767
commit
ed00d300ab
121
awesome-menu.c
121
awesome-menu.c
|
@ -103,6 +103,10 @@ typedef struct
|
||||||
xcb_connection_t *connection;
|
xcb_connection_t *connection;
|
||||||
/** Default screen number */
|
/** Default screen number */
|
||||||
int default_screen;
|
int default_screen;
|
||||||
|
/** Is the caps lock enabled? */
|
||||||
|
bool caps_lock;
|
||||||
|
/** Is the shift lock enabled? */
|
||||||
|
bool shift_lock;
|
||||||
/** The window */
|
/** The window */
|
||||||
SimpleWindow *sw;
|
SimpleWindow *sw;
|
||||||
/** The draw contet */
|
/** The draw contet */
|
||||||
|
@ -501,6 +505,95 @@ redraw(void)
|
||||||
xcb_aux_sync(globalconf.connection);
|
xcb_aux_sync(globalconf.connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** XCB equivalent of XLookupString which translate the keycode given
|
||||||
|
* by PressEvent to a KeySym and a string
|
||||||
|
* \todo use XKB!
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
x_lookup_string(xcb_key_press_event_t *e, char **buf, size_t *buf_len, xcb_keysym_t *ksym)
|
||||||
|
{
|
||||||
|
xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(globalconf.connection);
|
||||||
|
xcb_keysym_t k0, k1;
|
||||||
|
|
||||||
|
/* 'col' (third parameter) is used to get the proper KeySym
|
||||||
|
* according to modifier (XCB doesn't provide an equivalent to
|
||||||
|
* XLookupString()) */
|
||||||
|
k0 = xcb_key_press_lookup_keysym(keysyms, e, 0);
|
||||||
|
k1 = xcb_key_press_lookup_keysym(keysyms, e, 1);
|
||||||
|
|
||||||
|
xcb_key_symbols_free(keysyms);
|
||||||
|
|
||||||
|
if(xcb_is_modifier_key(k0) && !k1)
|
||||||
|
{
|
||||||
|
/* The Caps_Lock is now enabled */
|
||||||
|
if(k0 == XK_Caps_Lock)
|
||||||
|
globalconf.caps_lock = true;
|
||||||
|
|
||||||
|
/* The Shift lock is now enabled */
|
||||||
|
if(k0 == XK_Shift_Lock)
|
||||||
|
globalconf.shift_lock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The numlock modifier is on and the second KeySym is a keypad
|
||||||
|
* KeySym */
|
||||||
|
if((e->state & globalconf.numlockmask) && xcb_is_keypad_key(k1))
|
||||||
|
{
|
||||||
|
/* The Shift modifier is on, or if the Lock modifier is on and
|
||||||
|
* is interpreted as ShiftLock, use the first KeySym */
|
||||||
|
if((e->state & XCB_MOD_MASK_SHIFT) ||
|
||||||
|
(e->state & XCB_MOD_MASK_LOCK && globalconf.shift_lock))
|
||||||
|
*ksym = k0;
|
||||||
|
else
|
||||||
|
*ksym = k1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Shift and Lock modifers are both off, use the first
|
||||||
|
* KeySym */
|
||||||
|
else if(!(e->state & XCB_MOD_MASK_SHIFT) && !(e->state & XCB_MOD_MASK_LOCK))
|
||||||
|
*ksym = k0;
|
||||||
|
|
||||||
|
/* The Shift modifier is off and the Lock modifier is on and is
|
||||||
|
* interpreted as CapsLock */
|
||||||
|
else if(!(e->state & XCB_MOD_MASK_SHIFT) &&
|
||||||
|
(e->state & XCB_MOD_MASK_LOCK && globalconf.caps_lock))
|
||||||
|
/* TODO: The first Keysym is used but if that KeySym is
|
||||||
|
* lowercase alphabetic, then the corresponding uppercase
|
||||||
|
* KeySym is used instead */
|
||||||
|
*ksym = k0;
|
||||||
|
|
||||||
|
/* The Shift modifier is on, and the Lock modifier is on and is
|
||||||
|
* interpreted as CapsLock */
|
||||||
|
else if((e->state & XCB_MOD_MASK_SHIFT) &&
|
||||||
|
(e->state & XCB_MOD_MASK_LOCK && globalconf.caps_lock))
|
||||||
|
/* TODO: The second Keysym is used but if that KeySym is
|
||||||
|
* lowercase alphabetic, then the corresponding uppercase
|
||||||
|
* KeySym is used instead */
|
||||||
|
*ksym = k1;
|
||||||
|
|
||||||
|
/* The Shift modifer is on, or the Lock modifier is on and is
|
||||||
|
* interpreted as ShiftLock, or both */
|
||||||
|
else if((e->state & XCB_MOD_MASK_SHIFT) ||
|
||||||
|
(e->state & XCB_MOD_MASK_LOCK && globalconf.shift_lock))
|
||||||
|
*ksym = k1;
|
||||||
|
|
||||||
|
if(xcb_is_modifier_key(*ksym) || xcb_is_function_key(*ksym) ||
|
||||||
|
xcb_is_pf_key(*ksym) || xcb_is_cursor_key(*ksym) ||
|
||||||
|
xcb_is_misc_function_key(*ksym))
|
||||||
|
{
|
||||||
|
*buf_len = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Latin1 keysym */
|
||||||
|
if(*ksym < 0x80)
|
||||||
|
asprintf(buf, "%c", (char) *ksym);
|
||||||
|
else
|
||||||
|
/* TODO: remove this call in favor of XCB */
|
||||||
|
*buf = a_strdup(XKeysymToString(*ksym));
|
||||||
|
|
||||||
|
*buf_len = a_strlen(*buf);
|
||||||
|
}
|
||||||
|
|
||||||
/** Handle keypress event in awesome-menu.
|
/** Handle keypress event in awesome-menu.
|
||||||
* \param e received XKeyEvent
|
* \param e received XKeyEvent
|
||||||
*/
|
*/
|
||||||
|
@ -508,23 +601,22 @@ static void
|
||||||
handle_kpress(xcb_key_press_event_t *e)
|
handle_kpress(xcb_key_press_event_t *e)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(globalconf.connection);
|
|
||||||
xcb_keysym_t ksym;
|
xcb_keysym_t ksym;
|
||||||
int num;
|
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
size_t text_dst_len;
|
size_t text_dst_len, num;
|
||||||
|
|
||||||
len = a_strlen(globalconf.text);
|
len = a_strlen(globalconf.text);
|
||||||
/* TODO: check whether 'col' (last parameter) is correct */
|
|
||||||
ksym = xcb_key_press_lookup_keysym(keysyms, e, 1);
|
|
||||||
|
|
||||||
/* TODO: remove this call in favor of XCB */
|
x_lookup_string(e, &buf, &num, &ksym);
|
||||||
buf = XKeysymToString(ksym);
|
/* Got a special key, see x_lookup_string() */
|
||||||
num = strlen(buf);
|
if(!num)
|
||||||
|
return;
|
||||||
|
|
||||||
if(e->state & XCB_MOD_MASK_CONTROL)
|
if(e->state & XCB_MOD_MASK_CONTROL)
|
||||||
switch(ksym)
|
switch(ksym)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
p_delete(&buf);
|
||||||
return;
|
return;
|
||||||
case XK_bracketleft:
|
case XK_bracketleft:
|
||||||
ksym = XK_Escape;
|
ksym = XK_Escape;
|
||||||
|
@ -558,12 +650,14 @@ handle_kpress(xcb_key_press_event_t *e)
|
||||||
compute_match(get_last_word(globalconf.text));
|
compute_match(get_last_word(globalconf.text));
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
p_delete(&buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(CLEANMASK(e->state) & XCB_MOD_MASK_1)
|
else if(CLEANMASK(e->state) & XCB_MOD_MASK_1)
|
||||||
switch(ksym)
|
switch(ksym)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
p_delete(&buf);
|
||||||
return;
|
return;
|
||||||
case XK_h:
|
case XK_h:
|
||||||
ksym = XK_Left;
|
ksym = XK_Left;
|
||||||
|
@ -582,8 +676,6 @@ handle_kpress(xcb_key_press_event_t *e)
|
||||||
{
|
{
|
||||||
if(buf[0] != '/' || globalconf.text[len - 1] != '/')
|
if(buf[0] != '/' || globalconf.text[len - 1] != '/')
|
||||||
{
|
{
|
||||||
buf[num] = '\0';
|
|
||||||
|
|
||||||
/* Reallocate text string if needed to hold
|
/* Reallocate text string if needed to hold
|
||||||
* concatenation of text and buf */
|
* concatenation of text and buf */
|
||||||
if((text_dst_len = (a_strlen(globalconf.text) + num - 1)) > globalconf.text_size)
|
if((text_dst_len = (a_strlen(globalconf.text) + num - 1)) > globalconf.text_size)
|
||||||
|
@ -596,6 +688,8 @@ handle_kpress(xcb_key_press_event_t *e)
|
||||||
compute_match(get_last_word(globalconf.text));
|
compute_match(get_last_word(globalconf.text));
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_delete(&buf);
|
||||||
break;
|
break;
|
||||||
case XK_BackSpace:
|
case XK_BackSpace:
|
||||||
if(len)
|
if(len)
|
||||||
|
@ -622,6 +716,8 @@ handle_kpress(xcb_key_press_event_t *e)
|
||||||
status = STOP;
|
status = STOP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_delete(&buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_GETLINE
|
#ifndef HAVE_GETLINE
|
||||||
|
@ -835,6 +931,11 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
|
||||||
|
/* TODO: do we need to check at startup that the Caps_Lock and
|
||||||
|
* Shift_Lock keys are pressed? */
|
||||||
|
globalconf.caps_lock = false;
|
||||||
|
globalconf.shift_lock = false;
|
||||||
|
|
||||||
xutil_map_raised(globalconf.connection, globalconf.sw->window);
|
xutil_map_raised(globalconf.connection, globalconf.sw->window);
|
||||||
|
|
||||||
while(status == RUN)
|
while(status == RUN)
|
||||||
|
|
Loading…
Reference in New Issue