diff options
author | Ivan Tham <pickfire@riseup.net> | 2019-02-12 18:41:41 +0100 |
---|---|---|
committer | Hiltjo Posthuma <hiltjo@codemadness.org> | 2019-02-12 18:45:15 +0100 |
commit | e85b6b64660214121164ea97fb098eaa4935f7db (patch) | |
tree | d08873d1902c94102ce19294efa0c5bcd2c8d040 /x.c | |
parent | 75f92eb3489275bfcad901e5ca424134eda6e2f4 (diff) | |
download | st-patched-e85b6b64660214121164ea97fb098eaa4935f7db.tar.bz2 st-patched-e85b6b64660214121164ea97fb098eaa4935f7db.tar.xz st-patched-e85b6b64660214121164ea97fb098eaa4935f7db.zip |
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 (limited to 'x.c')
-rw-r--r-- | x.c | 69 |
1 files changed, 52 insertions, 17 deletions
@@ -139,6 +139,9 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); | |||
139 | static void xdrawglyph(Glyph, int, int); | 139 | static void xdrawglyph(Glyph, int, int); |
140 | static void xclear(int, int, int, int); | 140 | static void xclear(int, int, int, int); |
141 | static int xgeommasktogravity(int); | 141 | static int xgeommasktogravity(int); |
142 | static void ximopen(Display *); | ||
143 | static void ximinstantiate(Display *, XPointer, XPointer); | ||
144 | static void ximdestroy(XIM, XPointer, XPointer); | ||
142 | static void xinit(int, int); | 145 | static void xinit(int, int); |
143 | static void cresize(int, int); | 146 | static void cresize(int, int); |
144 | static void xresize(int, int); | 147 | static void xresize(int, int); |
@@ -997,6 +1000,43 @@ xunloadfonts(void) | |||
997 | } | 1000 | } |
998 | 1001 | ||
999 | void | 1002 | void |
1003 | ximopen(Display *dpy) | ||
1004 | { | ||
1005 | XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy }; | ||
1006 | |||
1007 | if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | ||
1008 | XSetLocaleModifiers("@im=local"); | ||
1009 | if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | ||
1010 | XSetLocaleModifiers("@im="); | ||
1011 | if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) | ||
1012 | die("XOpenIM failed. Could not open input device.\n"); | ||
1013 | } | ||
1014 | } | ||
1015 | if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL) | ||
1016 | die("XSetIMValues failed. Could not set input method value.\n"); | ||
1017 | xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, | ||
1018 | XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL); | ||
1019 | if (xw.xic == NULL) | ||
1020 | die("XCreateIC failed. Could not obtain input method.\n"); | ||
1021 | } | ||
1022 | |||
1023 | void | ||
1024 | ximinstantiate(Display *dpy, XPointer client, XPointer call) | ||
1025 | { | ||
1026 | ximopen(dpy); | ||
1027 | XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, | ||
1028 | ximinstantiate, NULL); | ||
1029 | } | ||
1030 | |||
1031 | void | ||
1032 | ximdestroy(XIM xim, XPointer client, XPointer call) | ||
1033 | { | ||
1034 | xw.xim = NULL; | ||
1035 | XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, | ||
1036 | ximinstantiate, NULL); | ||
1037 | } | ||
1038 | |||
1039 | void | ||
1000 | xinit(int cols, int rows) | 1040 | xinit(int cols, int rows) |
1001 | { | 1041 | { |
1002 | XGCValues gcvalues; | 1042 | XGCValues gcvalues; |
@@ -1033,7 +1073,7 @@ xinit(int cols, int rows) | |||
1033 | xw.attrs.background_pixel = dc.col[defaultbg].pixel; | 1073 | xw.attrs.background_pixel = dc.col[defaultbg].pixel; |
1034 | xw.attrs.border_pixel = dc.col[defaultbg].pixel; | 1074 | xw.attrs.border_pixel = dc.col[defaultbg].pixel; |
1035 | xw.attrs.bit_gravity = NorthWestGravity; | 1075 | xw.attrs.bit_gravity = NorthWestGravity; |
1036 | xw.attrs.event_mask = FocusChangeMask | KeyPressMask | 1076 | xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask |
1037 | | ExposureMask | VisibilityChangeMask | StructureNotifyMask | 1077 | | ExposureMask | VisibilityChangeMask | StructureNotifyMask |
1038 | | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | 1078 | | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; |
1039 | xw.attrs.colormap = xw.cmap; | 1079 | xw.attrs.colormap = xw.cmap; |
@@ -1061,22 +1101,7 @@ xinit(int cols, int rows) | |||
1061 | xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); | 1101 | xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); |
1062 | 1102 | ||
1063 | /* input methods */ | 1103 | /* input methods */ |
1064 | if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | 1104 | ximopen(xw.dpy); |
1065 | XSetLocaleModifiers("@im=local"); | ||
1066 | if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { | ||
1067 | XSetLocaleModifiers("@im="); | ||
1068 | if ((xw.xim = XOpenIM(xw.dpy, | ||
1069 | NULL, NULL, NULL)) == NULL) { | ||
1070 | die("XOpenIM failed. Could not open input" | ||
1071 | " device.\n"); | ||
1072 | } | ||
1073 | } | ||
1074 | } | ||
1075 | xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | ||
1076 | | XIMStatusNothing, XNClientWindow, xw.win, | ||
1077 | XNFocusWindow, xw.win, NULL); | ||
1078 | if (xw.xic == NULL) | ||
1079 | die("XCreateIC failed. Could not obtain input method.\n"); | ||
1080 | 1105 | ||
1081 | /* white cursor, black outline */ | 1106 | /* white cursor, black outline */ |
1082 | cursor = XCreateFontCursor(xw.dpy, mouseshape); | 1107 | cursor = XCreateFontCursor(xw.dpy, mouseshape); |
@@ -1555,6 +1580,16 @@ xfinishdraw(void) | |||
1555 | } | 1580 | } |
1556 | 1581 | ||
1557 | void | 1582 | void |
1583 | xximspot(int x, int y) | ||
1584 | { | ||
1585 | XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch }; | ||
1586 | XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); | ||
1587 | |||
1588 | XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL); | ||
1589 | XFree(attr); | ||
1590 | } | ||
1591 | |||
1592 | void | ||
1558 | expose(XEvent *ev) | 1593 | expose(XEvent *ev) |
1559 | { | 1594 | { |
1560 | redraw(); | 1595 | redraw(); |