commit 0556853f906c938396d798f95cd4eaa287b7adf8
parent 8e65be88ab4d6163990359741b3f36120b4dd403
Author: Ivan Tham <pickfire@riseup.net>
Date: Sat, 2 Feb 2019 20:17:19 +0800
[st][fix_ime] Fix st ime behavior
Diffstat:
2 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/st.suckless.org/patches/fix_ime/index.md b/st.suckless.org/patches/fix_ime/index.md
@@ -0,0 +1,22 @@
+Fix IME
+=======
+
+Description
+-----------
+Better Input Method Editor (IME) support. Features:
+
+* Over-the-spot pre-editing style, pre-edit data placed over insertion point
+* Restart IME without breaking st
+
+TODO:
+
+* Allow swapping input methods (E.g. ctrl + alt)
+* Automatically pickup IME if st started before IME
+
+Download
+--------
+* [st-ime-20190202-3be4cf1.diff](st-ime-20190202-3be4cf1.diff)
+
+Authors
+-------
+* Ivan Tham - <pickfire@riseup.net>
diff --git a/st.suckless.org/patches/fix_ime/st-ime-20190202-3be4cf1.diff b/st.suckless.org/patches/fix_ime/st-ime-20190202-3be4cf1.diff
@@ -0,0 +1,123 @@
+diff --git a/st.c b/st.c
+index b8e6077..cf8687e 100644
+--- a/st.c
++++ b/st.c
+@@ -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
+index 31f327d..a6ef1b9 100644
+--- a/win.h
++++ b/win.h
+@@ -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
+index 0422421..714098f 100644
+--- a/x.c
++++ b/x.c
+@@ -139,6 +139,9 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
+ 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);
+@@ -996,6 +999,46 @@ xunloadfonts(void)
+ xunloadfont(&dc.ibfont);
+ }
+
++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)) == NULL) {
++ die("XOpenIM failed. Could not open input"
++ " device.\n");
++ }
++ }
++ }
++ 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 | XIMStatusNothing,
++ XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL);
++ 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)
+ {
+@@ -1061,22 +1104,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, xw.win,
+- 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);
+@@ -1554,6 +1582,16 @@ xfinishdraw(void)
+ defaultfg : defaultbg].pixel);
+ }
+
++void
++xximspot(int x, int y)
++{
++ XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch };
++ XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
++
++ XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL);
++ XFree(attr);
++}
++
+ void
+ expose(XEvent *ev)
+ {