X-Git-Url: https://git.danieliu.xyz/?p=st.git;a=blobdiff_plain;f=x.c;h=5af6e4ddbb5c9e57d3b8e591e7e7c270b7ecba66;hp=8f570c25ef7e45ac40bb776f2fc84e0ed6615d02;hb=2cb539142b97bd2a5c1a322fd7c063c6afb67c9b;hpb=d2b75db8d7519a20af8bf09e9c205507f9ff828c diff --git a/x.c b/x.c index 8f570c2..5af6e4d 100644 --- a/x.c +++ b/x.c @@ -94,8 +94,12 @@ typedef struct { Drawable buf; GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ Atom xembed, wmdeletewin, netwmname, netwmpid; - XIM xim; - XIC xic; + struct { + XIM xim; + XIC xic; + XPoint spot; + XVaNestedList spotlist; + } ime; Draw draw; Visual *vis; XSetWindowAttributes attrs; @@ -426,7 +430,8 @@ mouseaction(XEvent *e, uint release) for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { if (ms->release == release && ms->button == e->xbutton.button && - match(ms->mod, e->xbutton.state & ~forcemousemod)) { + (match(ms->mod, e->xbutton.state) || /* exact or forced */ + match(ms->mod, e->xbutton.state & ~forcemousemod))) { ms->func(&(ms->arg)); return 1; } @@ -1025,20 +1030,23 @@ ximopen(Display *dpy) { XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy }; - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { + if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { XSetLocaleModifiers("@im=local"); - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { + if ((xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { XSetLocaleModifiers("@im="); - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) + if ((xw.ime.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) + if (XSetIMValues(xw.ime.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); + 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, + NULL); } void @@ -1052,9 +1060,10 @@ ximinstantiate(Display *dpy, XPointer client, XPointer call) void ximdestroy(XIM xim, XPointer client, XPointer call) { - xw.xim = NULL; + xw.ime.xim = NULL; XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, ximinstantiate, NULL); + XFree(xw.ime.spotlist); } void @@ -1153,8 +1162,8 @@ xinit(int cols, int rows) win.mode = MODE_NUMLOCK; resettitle(); - XMapWindow(xw.dpy, xw.win); xhints(); + XMapWindow(xw.dpy, xw.win); XSync(xw.dpy, False); clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); @@ -1600,11 +1609,13 @@ xfinishdraw(void) void xximspot(int x, int y) { - XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch }; - XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); + if (xw.ime.xic == NULL) + return; + + xw.ime.spot.x = borderpx + x * win.cw; + xw.ime.spot.y = borderpx + (y + 1) * win.ch; - XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL); - XFree(attr); + XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); } void @@ -1681,13 +1692,13 @@ focus(XEvent *ev) return; if (ev->type == FocusIn) { - XSetICFocus(xw.xic); + XSetICFocus(xw.ime.xic); win.mode |= MODE_FOCUSED; xseturgency(0); if (IS_SET(MODE_FOCUS)) ttywrite("\033[I", 3, 0); } else { - XUnsetICFocus(xw.xic); + XUnsetICFocus(xw.ime.xic); win.mode &= ~MODE_FOCUSED; if (IS_SET(MODE_FOCUS)) ttywrite("\033[O", 3, 0); @@ -1742,7 +1753,7 @@ kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym ksym; - char buf[32], *customkey; + char buf[64], *customkey; int len; Rune c; Status status; @@ -1751,7 +1762,7 @@ kpress(XEvent *ev) if (IS_SET(MODE_KBDLOCK)) return; - len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status); + len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); /* 1. shortcuts */ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { if (ksym == bp->keysym && match(bp->mod, e->state)) {