Sublime Forum

Input method support

#1

An older version of subl seems provide a bad support of input method, and the latest version even seems remove it.

I hope sublime will support input method correctly, since it’s a requirement for all CJK user, which sublime developer might ignore.

I’m developer of Fcitx, an input method framework on linux, for some technical details:

  1. do not grab key event before input method.
  2. do not eat key event it doesn’t use.
    Input method should always have the highest priority for key event, and by default input method use “ctrl + space” as default trigger key, which all application should avoid.

Thanks.

0 Likes

Dev Build 3137
#2

After some explore at least sublime missing gtk_im_context_focus_in for the text widget.

0 Likes

#3

遇见csslayer大神了,我也这些问题折磨,不过也同样惊奇于fcitx的兼容性,我用ibus完全不能输入。btw:从build 2183开始,st2已经不再占用ctrl-space了

0 Likes

#4

Builds 2183 and later (see sublimetext.com/dev) should work with IMEs on Linux, as the application no longer captures ctrl+space.

I’m not at all familiar with Fcitx, but I tried it on Ubuntu and it seemed to be working: After pressing ctrl+space, the IME window appeared, and I was able to enter characters using it.

0 Likes

#5

Hi, jps

No, it doesn’t work. I have give 2195 a try on ubuntu 12.04 (I can test it on so many other distribution, but result will not change), for both fcitx and ibus (ubuntu default).

Please check what I said, I fully understand why sublime doesn’t work. sublime is missing gtk_im_context_set_focus call. Input method will not process key when widget don’t have focus, otherwise it will cause some other bug.

After I gdb attach and set focus manually. I still find backspace being grabbed by sublime text first, I don’t know there is some other key is grabbed, but please check it.

0 Likes

#6

and
please call gtk_im_context_set_cursor_location, argument is the position corresponding to the window.
It will make input window of input method appear at the cursor position, which is important to most CJK user.

0 Likes

#7

Any response?
This problem is really concern most of the chinese, japanese, korean sublime text users.

0 Likes

#8

vietnam sublime text users too.
any news?

0 Likes

#9

just tried today, still not work (2.2216)

please check #2 hint for how to fix it. Most gtk im module implementation don’t send keyboard event if widget don’t have focus.

0 Likes

#10

Since user “csslayer” gives so many hints how to solve this problem, I’m wondering why this couldn’t be fixed yet.
It’s really an important issue for most CJK users.

0 Likes

#11

Still not solved.

build 2217 with fcitx…
it seems that it can not call the fcitx by the shortcut with Ctrl-Space. but change the fcitx’s shortcut from C-S to another. Problem remains…

0 Likes

#12

input methods(seems all 3rd party or system intergrated ) can’t follow cursor position in microsoft windows 7 and xp.
Jon, please consider fix this problem, every cjk user depend on input methods

0 Likes

#13

Still not works in CJK with ibus :frowning:
I hope this can be solved as soon as possible.

By the way, there is a package named “InputHelper” which can temporarily solve this issue. (Though it’s not quite convenient)

0 Likes

#14

I’m a sublime text2 user from China, it works fine in my windows, but in my fedora i can’t input any Chinese words :astonished: , it’s important for CJK user, please fix it.

0 Likes

#15

VIM is awesome! I’m not going to buy a Sublime until this bug has been fixed.

0 Likes

#16

This is a dirty fix but at least works. cursor position update also supported.

Use LD_PRELOAD to reimplement gtk_im_context_set_client_window and set im focus in.
use “gdk_region_get_clipbox” to catch the caret position. (It’s really difficult to find which function can catch the position…)

Here I made a assumption that the caret width is always 2, since it is 2.

the height is the “font glyph height”.

1, save below code to sublime_imfix.c

/*
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>

gcc -shared -o libsublime-imfix.so sublime_imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC
LD_PRELOAD=./libsublime-imfix.so sublime_text
*/
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
typedef GdkSegment GdkRegionBox;

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

GtkIMContext *local_context;

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; 
  //Maybe sometimes we will make a mistake, but for most of the time, it should be the caret.
  if(rectangle->width == 2 && 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);

  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;
  }
  gdk_window_add_filter (window, event_filter, context); 
}

2, compile a shared library.

gcc -shared -o libsublime-imfix.so sublime_imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC

3, LD_PRELOAD it

LD_PRELOAD=./libsublime-imfix.so sublime_text
0 Likes

#17

.

0 Likes

#18

[quote=“cjacker”]This is a dirty fix but at least works. cursor location update still not works, since I really can not find a proper way to get the current caret loation relative to
GdkWidow, it seems sublime use a customized GtkWidget? I am not sure.

[/quote]

I’ve tested this in Archlinux with sublime version 2.0.1-2, It works quite well.

Thanks for your excellent job!!

0 Likes

#19

I’ve tested this in Archlinux with sublime version 2.0.1-2, It works quite well.

Thanks for your excellent job!![/quote]

original post had been updated to support cursor location update, please try it.

0 Likes

#20

Followed all of cjacker’s steps but they didn’t seem to work for me. No errors or anything, I just still don’t get anything from the IME. Even if I turn it on manurally, when I type the characters are still English, not the Japanese characters from the IME.

0 Likes