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.
This commit is contained in:
parent
cd785755f2
commit
26cdfebf31
68
x.c
68
x.c
|
@ -146,9 +146,10 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
|
||||||
static void xdrawglyph(Glyph, int, int);
|
static void xdrawglyph(Glyph, int, int);
|
||||||
static void xclear(int, int, int, int);
|
static void xclear(int, int, int, int);
|
||||||
static int xgeommasktogravity(int);
|
static int xgeommasktogravity(int);
|
||||||
static void ximopen(Display *);
|
static int ximopen(Display *);
|
||||||
static void ximinstantiate(Display *, XPointer, XPointer);
|
static void ximinstantiate(Display *, XPointer, XPointer);
|
||||||
static void ximdestroy(XIM, XPointer, XPointer);
|
static void ximdestroy(XIM, XPointer, XPointer);
|
||||||
|
static int xicdestroy(XIC, XPointer, XPointer);
|
||||||
static void xinit(int, int);
|
static void xinit(int, int);
|
||||||
static void cresize(int, int);
|
static void cresize(int, int);
|
||||||
static void xresize(int, int);
|
static void xresize(int, int);
|
||||||
|
@ -1025,48 +1026,61 @@ xunloadfonts(void)
|
||||||
xunloadfont(&dc.ibfont);
|
xunloadfont(&dc.ibfont);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
ximopen(Display *dpy)
|
ximopen(Display *dpy)
|
||||||
{
|
{
|
||||||
XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy };
|
XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
|
||||||
|
XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy };
|
||||||
|
|
||||||
if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
|
xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
|
||||||
XSetLocaleModifiers("@im=local");
|
if (xw.ime.xim == NULL)
|
||||||
if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
|
return 0;
|
||||||
XSetLocaleModifiers("@im=");
|
|
||||||
if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL)
|
if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
|
||||||
die("XOpenIM failed. Could not open input device.\n");
|
fprintf(stderr, "XSetIMValues: "
|
||||||
}
|
"Could not set XNDestroyCallback.\n");
|
||||||
}
|
|
||||||
if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &destroy, NULL) != NULL)
|
|
||||||
die("XSetIMValues failed. Could not set input method value.\n");
|
|
||||||
xw.xic = XCreateIC(xw.ime.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
|
||||||
XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL);
|
|
||||||
if (xw.xic == NULL)
|
|
||||||
die("XCreateIC failed. Could not obtain input method.\n");
|
|
||||||
|
|
||||||
xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
|
xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
if (xw.ime.xic == NULL) {
|
||||||
|
xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle,
|
||||||
|
XIMPreeditNothing | XIMStatusNothing,
|
||||||
|
XNClientWindow, xw.win,
|
||||||
|
XNFocusWindow, xw.win,
|
||||||
|
XNDestroyCallback, &icdestroy,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
if (xw.ime.xic == NULL)
|
||||||
|
fprintf(stderr, "XCreateIC: Could not create input context.\n");
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ximinstantiate(Display *dpy, XPointer client, XPointer call)
|
ximinstantiate(Display *dpy, XPointer client, XPointer call)
|
||||||
{
|
{
|
||||||
ximopen(dpy);
|
if (ximopen(dpy))
|
||||||
XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||||
ximinstantiate, NULL);
|
ximinstantiate, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ximdestroy(XIM xim, XPointer client, XPointer call)
|
ximdestroy(XIM xim, XPointer client, XPointer call)
|
||||||
{
|
{
|
||||||
xw.ime.xim = NULL;
|
xw.ime.xim = NULL;
|
||||||
xw.ime.xic = NULL;
|
|
||||||
XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||||
ximinstantiate, NULL);
|
ximinstantiate, NULL);
|
||||||
XFree(xw.ime.spotlist);
|
XFree(xw.ime.spotlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xicdestroy(XIC xim, XPointer client, XPointer call)
|
||||||
|
{
|
||||||
|
xw.ime.xic = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xinit(int cols, int rows)
|
xinit(int cols, int rows)
|
||||||
{
|
{
|
||||||
|
@ -1132,7 +1146,10 @@ xinit(int cols, int rows)
|
||||||
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
|
||||||
|
|
||||||
/* input methods */
|
/* input methods */
|
||||||
ximopen(xw.dpy);
|
if (!ximopen(xw.dpy)) {
|
||||||
|
XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
|
||||||
|
ximinstantiate, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* white cursor, black outline */
|
/* white cursor, black outline */
|
||||||
cursor = XCreateFontCursor(xw.dpy, mouseshape);
|
cursor = XCreateFontCursor(xw.dpy, mouseshape);
|
||||||
|
@ -1765,7 +1782,10 @@ kpress(XEvent *ev)
|
||||||
if (IS_SET(MODE_KBDLOCK))
|
if (IS_SET(MODE_KBDLOCK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
|
if (xw.ime.xic)
|
||||||
|
len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
|
||||||
|
else
|
||||||
|
len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
|
||||||
/* 1. shortcuts */
|
/* 1. shortcuts */
|
||||||
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
|
for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
|
||||||
if (ksym == bp->keysym && match(bp->mod, e->state)) {
|
if (ksym == bp->keysym && match(bp->mod, e->state)) {
|
||||||
|
|
Loading…
Reference in a new issue