Call setlocale + XSetModifiers before XOpenIM, Work around ibus+xim duplicate events.
authorAlex Baines <alex@abaines.me.uk>
Wed, 30 Sep 2015 04:16:09 +0100
changeset 104362f18ea79bc03
parent 10435 d610af48d2b8
child 10437 d62c4978fffa
Call setlocale + XSetModifiers before XOpenIM, Work around ibus+xim duplicate events.
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11video.c
     1.1 --- a/src/video/x11/SDL_x11events.c	Sat Oct 01 14:05:35 2016 -0700
     1.2 +++ b/src/video/x11/SDL_x11events.c	Wed Sep 30 04:16:09 2015 +0100
     1.3 @@ -565,15 +565,12 @@
     1.4  #endif
     1.5          if (orig_keycode) {
     1.6              /* Make sure dead key press/release events are sent */
     1.7 -            /* Actually, don't do this because it causes double-delivery
     1.8 -               of some keys on Ubuntu 14.04 (bug 2526)
     1.9              SDL_Scancode scancode = videodata->key_layout[orig_keycode];
    1.10              if (orig_event_type == KeyPress) {
    1.11                  SDL_SendKeyboardKey(SDL_PRESSED, scancode);
    1.12              } else {
    1.13                  SDL_SendKeyboardKey(SDL_RELEASED, scancode);
    1.14              }
    1.15 -            */
    1.16          }
    1.17          return;
    1.18      }
    1.19 @@ -781,6 +778,8 @@
    1.20              if (data->ic) {
    1.21                  X11_Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text),
    1.22                                    &keysym, &status);
    1.23 +            } else {
    1.24 +                X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
    1.25              }
    1.26  #else
    1.27              X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL);
     2.1 --- a/src/video/x11/SDL_x11sym.h	Sat Oct 01 14:05:35 2016 -0700
     2.2 +++ b/src/video/x11/SDL_x11sym.h	Wed Sep 30 04:16:09 2015 +0100
     2.3 @@ -196,6 +196,7 @@
     2.4  SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return)
     2.5  SDL_X11_SYM(void,Xutf8DrawString,(Display *a, Drawable b, XFontSet c, GC d, int e, int f, _Xconst char *g, int h),(a,b,c,d,e,f,g,h),)
     2.6  SDL_X11_SYM(int,Xutf8TextExtents,(XFontSet a, _Xconst char*	b, int c, XRectangle* d, XRectangle* e),(a,b,c,d,e),return)
     2.7 +SDL_X11_SYM(char*,XSetLocaleModifiers,(const char *a),(a),return)
     2.8  #endif
     2.9  
    2.10  #ifndef NO_SHARED_MEMORY
     3.1 --- a/src/video/x11/SDL_x11video.c	Sat Oct 01 14:05:35 2016 -0700
     3.2 +++ b/src/video/x11/SDL_x11video.c	Wed Sep 30 04:16:09 2015 +0100
     3.3 @@ -39,6 +39,10 @@
     3.4  #include "SDL_x11opengles.h"
     3.5  #endif
     3.6  
     3.7 +#ifdef X_HAVE_UTF8_STRING
     3.8 +#include <locale.h>
     3.9 +#endif
    3.10 +
    3.11  /* Initialization/Query functions */
    3.12  static int X11_VideoInit(_THIS);
    3.13  static void X11_VideoQuit(_THIS);
    3.14 @@ -387,8 +391,40 @@
    3.15      /* Open a connection to the X input manager */
    3.16  #ifdef X_HAVE_UTF8_STRING
    3.17      if (SDL_X11_HAVE_UTF8) {
    3.18 +        /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that 
    3.19 +           Compose keys will work correctly. */
    3.20 +        char *prev_locale = setlocale(LC_ALL, NULL);
    3.21 +        char *prev_xmods  = X11_XSetLocaleModifiers(NULL);
    3.22 +        
    3.23 +        if (prev_xmods) {
    3.24 +            prev_xmods = SDL_strdup(prev_xmods);
    3.25 +        }
    3.26 +        
    3.27 +        /* IBus resends some key events that were filtered by XFilterEvents
    3.28 +           when it is used via XIM which causes issues. Prevent this by forcing
    3.29 +           @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via 
    3.30 +           the DBus implementation, which also has support for pre-editing. */
    3.31 +        const char *new_xmods = "";
    3.32 +        const char *env_xmods = SDL_getenv("XMODIFIERS");
    3.33 +        
    3.34 +        if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
    3.35 +            new_xmods = "@im=none";
    3.36 +        }
    3.37 +        
    3.38 +        setlocale(LC_ALL, "");
    3.39 +        X11_XSetLocaleModifiers(new_xmods);
    3.40 +        
    3.41          data->im =
    3.42              X11_XOpenIM(data->display, NULL, data->classname, data->classname);
    3.43 +        
    3.44 +        /* Reset the locale + X locale modifiers back to how they were,
    3.45 +           locale first because the X locale modifiers depend on it. */
    3.46 +        setlocale(LC_ALL, prev_locale);
    3.47 +        X11_XSetLocaleModifiers(prev_xmods);
    3.48 +        
    3.49 +        if (prev_xmods) {
    3.50 +            SDL_free(prev_xmods);
    3.51 +        }
    3.52      }
    3.53  #endif
    3.54