aboutsummaryrefslogtreecommitdiff
path: root/x.c
diff options
context:
space:
mode:
authorQuentin Rameau <quinq@fifth.space>2020-02-02 21:47:19 +0100
committerHiltjo Posthuma <hiltjo@codemadness.org>2020-02-02 22:56:51 +0100
commit26cdfebf31f024e331429e482b1ee342708888e3 (patch)
treec6c0bee9676b4192ece595fad7381363a563af6e /x.c
parentcd785755f2e3e3305c7d2556a04423a40bce060a (diff)
downloadst-patched-26cdfebf31f024e331429e482b1ee342708888e3.tar.bz2
st-patched-26cdfebf31f024e331429e482b1ee342708888e3.tar.xz
st-patched-26cdfebf31f024e331429e482b1ee342708888e3.zip
x: fix XIM handling
Do not try to set specific IM method, let the user specify it with XMODIFIERS. If the requested method is not available or opening fails, fallback to the default input handler and register a handler on the new IM server availability signal. Do the same when the input server is closed and (re)started.
Diffstat (limited to 'x.c')
-rw-r--r--x.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/x.c b/x.c
index b488617..1f62129 100644
--- a/x.c
+++ b/x.c
@@ -146,9 +146,10 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
146static void xdrawglyph(Glyph, int, int); 146static void xdrawglyph(Glyph, int, int);
147static void xclear(int, int, int, int); 147static void xclear(int, int, int, int);
148static int xgeommasktogravity(int); 148static int xgeommasktogravity(int);
149static void ximopen(Display *); 149static int ximopen(Display *);
150static void ximinstantiate(Display *, XPointer, XPointer); 150static void ximinstantiate(Display *, XPointer, XPointer);
151static void ximdestroy(XIM, XPointer, XPointer); 151static void ximdestroy(XIM, XPointer, XPointer);
152static int xicdestroy(XIC, XPointer, XPointer);
152static void xinit(int, int); 153static void xinit(int, int);
153static void cresize(int, int); 154static void cresize(int, int);
154static void xresize(int, int); 155static void xresize(int, int);
@@ -1025,48 +1026,61 @@ xunloadfonts(void)
1025 xunloadfont(&dc.ibfont); 1026 xunloadfont(&dc.ibfont);
1026} 1027}
1027 1028
1028void 1029int
1029ximopen(Display *dpy) 1030ximopen(Display *dpy)
1030{ 1031{
1031 XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy }; 1032 XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
1033 XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy };
1032 1034
1033 if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { 1035 xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
1034 XSetLocaleModifiers("@im=local"); 1036 if (xw.ime.xim == NULL)
1035 if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { 1037 return 0;
1036 XSetLocaleModifiers("@im="); 1038
1037 if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) 1039 if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
1038 die("XOpenIM failed. Could not open input device.\n"); 1040 fprintf(stderr, "XSetIMValues: "
1039 } 1041 "Could not set XNDestroyCallback.\n");
1040 }
1041 if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &destroy, NULL) != NULL)
1042 die("XSetIMValues failed. Could not set input method value.\n");
1043 xw.xic = XCreateIC(xw.ime.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
1044 XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL);
1045 if (xw.xic == NULL)
1046 die("XCreateIC failed. Could not obtain input method.\n");
1047 1042
1048 xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, 1043 xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
1049 NULL); 1044 NULL);
1045
1046 if (xw.ime.xic == NULL) {
1047 xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle,
1048 XIMPreeditNothing | XIMStatusNothing,
1049 XNClientWindow, xw.win,
1050 XNFocusWindow, xw.win,
1051 XNDestroyCallback, &icdestroy,
1052 NULL);
1053 }
1054 if (xw.ime.xic == NULL)
1055 fprintf(stderr, "XCreateIC: Could not create input context.\n");
1056
1057 return 1;
1050} 1058}
1051 1059
1052void 1060void
1053ximinstantiate(Display *dpy, XPointer client, XPointer call) 1061ximinstantiate(Display *dpy, XPointer client, XPointer call)
1054{ 1062{
1055 ximopen(dpy); 1063 if (ximopen(dpy))
1056 XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, 1064 XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
1057 ximinstantiate, NULL); 1065 ximinstantiate, NULL);
1058} 1066}
1059 1067
1060void 1068void
1061ximdestroy(XIM xim, XPointer client, XPointer call) 1069ximdestroy(XIM xim, XPointer client, XPointer call)
1062{ 1070{
1063 xw.ime.xim = NULL; 1071 xw.ime.xim = NULL;
1064 xw.ime.xic = NULL;
1065 XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, 1072 XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
1066 ximinstantiate, NULL); 1073 ximinstantiate, NULL);
1067 XFree(xw.ime.spotlist); 1074 XFree(xw.ime.spotlist);
1068} 1075}
1069 1076
1077int
1078xicdestroy(XIC xim, XPointer client, XPointer call)
1079{
1080 xw.ime.xic = NULL;
1081 return 1;
1082}
1083
1070void 1084void
1071xinit(int cols, int rows) 1085xinit(int cols, int rows)
1072{ 1086{
@@ -1132,7 +1146,10 @@ xinit(int cols, int rows)
1132 xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); 1146 xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
1133 1147
1134 /* input methods */ 1148 /* input methods */
1135 ximopen(xw.dpy); 1149 if (!ximopen(xw.dpy)) {
1150 XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
1151 ximinstantiate, NULL);
1152 }
1136 1153
1137 /* white cursor, black outline */ 1154 /* white cursor, black outline */
1138 cursor = XCreateFontCursor(xw.dpy, mouseshape); 1155 cursor = XCreateFontCursor(xw.dpy, mouseshape);
@@ -1765,7 +1782,10 @@ kpress(XEvent *ev)
1765 if (IS_SET(MODE_KBDLOCK)) 1782 if (IS_SET(MODE_KBDLOCK))
1766 return; 1783 return;
1767 1784
1768 len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); 1785 if (xw.ime.xic)
1786 len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
1787 else
1788 len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
1769 /* 1. shortcuts */ 1789 /* 1. shortcuts */
1770 for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { 1790 for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
1771 if (ksym == bp->keysym && match(bp->mod, e->state)) { 1791 if (ksym == bp->keysym && match(bp->mod, e->state)) {