X-Git-Url: https://git.xinqibao.xyz/dmenu.git/blobdiff_plain/e2a280541eab62717d6a9a72d047c832e5cb1edc..a9a3836861bd23387b5a51d6f6ac23377e98e26f:/dmenu.c diff --git a/dmenu.c b/dmenu.c index 5e9c367..d06bea1 100644 --- a/dmenu.c +++ b/dmenu.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -101,17 +102,6 @@ cleanup(void) XCloseDisplay(dpy); } -static char * -cistrstr(const char *s, const char *sub) -{ - size_t len; - - for (len = strlen(sub); *s; s++) - if (!strncasecmp(s, sub, len)) - return (char *)s; - return NULL; -} - static int drawitem(struct item *item, int x, int y, int w) { @@ -144,7 +134,7 @@ drawmenu(void) drw_setscheme(drw, scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - drw_font_getexts(drw->fonts, text, cursor, &curpos, NULL); + curpos = TEXTW(text) - TEXTW(&text[cursor]); if ((curpos += lrpad / 2 - 1) < w) { drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); @@ -308,13 +298,21 @@ keypress(XKeyEvent *ev) { char buf[32]; int len; - KeySym ksym = NoSymbol; + KeySym ksym; Status status; len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - if (status == XBufferOverflow) + switch (status) { + default: /* XLookupNone, XBufferOverflow */ return; - if (ev->state & ControlMask) + case XLookupChars: + goto insert; + case XLookupKeySym: + case XLookupBoth: + break; + } + + if (ev->state & ControlMask) { switch(ksym) { case XK_a: ksym = XK_Home; break; case XK_b: ksym = XK_Left; break; @@ -351,13 +349,13 @@ keypress(XKeyEvent *ev) utf8, utf8, win, CurrentTime); return; case XK_Left: + case XK_KP_Left: movewordedge(-1); - ksym = NoSymbol; - break; + goto draw; case XK_Right: + case XK_KP_Right: movewordedge(+1); - ksym = NoSymbol; - break; + goto draw; case XK_Return: case XK_KP_Enter: break; @@ -367,16 +365,14 @@ keypress(XKeyEvent *ev) default: return; } - else if (ev->state & Mod1Mask) + } else if (ev->state & Mod1Mask) { switch(ksym) { case XK_b: movewordedge(-1); - ksym = NoSymbol; - break; + goto draw; case XK_f: movewordedge(+1); - ksym = NoSymbol; - break; + goto draw; case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; case XK_h: ksym = XK_Up; break; @@ -386,14 +382,16 @@ keypress(XKeyEvent *ev) default: return; } + } + switch(ksym) { default: +insert: if (!iscntrl(*buf)) insert(buf, len); break; - case NoSymbol: - break; case XK_Delete: + case XK_KP_Delete: if (text[cursor] == '\0') return; cursor = nextrune(+1); @@ -404,6 +402,7 @@ keypress(XKeyEvent *ev) insert(NULL, nextrune(-1) - cursor); break; case XK_End: + case XK_KP_End: if (text[cursor] != '\0') { cursor = strlen(text); break; @@ -423,6 +422,7 @@ keypress(XKeyEvent *ev) cleanup(); exit(1); case XK_Home: + case XK_KP_Home: if (sel == matches) { cursor = 0; break; @@ -431,6 +431,7 @@ keypress(XKeyEvent *ev) calcoffsets(); break; case XK_Left: + case XK_KP_Left: if (cursor > 0 && (!sel || !sel->left || lines > 0)) { cursor = nextrune(-1); break; @@ -439,18 +440,21 @@ keypress(XKeyEvent *ev) return; /* fallthrough */ case XK_Up: + case XK_KP_Up: if (sel && sel->left && (sel = sel->left)->right == curr) { curr = prev; calcoffsets(); } break; case XK_Next: + case XK_KP_Next: if (!next) return; sel = curr = next; calcoffsets(); break; case XK_Prior: + case XK_KP_Prior: if (!prev) return; sel = curr = prev; @@ -467,6 +471,7 @@ keypress(XKeyEvent *ev) sel->out = 1; break; case XK_Right: + case XK_KP_Right: if (text[cursor] != '\0') { cursor = nextrune(+1); break; @@ -475,6 +480,7 @@ keypress(XKeyEvent *ev) return; /* fallthrough */ case XK_Down: + case XK_KP_Down: if (sel && sel->right && (sel = sel->right) == next) { curr = next; calcoffsets(); @@ -489,6 +495,8 @@ keypress(XKeyEvent *ev) match(); break; } + +draw: drawmenu(); } @@ -548,6 +556,11 @@ run(void) if (XFilterEvent(&ev, win)) continue; switch(ev.type) { + case DestroyNotify: + if (ev.xdestroywindow.window != win) + break; + cleanup(); + exit(1); case Expose: if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); @@ -651,14 +664,17 @@ setup(void) CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); XSetClassHint(dpy, win, &ch); - /* open input methods */ - xim = XOpenIM(dpy, NULL, NULL, NULL); + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); if (embed) { - XSelectInput(dpy, parentwin, FocusChangeMask); + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { for (i = 0; i < du && dws[i] != win; ++i) XSelectInput(dpy, dws[i], FocusChangeMask); @@ -695,7 +711,7 @@ main(int argc, char *argv[]) fast = 1; else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; - fstrstr = cistrstr; + fstrstr = strcasestr; } else if (i + 1 == argc) usage(); /* these options take one argument */ @@ -736,7 +752,12 @@ main(int argc, char *argv[]) die("no fonts could be loaded."); lrpad = drw->fonts->h; - if (fast) { +#ifdef __OpenBSD__ + if (pledge("stdio rpath", NULL) == -1) + die("pledge"); +#endif + + if (fast && !isatty(0)) { grabkeyboard(); readstdin(); } else {