Send key release event to input method. (#5281)
Co-authored-by: Ethan Lee <flibitijibibo@gmail.com>main
parent
8bae343f25
commit
138d96c8a6
|
@ -339,11 +339,11 @@ SDL_Fcitx_Reset(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool
|
||||||
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
|
||||||
{
|
{
|
||||||
Uint32 state = Fcitx_ModState();
|
Uint32 mod_state = Fcitx_ModState();
|
||||||
Uint32 handled = SDL_FALSE;
|
Uint32 handled = SDL_FALSE;
|
||||||
Uint32 is_release = SDL_FALSE;
|
Uint32 is_release = (state == SDL_RELEASED);
|
||||||
Uint32 event_time = 0;
|
Uint32 event_time = 0;
|
||||||
|
|
||||||
if (!fcitx_client.ic_path) {
|
if (!fcitx_client.ic_path) {
|
||||||
|
@ -351,7 +351,7 @@ SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
|
if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
|
||||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
|
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
|
||||||
DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
|
DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
|
||||||
if (handled) {
|
if (handled) {
|
||||||
SDL_Fcitx_UpdateTextRect(NULL);
|
SDL_Fcitx_UpdateTextRect(NULL);
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern SDL_bool SDL_Fcitx_Init(void);
|
||||||
extern void SDL_Fcitx_Quit(void);
|
extern void SDL_Fcitx_Quit(void);
|
||||||
extern void SDL_Fcitx_SetFocus(SDL_bool focused);
|
extern void SDL_Fcitx_SetFocus(SDL_bool focused);
|
||||||
extern void SDL_Fcitx_Reset(void);
|
extern void SDL_Fcitx_Reset(void);
|
||||||
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
|
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
|
||||||
extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect);
|
extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect);
|
||||||
extern void SDL_Fcitx_PumpEvents(void);
|
extern void SDL_Fcitx_PumpEvents(void);
|
||||||
|
|
||||||
|
|
|
@ -503,14 +503,18 @@ SDL_IBus_Reset(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool
|
||||||
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
|
||||||
{
|
{
|
||||||
Uint32 result = 0;
|
Uint32 result = 0;
|
||||||
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
||||||
|
|
||||||
|
|
||||||
if (IBus_CheckConnection(dbus)) {
|
if (IBus_CheckConnection(dbus)) {
|
||||||
Uint32 mods = IBus_ModState();
|
Uint32 mods = IBus_ModState();
|
||||||
Uint32 ibus_keycode = keycode - 8;
|
Uint32 ibus_keycode = keycode - 8;
|
||||||
|
if (state == SDL_RELEASED) {
|
||||||
|
mods |= (1 << 30); // IBUS_RELEASE_MASK
|
||||||
|
}
|
||||||
if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
|
if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
|
||||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
|
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
|
||||||
DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) {
|
DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ extern void SDL_IBus_Reset(void);
|
||||||
/* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to
|
/* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to
|
||||||
update its candidate list or change input methods. PumpEvents should be
|
update its candidate list or change input methods. PumpEvents should be
|
||||||
called some time after this, to recieve the TextInput / TextEditing event back. */
|
called some time after this, to recieve the TextInput / TextEditing event back. */
|
||||||
extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
|
extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
|
||||||
|
|
||||||
/* Update the position of IBus' candidate list. If rect is NULL then this will
|
/* Update the position of IBus' candidate list. If rect is NULL then this will
|
||||||
just reposition it relative to the focused window's new position. */
|
just reposition it relative to the focused window's new position. */
|
||||||
|
|
|
@ -27,7 +27,7 @@ typedef SDL_bool (*_SDL_IME_Init)(void);
|
||||||
typedef void (*_SDL_IME_Quit)(void);
|
typedef void (*_SDL_IME_Quit)(void);
|
||||||
typedef void (*_SDL_IME_SetFocus)(SDL_bool);
|
typedef void (*_SDL_IME_SetFocus)(SDL_bool);
|
||||||
typedef void (*_SDL_IME_Reset)(void);
|
typedef void (*_SDL_IME_Reset)(void);
|
||||||
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32);
|
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state);
|
||||||
typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *);
|
typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *);
|
||||||
typedef void (*_SDL_IME_PumpEvents)(void);
|
typedef void (*_SDL_IME_PumpEvents)(void);
|
||||||
|
|
||||||
|
@ -127,10 +127,10 @@ SDL_IME_Reset(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool
|
||||||
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
|
||||||
{
|
{
|
||||||
if (SDL_IME_ProcessKeyEvent_Real)
|
if (SDL_IME_ProcessKeyEvent_Real)
|
||||||
return SDL_IME_ProcessKeyEvent_Real(keysym, keycode);
|
return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state);
|
||||||
|
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern SDL_bool SDL_IME_Init(void);
|
||||||
extern void SDL_IME_Quit(void);
|
extern void SDL_IME_Quit(void);
|
||||||
extern void SDL_IME_SetFocus(SDL_bool focused);
|
extern void SDL_IME_SetFocus(SDL_bool focused);
|
||||||
extern void SDL_IME_Reset(void);
|
extern void SDL_IME_Reset(void);
|
||||||
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
|
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
|
||||||
extern void SDL_IME_UpdateTextRect(SDL_Rect *rect);
|
extern void SDL_IME_UpdateTextRect(SDL_Rect *rect);
|
||||||
extern void SDL_IME_PumpEvents(void);
|
extern void SDL_IME_PumpEvents(void);
|
||||||
|
|
||||||
|
|
|
@ -921,7 +921,7 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, SDL_bool *handled_by_ime)
|
keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, Uint8 state, SDL_bool *handled_by_ime)
|
||||||
{
|
{
|
||||||
SDL_WindowData *window = input->keyboard_focus;
|
SDL_WindowData *window = input->keyboard_focus;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
|
@ -938,12 +938,16 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
|
||||||
sym = syms[0];
|
sym = syms[0];
|
||||||
|
|
||||||
#ifdef SDL_USE_IME
|
#ifdef SDL_USE_IME
|
||||||
if (SDL_IME_ProcessKeyEvent(sym, key + 8)) {
|
if (SDL_IME_ProcessKeyEvent(sym, key + 8, state)) {
|
||||||
*handled_by_ime = SDL_TRUE;
|
*handled_by_ime = SDL_TRUE;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (state == SDL_RELEASED) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) {
|
if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) {
|
||||||
switch(WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) {
|
switch(WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) {
|
||||||
case XKB_COMPOSE_COMPOSING:
|
case XKB_COMPOSE_COMPOSING:
|
||||||
|
@ -977,7 +981,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||||
SDL_bool handled_by_ime = SDL_FALSE;
|
SDL_bool handled_by_ime = SDL_FALSE;
|
||||||
|
|
||||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
has_text = keyboard_input_get_text(text, input, key, &handled_by_ime);
|
has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime);
|
||||||
} else {
|
} else {
|
||||||
if (keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
if (keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
||||||
// Send any due key repeat events before stopping the repeat and generating the key up event
|
// Send any due key repeat events before stopping the repeat and generating the key up event
|
||||||
|
@ -987,6 +991,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||||
keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time);
|
keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time);
|
||||||
keyboard_repeat_clear(&input->keyboard_repeat);
|
keyboard_repeat_clear(&input->keyboard_repeat);
|
||||||
}
|
}
|
||||||
|
keyboard_input_get_text(text, input, key, SDL_RELEASED, &handled_by_ime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handled_by_ime && key < SDL_arraysize(xfree86_scancode_table2)) {
|
if (!handled_by_ime && key < SDL_arraysize(xfree86_scancode_table2)) {
|
||||||
|
|
|
@ -996,8 +996,9 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Key press? */
|
/* Key press/release? */
|
||||||
case KeyPress:{
|
case KeyPress:
|
||||||
|
case KeyRelease: {
|
||||||
KeyCode keycode = xevent->xkey.keycode;
|
KeyCode keycode = xevent->xkey.keycode;
|
||||||
KeySym keysym = NoSymbol;
|
KeySym keysym = NoSymbol;
|
||||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||||
|
@ -1005,7 +1006,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
||||||
SDL_bool handled_by_ime = SDL_FALSE;
|
SDL_bool handled_by_ime = SDL_FALSE;
|
||||||
|
|
||||||
#ifdef DEBUG_XEVENTS
|
#ifdef DEBUG_XEVENTS
|
||||||
printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode);
|
printf("window %p: %s (X11 keycode = 0x%X)\n" data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode);
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
|
if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
|
||||||
|
@ -1021,7 +1022,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
||||||
/* */
|
/* */
|
||||||
SDL_zeroa(text);
|
SDL_zeroa(text);
|
||||||
#ifdef X_HAVE_UTF8_STRING
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
if (data->ic) {
|
if (data->ic && xevent->type == KeyPress) {
|
||||||
X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text),
|
X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text),
|
||||||
&keysym, &status);
|
&keysym, &status);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1033,35 +1034,30 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
||||||
|
|
||||||
#ifdef SDL_USE_IME
|
#ifdef SDL_USE_IME
|
||||||
if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
|
if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
|
||||||
handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode);
|
handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode, (xevent->type == KeyPress ? SDL_PRESSED : SDL_RELEASED));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!handled_by_ime) {
|
if (!handled_by_ime) {
|
||||||
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
|
if (xevent->type == KeyPress) {
|
||||||
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
|
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
|
||||||
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
|
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
|
||||||
}
|
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
|
||||||
if(*text) {
|
}
|
||||||
SDL_SendKeyboardText(text);
|
if(*text) {
|
||||||
|
SDL_SendKeyboardText(text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (X11_KeyRepeat(display, xevent)) {
|
||||||
|
/* We're about to get a repeated key down, ignore the key up */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
X11_UpdateUserTime(data, xevent->xkey.time);
|
if (xevent->type == KeyPress) {
|
||||||
}
|
X11_UpdateUserTime(data, xevent->xkey.time);
|
||||||
break;
|
|
||||||
|
|
||||||
/* Key release? */
|
|
||||||
case KeyRelease:{
|
|
||||||
KeyCode keycode = xevent->xkey.keycode;
|
|
||||||
|
|
||||||
#ifdef DEBUG_XEVENTS
|
|
||||||
printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode);
|
|
||||||
#endif
|
|
||||||
if (X11_KeyRepeat(display, xevent)) {
|
|
||||||
/* We're about to get a repeated key down, ignore the key up */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue