X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=dmenu.c;h=65f25ce576e819421da9320afd7808c730e84ab4;hb=db6093f6ec1bb884f7540f2512935b5254750b30;hp=eae56850e37d6cf78b570a46b1f5abe57e3df563;hpb=1cabeda5505dcc35d4d2ca2a09151a7c449fb401;p=dmenu.git diff --git a/dmenu.c b/dmenu.c index eae5685..65f25ce 100644 --- a/dmenu.c +++ b/dmenu.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -144,7 +145,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); @@ -287,18 +288,42 @@ nextrune(int inc) return n; } +static void +movewordedge(int dir) +{ + if (dir < 0) { /* move cursor to the start of the word*/ + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + } else { /* move cursor to the end of the word */ + while (text[cursor] && strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + while (text[cursor] && !strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + } +} + static void 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; @@ -334,6 +359,12 @@ keypress(XKeyEvent *ev) XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + case XK_Left: + movewordedge(-1); + goto draw; + case XK_Right: + movewordedge(+1); + goto draw; case XK_Return: case XK_KP_Enter: break; @@ -343,8 +374,14 @@ keypress(XKeyEvent *ev) default: return; } - else if (ev->state & Mod1Mask) + } else if (ev->state & Mod1Mask) { switch(ksym) { + case XK_b: + movewordedge(-1); + goto draw; + case XK_f: + movewordedge(+1); + goto draw; case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; case XK_h: ksym = XK_Up; break; @@ -354,8 +391,11 @@ keypress(XKeyEvent *ev) default: return; } + } + switch(ksym) { default: +insert: if (!iscntrl(*buf)) insert(buf, len); break; @@ -455,6 +495,8 @@ keypress(XKeyEvent *ev) match(); break; } + +draw: drawmenu(); } @@ -514,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); @@ -541,7 +588,7 @@ run(void) static void setup(void) { - int x, y, i = 0; + int x, y, i, j; unsigned int du; XSetWindowAttributes swa; XIM xim; @@ -551,9 +598,8 @@ setup(void) #ifdef XINERAMA XineramaScreenInfo *info; Window pw; - int a, j, di, n, area = 0; + int a, di, n, area = 0; #endif - /* init appearance */ for (j = 0; j < SchemeLast; j++) scheme[j] = drw_scm_create(drw, colors[j], 2); @@ -566,6 +612,7 @@ setup(void) lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA + i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); if (mon >= 0 && mon < n) @@ -617,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); @@ -702,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 {