Created
December 9, 2016 10:11
-
-
Save Allianzcortex/5d10e4b16feae058466a6681563644b5 to your computer and use it in GitHub Desktop.
让 sublime text2 可以输入中文
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment