mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-16 11:06:49 +01:00
Fix double events / no repeat flag on key events when built withoutibus/fcitx
Uses XkbSetDetectableKeyRepeat, and falls back to forcing @im=none if it's not supported.
This commit is contained in:
parent
88f2d16e45
commit
5fe984978c
@ -568,14 +568,18 @@ X11_DispatchEvent(_THIS)
|
|||||||
printf("Filtered event type = %d display = %d window = %d\n",
|
printf("Filtered event type = %d display = %d window = %d\n",
|
||||||
xevent.type, xevent.xany.display, xevent.xany.window);
|
xevent.type, xevent.xany.display, xevent.xany.window);
|
||||||
#endif
|
#endif
|
||||||
if (orig_keycode) {
|
|
||||||
/* Make sure dead key press/release events are sent */
|
/* Make sure dead key press/release events are sent */
|
||||||
|
/* But only if we're using one of the DBus IMEs, otherwise
|
||||||
|
some XIM IMEs will generate duplicate events */
|
||||||
|
if (orig_keycode) {
|
||||||
|
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
|
||||||
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
||||||
if (orig_event_type == KeyPress) {
|
if (orig_event_type == KeyPress) {
|
||||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||||
} else {
|
} else {
|
||||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
#include "imKStoUCS.h"
|
#include "imKStoUCS.h"
|
||||||
|
|
||||||
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
|
#include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
static const struct {
|
static const struct {
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
@ -262,6 +266,7 @@ X11_InitKeyboard(_THIS)
|
|||||||
int best_distance;
|
int best_distance;
|
||||||
int best_index;
|
int best_index;
|
||||||
int distance;
|
int distance;
|
||||||
|
BOOL xkb_repeat = 0;
|
||||||
|
|
||||||
X11_XAutoRepeatOn(data->display);
|
X11_XAutoRepeatOn(data->display);
|
||||||
|
|
||||||
@ -269,12 +274,74 @@ X11_InitKeyboard(_THIS)
|
|||||||
{
|
{
|
||||||
int xkb_major = XkbMajorVersion;
|
int xkb_major = XkbMajorVersion;
|
||||||
int xkb_minor = XkbMinorVersion;
|
int xkb_minor = XkbMinorVersion;
|
||||||
|
|
||||||
if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
|
if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
|
||||||
data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
|
data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This will remove KeyRelease events for held keys */
|
||||||
|
X11_XkbSetDetectableAutoRepeat(data->display, True, &xkb_repeat);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Open a connection to the X input manager */
|
||||||
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
|
if (SDL_X11_HAVE_UTF8) {
|
||||||
|
/* Set the locale, and call XSetLocaleModifiers before XOpenIM so that
|
||||||
|
Compose keys will work correctly. */
|
||||||
|
char *prev_locale = setlocale(LC_ALL, NULL);
|
||||||
|
char *prev_xmods = X11_XSetLocaleModifiers(NULL);
|
||||||
|
const char *new_xmods = "";
|
||||||
|
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
|
||||||
|
const char *env_xmods = SDL_getenv("XMODIFIERS");
|
||||||
|
#endif
|
||||||
|
SDL_bool has_dbus_ime_support = SDL_FALSE;
|
||||||
|
|
||||||
|
if (prev_locale) {
|
||||||
|
prev_locale = SDL_strdup(prev_locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_xmods) {
|
||||||
|
prev_xmods = SDL_strdup(prev_xmods);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IBus resends some key events that were filtered by XFilterEvents
|
||||||
|
when it is used via XIM which causes issues. Prevent this by forcing
|
||||||
|
@im=none if XMODIFIERS contains @im=ibus. IBus can still be used via
|
||||||
|
the DBus implementation, which also has support for pre-editing. */
|
||||||
|
#ifdef HAVE_IBUS_IBUS_H
|
||||||
|
if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
|
||||||
|
has_dbus_ime_support = SDL_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FCITX_FRONTEND_H
|
||||||
|
if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) {
|
||||||
|
has_dbus_ime_support = SDL_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (has_dbus_ime_support || !xkb_repeat) {
|
||||||
|
new_xmods = "@im=none";
|
||||||
|
}
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
X11_XSetLocaleModifiers(new_xmods);
|
||||||
|
|
||||||
|
data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname);
|
||||||
|
|
||||||
|
/* Reset the locale + X locale modifiers back to how they were,
|
||||||
|
locale first because the X locale modifiers depend on it. */
|
||||||
|
setlocale(LC_ALL, prev_locale);
|
||||||
|
X11_XSetLocaleModifiers(prev_xmods);
|
||||||
|
|
||||||
|
if (prev_locale) {
|
||||||
|
SDL_free(prev_locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_xmods) {
|
||||||
|
SDL_free(prev_xmods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Try to determine which scancodes are being used based on fingerprint */
|
/* Try to determine which scancodes are being used based on fingerprint */
|
||||||
best_distance = SDL_arraysize(fingerprint) + 1;
|
best_distance = SDL_arraysize(fingerprint) + 1;
|
||||||
best_index = -1;
|
best_index = -1;
|
||||||
|
@ -179,6 +179,7 @@ SDL_X11_SYM(Status,XkbGetState,(Display* a,unsigned int b,XkbStatePtr c),(a,b,c)
|
|||||||
SDL_X11_SYM(Status,XkbGetUpdatedMap,(Display* a,unsigned int b,XkbDescPtr c),(a,b,c),return)
|
SDL_X11_SYM(Status,XkbGetUpdatedMap,(Display* a,unsigned int b,XkbDescPtr c),(a,b,c),return)
|
||||||
SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b,c),return)
|
SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b,c),return)
|
||||||
SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
|
SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
|
||||||
|
SDL_X11_SYM(BOOL,XkbSetDetectableAutoRepeat,(Display* a, BOOL b, BOOL* c),(a,b,c),return)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if NeedWidePrototypes
|
#if NeedWidePrototypes
|
||||||
|
@ -39,10 +39,6 @@
|
|||||||
#include "SDL_x11opengles.h"
|
#include "SDL_x11opengles.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef X_HAVE_UTF8_STRING
|
|
||||||
#include <locale.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialization/Query functions */
|
/* Initialization/Query functions */
|
||||||
static int X11_VideoInit(_THIS);
|
static int X11_VideoInit(_THIS);
|
||||||
static void X11_VideoQuit(_THIS);
|
static void X11_VideoQuit(_THIS);
|
||||||
@ -388,65 +384,6 @@ X11_VideoInit(_THIS)
|
|||||||
/* I have no idea how random this actually is, or has to be. */
|
/* I have no idea how random this actually is, or has to be. */
|
||||||
data->window_group = (XID) (((size_t) data->pid) ^ ((size_t) _this));
|
data->window_group = (XID) (((size_t) data->pid) ^ ((size_t) _this));
|
||||||
|
|
||||||
/* Open a connection to the X input manager */
|
|
||||||
#ifdef X_HAVE_UTF8_STRING
|
|
||||||
if (SDL_X11_HAVE_UTF8) {
|
|
||||||
/* Set the locale, and call XSetLocaleModifiers before XOpenIM so that
|
|
||||||
Compose keys will work correctly. */
|
|
||||||
char *prev_locale = setlocale(LC_ALL, NULL);
|
|
||||||
char *prev_xmods = X11_XSetLocaleModifiers(NULL);
|
|
||||||
const char *new_xmods = "";
|
|
||||||
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
|
|
||||||
const char *env_xmods = SDL_getenv("XMODIFIERS");
|
|
||||||
#endif
|
|
||||||
SDL_bool has_dbus_ime_support = SDL_FALSE;
|
|
||||||
|
|
||||||
if (prev_locale) {
|
|
||||||
prev_locale = SDL_strdup(prev_locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_xmods) {
|
|
||||||
prev_xmods = SDL_strdup(prev_xmods);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IBus resends some key events that were filtered by XFilterEvents
|
|
||||||
when it is used via XIM which causes issues. Prevent this by forcing
|
|
||||||
@im=none if XMODIFIERS contains @im=ibus. IBus can still be used via
|
|
||||||
the DBus implementation, which also has support for pre-editing. */
|
|
||||||
#ifdef HAVE_IBUS_IBUS_H
|
|
||||||
if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
|
|
||||||
has_dbus_ime_support = SDL_TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FCITX_FRONTEND_H
|
|
||||||
if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) {
|
|
||||||
has_dbus_ime_support = SDL_TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (has_dbus_ime_support) {
|
|
||||||
new_xmods = "@im=none";
|
|
||||||
}
|
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
X11_XSetLocaleModifiers(new_xmods);
|
|
||||||
|
|
||||||
data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname);
|
|
||||||
|
|
||||||
/* Reset the locale + X locale modifiers back to how they were,
|
|
||||||
locale first because the X locale modifiers depend on it. */
|
|
||||||
setlocale(LC_ALL, prev_locale);
|
|
||||||
X11_XSetLocaleModifiers(prev_xmods);
|
|
||||||
|
|
||||||
if (prev_locale) {
|
|
||||||
SDL_free(prev_locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev_xmods) {
|
|
||||||
SDL_free(prev_xmods);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Look up some useful Atoms */
|
/* Look up some useful Atoms */
|
||||||
#define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False)
|
#define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False)
|
||||||
GET_ATOM(WM_PROTOCOLS);
|
GET_ATOM(WM_PROTOCOLS);
|
||||||
|
Loading…
Reference in New Issue
Block a user