Sublime Forum

3103, Unable to enter Chinese,,ibus fcitx

#1

3103, Unable to enter Chinese,ibus fcitx

0 Likes

#2

It would be good if you have searched fcitx before you post.

0 Likes

#3

Every time I toss, the system is a bad time, and now the system is bad, Pinyin IBus input method is gray, can not be used, fcitx is not enough, the system will not be the first choice.

我每折腾一次,系统就坏一次,现在系统又坏了,ibus pinyin输入法灰色,不能用了,fcitx也不行的,系统首选项也打不开了

0 Likes

#4

Are you using Ubuntu?

0 Likes

#5

yes ,Ubuntu

0 Likes

#6

You may try my sublime_text_fcitx/sublime_text_fcitx.sh script in https://github.com/jfcherng/my_scripts.

If ST is not installed by a deb package, you have to modify the install path (default: /opt/sublime_text) in subl, sublime_text.desktop and sublime_text_fcitx.sh.

And then just execute the script with sudo.

It should be done if there is any luck.

I have used the script since Ubuntu 14.04 and now 16.04 works too.

It does nothing special than other solution for fcitx but just in a script.

0 Likes

#7

这并没真正解决问题,这个库会造成一些不是意外的意外, 比如terminal插件,colorPicker插件等就再也用不了,从菜单里也没法再打开配置/插件目录了。

0 Likes

#8
  • I use the terminal plugin created by wbond too. It works.
  • I use the menu to open settings files. It works.
  • You are not the first one to mention this issue and Jon never replies this. :slight_smile:

I am not sure what happens to your ST. What’s the version of your Ubuntu?

0 Likes

#9

(gnome-terminal:12645): Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported

那请问你是如何解决这个问题的?

0 Likes

#10

Ah, I guess I know why it won’t work.
Ubuntu 16.04’s default desktop environment uses a newer GTK.
But the desktop environment I used is LXDE which may use an old one.

I will try it in a virtual machine later.

0 Likes

#11

嗯,目前我用的是深度系统,自带的终端是gtk+3开发的,所以可以使用。
文件管理管理器是Nautilus, 也可以使用;
但是偏偏自带的终端和文件管理器都不太好用,但sublime的原因,我只能保留着。
不过colorPicker这个插件就真的用不了了。

按ctrl + `, 然后执行 import subprocess, 再用subprocess.Popen()方法调用系统的其他应用,绝大部分都没用。


只希望作者能接受这个库,或者通过别的方式修复支持输入法了。

0 Likes

#12

It’s no use.
都没什么用

0 Likes

#13

I just test in a clean Ubuntu 16.04 and the script works fine with fcitx.

0 Likes

#14

没有用那个imfix.so也正常?
不过不喜欢用原生的ubuntu,丑的没朋友。
等elementary0.4出来,再说

0 Likes

#15

用的。我只是想告訴 @120011676 這東西確實對 Ubuntu 16.04 有效。
另外在這裡使用中文問答的話,只有非常少數的人會回覆你。
反正我是沒看過有人用中文。

0 Likes

#16

哦, 吓到我了。还以为……


我也看问题的,别的问题我就英语,这个问题我就用中文了,反正有这个纠结的人,基本上都是中国人,哈哈

0 Likes

#17

不过我用的是另外一个库文件,那个可以解决光标跟随。你用的那个太旧了,输入的时候光标不跟随

    /*
    sublime-imfix.c
    Use LD_PRELOAD to interpose some function to fix sublime input method support for linux.
    By Cjacker Huang <jianzhong.huang at i-soft.com.cn>
    By whitequark@whitequark.org

    How to compile:
    gcc -shared -o libsublime-imfix.so sublime_imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC
    How to use:
    LD_PRELOAD=./libsublime-imfix.so sublime_text

    Changes:
    2014 06-09
    1, Fix cursor position update for sublime text 3.
    2, Combine the codes from whitequark(fix for xim immodule) and add cursor update support for XIM immodule.
    */

    /*for RTLD_NEXT*/
    #define _GNU_SOURCE

    #include <gtk/gtk.h>
    #include <gdk/gdkx.h>
    #include <assert.h>
    #include <dlfcn.h>
    #include <stdio.h>
    #include <string.h>
    #include <gtk/gtk.h>
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>

    #ifdef VERBOSE
    #define DEBUG(fmt, ...) do { \
        FILE* err = fopen("/tmp/libsublime-immethod-fix.log", "a"); \
        if (err) { \
          fprintf(err, fmt, __VA_ARGS__); \
          fclose(err); \
        } \
      } while(0)
    #else
    #define DEBUG(fmt, ...)
    #endif


    typedef GdkSegment GdkRegionBox;

    struct _GdkRegion
    {
      long size;
      long numRects;
      GdkRegionBox *rects;
      GdkRegionBox extents;
    };

    GtkIMContext *local_context;


    //this func is interposed to support cursor position update.
    void
    gdk_region_get_clipbox (const GdkRegion *region,
                GdkRectangle    *rectangle)
    {
      g_return_if_fail (region != NULL);
      g_return_if_fail (rectangle != NULL);

      rectangle->x = region->extents.x1;
      rectangle->y = region->extents.y1;
      rectangle->width = region->extents.x2 - region->extents.x1;
      rectangle->height = region->extents.y2 - region->extents.y1;
      GdkRectangle rect;
      rect.x = rectangle->x;
      rect.y = rectangle->y;
      rect.width = 0;
      rect.height = rectangle->height;
      //The caret width is 2 in sublime text 2
      //And is 1 in sublime text 3.
      //Maybe sometimes we will make a mistake, but for most of the time, it should be the caret.
      if((rectangle->width == 2 || rectangle->width == 1)  && GTK_IS_IM_CONTEXT(local_context)) {
            gtk_im_context_set_cursor_location(local_context, rectangle);
      }
    }

    //this is needed, for example, if you input something in file dialog and return back the edit area
    //context will lost, so here we set it again.
    static GdkFilterReturn event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer im_context)
    {
        XEvent *xev = (XEvent *)xevent;
        if(xev->type == KeyRelease && GTK_IS_IM_CONTEXT(im_context)) {
           GdkWindow * win = g_object_get_data(G_OBJECT(im_context),"window");
           if(GDK_IS_WINDOW(win))
             gtk_im_context_set_client_window(im_context, win);
        }
        return GDK_FILTER_CONTINUE;
    }

    void gtk_im_context_set_client_window (GtkIMContext *context,
              GdkWindow    *window)
    {
        GtkIMContextClass *klass;
        g_return_if_fail (GTK_IS_IM_CONTEXT (context));
        klass = GTK_IM_CONTEXT_GET_CLASS (context);
        if (klass->set_client_window)
            klass->set_client_window (context, window);

        //below is our interposed codes to save the context to local_context.
        if(!GDK_IS_WINDOW (window))
            return;
        g_object_set_data(G_OBJECT(context),"window",window);
        int width = gdk_window_get_width(window);
        int height = gdk_window_get_height(window);
        if(width != 0 && height !=0) {
            gtk_im_context_focus_in(context);
            local_context = context;
        }
        //only add this event_filter when using 'fcitx' immodule.
        //for xim immodule, this function is as same as original from gtk2.
        const gchar * immodule = g_getenv("GTK_IM_MODULE");
        if(immodule && !strcmp(immodule, "fcitx")) {
            gdk_window_add_filter (window, event_filter, context);
        }
    }


    /*below codes is from whitequark, fix for xim immodule*/

    /* See gtkimcontextxim.c */
    GType gtk_type_im_context_xim = 0;

    #define GTK_TYPE_IM_CONTEXT_XIM            (gtk_type_im_context_xim)
    #define GTK_IM_CONTEXT_XIM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
    #define GTK_IM_CONTEXT_XIM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
    #define GTK_IS_IM_CONTEXT_XIM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
    #define GTK_IS_IM_CONTEXT_XIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_XIM))
    #define GTK_IM_CONTEXT_XIM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))

    typedef struct _GtkIMContextXIM       GtkIMContextXIM;
    typedef struct _GtkIMContextXIMClass  GtkIMContextXIMClass;

    struct _GtkIMContextXIMClass
    {
      GtkIMContextClass parent_class;
    };

    typedef struct _StatusWindow StatusWindow;
    typedef struct _GtkXIMInfo GtkXIMInfo;

    struct _GtkIMContextXIM
    {
      GtkIMContext object;

      GtkXIMInfo *im_info;

      gchar *locale;
      gchar *mb_charset;

      GdkWindow *client_window;
      GtkWidget *client_widget;

      /* The status window for this input context; we claim the
    *    * status window when we are focused and have created an XIC
    *       */
      StatusWindow *status_window;

      gint preedit_size;
      gint preedit_length;
      gunichar *preedit_chars;
      XIMFeedback *feedbacks;

      gint preedit_cursor;

      XIMCallback preedit_start_callback;
      XIMCallback preedit_done_callback;
      XIMCallback preedit_draw_callback;
      XIMCallback preedit_caret_callback;

      XIMCallback status_start_callback;
      XIMCallback status_done_callback;
      XIMCallback status_draw_callback;

      XIMCallback string_conversion_callback;

      XIC ic;

      guint filter_key_release : 1;
      guint use_preedit : 1;
      guint finalizing : 1;
      guint in_toplevel : 1;
      guint has_focus : 1;
    };

    static GClassInitFunc orig_gtk_im_context_xim_class_init;
    static GType (*orig_g_type_module_register_type)(GTypeModule *,
                                                     GType, const gchar *,
                                                     const GTypeInfo *, GTypeFlags);
    static gboolean (*orig_gtk_im_context_xim_filter_keypress)(GtkIMContext *context,
                                                               GdkEventKey *event);

    static gboolean
    hook_gtk_im_context_xim_filter_keypress(GtkIMContext *context, GdkEventKey *event) {
      GtkIMContextXIM *im_context_xim = GTK_IM_CONTEXT_XIM(context);
      if (!im_context_xim->client_window) {
        DEBUG("im_context_xim == %p\n", im_context_xim);
        DEBUG("event->window == %p\n", event->window);

        gtk_im_context_set_client_window(context, event->window);
      }

      return orig_gtk_im_context_xim_filter_keypress(context, event);
    }

    static void
    hook_gtk_im_context_xim_class_init (GtkIMContextXIMClass *class) {
      orig_gtk_im_context_xim_class_init(class, NULL); /* wat? */

      GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);

      assert(!orig_gtk_im_context_xim_filter_keypress);
      orig_gtk_im_context_xim_filter_keypress = im_context_class->filter_keypress;
      im_context_class->filter_keypress = hook_gtk_im_context_xim_filter_keypress;
      DEBUG("orig_gtk_im_context_xim_filter_keypress: %p\n",
            orig_gtk_im_context_xim_filter_keypress);
    }

    GType
    g_type_module_register_type (GTypeModule *module,
                                 GType parent_type,
                                 const gchar *type_name,
                                 const GTypeInfo *type_info,
                                 GTypeFlags flags) {
      if (!orig_g_type_module_register_type) {
        orig_g_type_module_register_type = dlsym(RTLD_NEXT, "g_type_module_register_type");
        assert(orig_g_type_module_register_type);
      }

      if (type_name && !strcmp(type_name, "GtkIMContextXIM")) {
        assert(!orig_gtk_im_context_xim_class_init);
        orig_gtk_im_context_xim_class_init = type_info->class_init;

        assert(sizeof(GtkIMContextXIM) == type_info->instance_size);

        const GTypeInfo hook_im_context_xim_info =
        {
          type_info->class_size,
          type_info->base_init,
          type_info->base_finalize,
          (GClassInitFunc) hook_gtk_im_context_xim_class_init,
          type_info->class_finalize,
          type_info->class_data,
          type_info->instance_size,
          type_info->n_preallocs,
          type_info->instance_init,
        };

        DEBUG("orig_gtk_im_context_xim_class_init: %p\n", orig_gtk_im_context_xim_class_init);

        gtk_type_im_context_xim =
          orig_g_type_module_register_type(module, parent_type, type_name,
                                           &hook_im_context_xim_info, flags);

        return gtk_type_im_context_xim;
      }

      return orig_g_type_module_register_type(module, parent_type, type_name, type_info, flags);
    }


1 Like

#18

yutent ,你好,我为什么用你这个库文件,光标也不跟随,centos7 Subl 3126.

0 Likes

#19

我的跟随,不过我现在不用了,因为用了这个补丁,会导致sublime无法调用gtk3开发的程序。
我现在发现一个输入法yong(http://yongim.ys168.com/),可以直接在sublime上使用,不用打补丁。

0 Likes

#20

beautiful, thank you so much, I use it in Ubuntu 16.04 gnome3 successfully.

0 Likes