efl - ecore c+ ecore-imf - fix odd case input when faking a real event

so ibus module for ecore-imf likes to send an x event back to
ourselves faking a key... this works unless we are looking at
modifiers that make make for odd combos with keysyms turned into
keycodes. so actualyl use the correct original keycode plus state
unless we are having to explicitly send a keysym from ibus core.

this fixes T3703

@fix
This commit is contained in:
Carsten Haitzler 2016-05-27 23:55:24 +09:00
parent 20f418b8d7
commit 072674dbe2
2 changed files with 32 additions and 15 deletions

View File

@ -347,14 +347,15 @@ _ecore_key_press(int event,
char *key; char *key;
char keyname_buffer[256]; char keyname_buffer[256];
char compose_buffer[256]; char compose_buffer[256];
KeySym sym; KeySym sym, sym2 = 0;
XComposeStatus status; XComposeStatus status;
int val; int val;
int key_len, keyname_len, compose_len; int key_len, keyname_len, compose_len;
_ecore_x_last_event_mouse_move = 0; _ecore_x_last_event_mouse_move = 0;
keyname = XKeysymToString(_ecore_x_XKeycodeToKeysym(xevent->display, sym = _ecore_x_XKeycodeToKeysym(xevent->display, xevent->keycode, 0);
xevent->keycode, 0)); keyname = XKeysymToString(sym);
if (!keyname) if (!keyname)
{ {
snprintf(keyname_buffer, snprintf(keyname_buffer,
@ -364,13 +365,12 @@ _ecore_key_press(int event,
keyname = keyname_buffer; keyname = keyname_buffer;
} }
sym = 0;
key = NULL; key = NULL;
compose = NULL; compose = NULL;
val = XLookupString(xevent, val = XLookupString(xevent,
compose_buffer, compose_buffer,
sizeof(compose_buffer), sizeof(compose_buffer),
&sym, &sym2,
&status); &status);
if (val > 0) if (val > 0)
{ {
@ -381,6 +381,7 @@ _ecore_key_press(int event,
ERR("Ecore_X cannot convert input key string '%s' to UTF-8. " ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
"Is Eina built with iconv support?", compose_buffer); "Is Eina built with iconv support?", compose_buffer);
tmp = compose; tmp = compose;
sym = sym2;
} }
key = XKeysymToString(sym); key = XKeysymToString(sym);

View File

@ -48,6 +48,7 @@ typedef struct _KeyEvent KeyEvent;
struct _KeyEvent struct _KeyEvent
{ {
int keysym; int keysym;
int keycode;
int state; int state;
}; };
@ -64,6 +65,7 @@ static void _ecore_imf_context_ibus_bus_connected_cb(IBusBus *bus, IBusIMContext
static XKeyEvent _ecore_imf_ibus_x_key_event_generate(Window win, static XKeyEvent _ecore_imf_ibus_x_key_event_generate(Window win,
Eina_Bool press, Eina_Bool press,
int keysym, int keysym,
int keycode,
int modifiers); int modifiers);
static unsigned int static unsigned int
@ -163,7 +165,7 @@ _ecore_imf_locks_to_ibus_modifier(unsigned int locks)
} }
static void static void
_ecore_imf_ibus_key_event_put(int keysym, int state) _ecore_imf_ibus_key_event_put(int keysym, int keycode, int state)
{ {
// Find the window which has the current keyboard focus. // Find the window which has the current keyboard focus.
Window winFocus = 0; Window winFocus = 0;
@ -177,6 +179,7 @@ _ecore_imf_ibus_key_event_put(int keysym, int state)
event = _ecore_imf_ibus_x_key_event_generate(winFocus, event = _ecore_imf_ibus_x_key_event_generate(winFocus,
EINA_FALSE, EINA_FALSE,
keysym, keysym,
keycode,
state); state);
XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event);
} }
@ -185,16 +188,18 @@ _ecore_imf_ibus_key_event_put(int keysym, int state)
event = _ecore_imf_ibus_x_key_event_generate(winFocus, event = _ecore_imf_ibus_x_key_event_generate(winFocus,
EINA_TRUE, EINA_TRUE,
keysym, keysym,
keycode,
state); state);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
} }
} }
static KeyEvent * static KeyEvent *
_ecore_imf_ibus_key_event_copy(int keysym, int state) _ecore_imf_ibus_key_event_copy(int keysym, int keycode, int state)
{ {
KeyEvent *kev = calloc(1, sizeof(KeyEvent)); KeyEvent *kev = calloc(1, sizeof(KeyEvent));
kev->keysym = keysym; kev->keysym = keysym;
kev->keycode = keycode;
kev->state = state; kev->state = state;
return kev; return kev;
@ -221,7 +226,9 @@ _ecore_imf_ibus_process_key_event_done(GObject *object,
if (retval == EINA_FALSE) if (retval == EINA_FALSE)
{ {
_ecore_imf_ibus_key_event_put(event->keysym, event->state); _ecore_imf_ibus_key_event_put(event->keysym,
event->keycode,
event->state);
} }
free(event); free(event);
} }
@ -394,7 +401,7 @@ ecore_imf_context_ibus_filter_event(Ecore_IMF_Context *ctx,
if (ev->timestamp == 0) if (ev->timestamp == 0)
return EINA_FALSE; return EINA_FALSE;
keycode = ecore_x_keysym_keycode_get(ev->key); keycode = ecore_x_keysym_keycode_get(ev->keyname);
keysym = XStringToKeysym(ev->key); keysym = XStringToKeysym(ev->key);
state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) | state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) |
_ecore_imf_locks_to_ibus_modifier(ev->locks) | IBUS_RELEASE_MASK; _ecore_imf_locks_to_ibus_modifier(ev->locks) | IBUS_RELEASE_MASK;
@ -415,7 +422,7 @@ ecore_imf_context_ibus_filter_event(Ecore_IMF_Context *ctx,
-1, -1,
NULL, NULL,
_ecore_imf_ibus_process_key_event_done, _ecore_imf_ibus_process_key_event_done,
_ecore_imf_ibus_key_event_copy(keysym, state)); _ecore_imf_ibus_key_event_copy(keysym, keycode, state));
retval = EINA_TRUE; retval = EINA_TRUE;
} }
} }
@ -427,7 +434,7 @@ ecore_imf_context_ibus_filter_event(Ecore_IMF_Context *ctx,
_request_surrounding_text(ibusimcontext); _request_surrounding_text(ibusimcontext);
keycode = ecore_x_keysym_keycode_get(ev->key); keycode = ecore_x_keysym_keycode_get(ev->keyname);
keysym = XStringToKeysym(ev->key); keysym = XStringToKeysym(ev->key);
state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) | state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) |
_ecore_imf_locks_to_ibus_modifier(ev->locks); _ecore_imf_locks_to_ibus_modifier(ev->locks);
@ -448,7 +455,7 @@ ecore_imf_context_ibus_filter_event(Ecore_IMF_Context *ctx,
-1, -1,
NULL, NULL,
_ecore_imf_ibus_process_key_event_done, _ecore_imf_ibus_process_key_event_done,
_ecore_imf_ibus_key_event_copy(keysym, state)); _ecore_imf_ibus_key_event_copy(keysym, keycode, state));
retval = EINA_TRUE; retval = EINA_TRUE;
} }
} }
@ -716,6 +723,7 @@ _ecore_imf_context_ibus_commit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED
static XKeyEvent _ecore_imf_ibus_x_key_event_generate(Window win, static XKeyEvent _ecore_imf_ibus_x_key_event_generate(Window win,
Eina_Bool press, Eina_Bool press,
int keysym, int keysym,
int keycode,
int modifiers) int modifiers)
{ {
XKeyEvent event; XKeyEvent event;
@ -731,8 +739,16 @@ static XKeyEvent _ecore_imf_ibus_x_key_event_generate(Window win,
event.x_root = 1; event.x_root = 1;
event.y_root = 1; event.y_root = 1;
event.same_screen = EINA_TRUE; event.same_screen = EINA_TRUE;
event.state = modifiers; if (keycode == -1)
event.keycode = XKeysymToKeycode(display, keysym); {
event.keycode = XKeysymToKeycode(display, keysym);
event.state = 0;
}
else
{
event.keycode = keycode;
event.state = modifiers;
}
if (press) if (press)
event.type = KeyPress; event.type = KeyPress;
else else
@ -751,7 +767,7 @@ _ecore_imf_context_ibus_forward_key_event_cb(IBusInputContext *ibuscontext EINA
{ {
EINA_LOG_DBG("keyval : %d, state : %d", keyval, state); EINA_LOG_DBG("keyval : %d, state : %d", keyval, state);
_ecore_imf_ibus_key_event_put(keyval, state); _ecore_imf_ibus_key_event_put(keyval, -1, state);
} }
static void static void