Sublime Text实在太好用了,我都好久没有用过VIM了。
不知道从什么时候起,ubuntu下的中文输入突然不能用了(fcitx/ibus都无效)。在这里,我找到一个比较完美的解决方案:
- 安装编译依赖:
[cc lang="bash"]sudo apt-get install libgtk2.0-d[/cc] 然后在任意位置以下面的内容新建文件sublime\_imfix.c:
[cc lang="c"]
/*
sublime-imfix.c
Use LD\_PRELOAD to interpose some function to fix sublime input method support for linux.
By Cjacker Huang
gcc -shared -o libsublime-imfix.so sublime\_imfix.cpkg-config --libs --cflags gtk+-2.0-fPIC
LD\_PRELOAD=./libsublime-imfix.so sublime\_text
*/include
include
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);
}
[/cc]- 编译这个文件:
[cc lang="bash"]gcc -shared -o libsublime-imfix.so sublime\_imfix.cpkg-config --libs --cflags gtk+-2.0-fPIC[/cc]
如果一切顺利,会生成一个libsublime-imfix.so,把它移动到sublime text的安装目录,如:
[cc lang="bash"]mv libsublime-imfix.so /opt/sublime\_text[/cc] 修改/usr/bin/subl的内容为:
[cc lang="bash"]!/bin/sh
sh -c "LD\_PRELOAD=/opt/sublime\_text/libsublime-imfix.so /opt/sublime\_text/sublime\_text '$@'"
exec /opt/sublime\_text/sublime\_text "$@"
[/cc]
修改/usr/share/applications/sublime\_text.desktop内容为:
[cc lang="bash"]
[Desktop Entry]
Version=1.0
Type=Application
Name=Sublime Text
GenericName=Text Editor
Comment=Sophisticated text editor for code, markup and prose
Exec=/usr/bin/subl %F
Terminal=false
MimeType=text/plain;
Icon=sublime-text
Categories=TextEditor;Development;
StartupNotify=true
Actions=Window;Document;
[Desktop Action Window]
Name=New Window
Exec=/usr/bin/subl -n
OnlyShowIn=Unity;
[Desktop Action Document]
Name=New File
Exec=/usr/bin/subl --command new\_file
OnlyShowIn=Unity;[/cc]最后得到:
之所以前面说“比较完美”,是因为如果以root权限运行:sudo subl something,输入法依然不可用。我估摸着大概是因为系统不允许以root身份加载那个so文件吧。
补丁作者的信息可以从C代码的头部注释中找到。