# st

Unnamed repository; edit this file 'description' to name the repository.

| Log | Files | Refs | README | LICENSE

    commit 26cdfebf31f024e331429e482b1ee342708888e3
    parent cd785755f2e3e3305c7d2556a04423a40bce060a
    Author: Quentin Rameau <quinq@fifth.space>
    Date:   Sun,  2 Feb 2020 21:47:19 +0100

    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:
    Mx.c | 68++++++++++++++++++++++++++++++++++++++++++++------------------------

    1 file changed, 44 insertions(+), 24 deletions(-)
    diff --git a/x.c b/x.c
    @@ -146,9 +146,10 @@ 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 int ximopen(Display *);
     static void ximinstantiate(Display *, XPointer, XPointer);
     static void ximdestroy(XIM, XPointer, XPointer);
    +static int xicdestroy(XIC, XPointer, XPointer);
     static void xinit(int, int);
     static void cresize(int, int);
     static void xresize(int, int);
    @@ -1025,48 +1026,61 @@ xunloadfonts(void)
     	xunloadfont(&dc.ibfont);
     }

    -void
    +int
     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) {
    -		XSetLocaleModifiers("@im=local");
    -		if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
    -			XSetLocaleModifiers("@im=");
    -			if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL)
    -				die("XOpenIM failed. Could not open input device.\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.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
    +	if (xw.ime.xim == NULL)
    +		return 0;
    +
    +	if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
    +		fprintf(stderr, "XSetIMValues: "
    +		                "Could not set XNDestroyCallback.\n");

     	xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
     	                                      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
     ximinstantiate(Display *dpy, XPointer client, XPointer call)
     {
    -	ximopen(dpy);
    -	XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
    -					ximinstantiate, NULL);
    +	if (ximopen(dpy))
    +		XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
    +		                                 ximinstantiate, NULL);
     }

     void
     ximdestroy(XIM xim, XPointer client, XPointer call)
     {
     	xw.ime.xim = NULL;
    -	xw.ime.xic = NULL;
     	XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
    -					ximinstantiate, NULL);
    +	                               ximinstantiate, NULL);
     	XFree(xw.ime.spotlist);
     }

    +int
    +xicdestroy(XIC xim, XPointer client, XPointer call)
    +{
    +	xw.ime.xic = NULL;
    +	return 1;
    +}
    +
     void
     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);

     	/* input methods */
    -	ximopen(xw.dpy);
    +	if (!ximopen(xw.dpy)) {
    +		XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
    +	                                       ximinstantiate, NULL);
    +	}

     	/* white cursor, black outline */
     	cursor = XCreateFontCursor(xw.dpy, mouseshape);
    @@ -1765,7 +1782,10 @@ kpress(XEvent *ev)
     	if (IS_SET(MODE_KBDLOCK))
     		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 */
     	for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
     		if (ksym == bp->keysym && match(bp->mod, e->state)) {