tbetter Input Method Editor (IME) support - st - [fork] customized build of st,… | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit e85b6b64660214121164ea97fb098eaa4935f7db | |
parent 75f92eb3489275bfcad901e5ca424134eda6e2f4 | |
Author: Ivan Tham <[email protected]> | |
Date: Tue, 12 Feb 2019 18:41:41 +0100 | |
better Input Method Editor (IME) support | |
Features: | |
- Allow input methods swap with hotkey (E.g. left ctrl + left shift). | |
- Over-the-spot pre-editing style, pre-edit data placed over insertion point. | |
- Restart IME without segmentation fault. | |
TODO: | |
- Automatically pickup IME if st started before IME | |
Diffstat: | |
M st.c | 1 + | |
M win.h | 1 + | |
M x.c | 69 +++++++++++++++++++++++------… | |
3 files changed, 54 insertions(+), 17 deletions(-) | |
--- | |
diff --git a/st.c b/st.c | |
t@@ -2594,6 +2594,7 @@ draw(void) | |
term.ocx, term.ocy, term.line[term.ocy][term.ocx]); | |
term.ocx = cx, term.ocy = term.c.y; | |
xfinishdraw(); | |
+ xximspot(term.ocx, term.ocy); | |
} | |
void | |
diff --git a/win.h b/win.h | |
t@@ -36,3 +36,4 @@ void xsetmode(int, unsigned int); | |
void xsetpointermotion(int); | |
void xsetsel(char *); | |
int xstartdraw(void); | |
+void xximspot(int, int); | |
diff --git a/x.c b/x.c | |
t@@ -139,6 +139,9 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, … | |
static void xdrawglyph(Glyph, int, int); | |
static void xclear(int, int, int, int); | |
static int xgeommasktogravity(int); | |
+static void ximopen(Display *); | |
+static void ximinstantiate(Display *, XPointer, XPointer); | |
+static void ximdestroy(XIM, XPointer, XPointer); | |
static void xinit(int, int); | |
static void cresize(int, int); | |
static void xresize(int, int); | |
t@@ -997,6 +1000,43 @@ xunloadfonts(void) | |
} | |
void | |
+ximopen(Display *dpy) | |
+{ | |
+ XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy }; | |
+ | |
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | |
+ XSetLocaleModifiers("@im=local"); | |
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | |
+ XSetLocaleModifiers("@im="); | |
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NU… | |
+ die("XOpenIM failed. Could not open input devi… | |
+ } | |
+ } | |
+ if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL) | |
+ die("XSetIMValues failed. Could not set input method value.\n"… | |
+ xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatus… | |
+ XNClientWindow, xw.win, XNFocusWindow, xw.win,… | |
+ if (xw.xic == NULL) | |
+ die("XCreateIC failed. Could not obtain input method.\n"); | |
+} | |
+ | |
+void | |
+ximinstantiate(Display *dpy, XPointer client, XPointer call) | |
+{ | |
+ ximopen(dpy); | |
+ XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, | |
+ ximinstantiate, NULL); | |
+} | |
+ | |
+void | |
+ximdestroy(XIM xim, XPointer client, XPointer call) | |
+{ | |
+ xw.xim = NULL; | |
+ XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, | |
+ ximinstantiate, NULL); | |
+} | |
+ | |
+void | |
xinit(int cols, int rows) | |
{ | |
XGCValues gcvalues; | |
t@@ -1033,7 +1073,7 @@ xinit(int cols, int rows) | |
xw.attrs.background_pixel = dc.col[defaultbg].pixel; | |
xw.attrs.border_pixel = dc.col[defaultbg].pixel; | |
xw.attrs.bit_gravity = NorthWestGravity; | |
- xw.attrs.event_mask = FocusChangeMask | KeyPressMask | |
+ xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | |
| ExposureMask | VisibilityChangeMask | StructureNotifyMask | |
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | |
xw.attrs.colormap = xw.cmap; | |
t@@ -1061,22 +1101,7 @@ xinit(int cols, int rows) | |
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); | |
/* input methods */ | |
- if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | |
- XSetLocaleModifiers("@im=local"); | |
- if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | |
- XSetLocaleModifiers("@im="); | |
- if ((xw.xim = XOpenIM(xw.dpy, | |
- NULL, NULL, NULL)) == NULL) { | |
- die("XOpenIM failed. Could not open input" | |
- " device.\n"); | |
- } | |
- } | |
- } | |
- xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | |
- | XIMStatusNothing, XNClientWindow,… | |
- XNFocusWindow, xw.win, NULL); | |
- if (xw.xic == NULL) | |
- die("XCreateIC failed. Could not obtain input method.\n"); | |
+ ximopen(xw.dpy); | |
/* white cursor, black outline */ | |
cursor = XCreateFontCursor(xw.dpy, mouseshape); | |
t@@ -1555,6 +1580,16 @@ xfinishdraw(void) | |
} | |
void | |
+xximspot(int x, int y) | |
+{ | |
+ XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch }; | |
+ XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NUL… | |
+ | |
+ XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL); | |
+ XFree(attr); | |
+} | |
+ | |
+void | |
expose(XEvent *ev) | |
{ | |
redraw(); |