referred to LICENSE file
[dmenu.git] / main.c
diff --git a/main.c b/main.c
index 8b24bb0..9c10958 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,7 +1,4 @@
-/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
- * (C)opyright MMVI-MMVII Sander van Dijk <a dot h dot vandijk at gmail dot com>
- * See LICENSE file for license details.
- */
+/* See LICENSE file for copyright and license details. */
 #include "dmenu.h"
 #include <ctype.h>
 #include <locale.h>
@@ -108,8 +105,21 @@ drawmenu(void) {
        XFlush(dpy);
 }
 
+static Bool
+grabkeyboard(void) {
+       unsigned int len;
+
+       for(len = 1000; len; len--) {
+               if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
+                       == GrabSuccess)
+                       break;
+               usleep(1000);
+       }
+       return len > 0;
+}
+
 static unsigned long
-getcolor(const char *colstr) {
+initcolor(const char *colstr) {
        Colormap cmap = DefaultColormap(dpy, screen);
        XColor color;
 
@@ -119,10 +129,12 @@ getcolor(const char *colstr) {
 }
 
 static void
-setfont(const char *fontstr) {
+initfont(const char *fontstr) {
        char *def, **missing;
        int i, n;
 
+       if(!fontstr || fontstr[0] == '\0')
+               eprint("error, cannot load font: '%s'\n", fontstr);
        missing = NULL;
        if(dc.font.set)
                XFreeFontSet(dpy, dc.font.set);
@@ -196,13 +208,20 @@ match(char *pattern) {
 static void
 kpress(XKeyEvent * e) {
        char buf[32];
-       int i, num, prev_nitem;
+       int i, num;
        unsigned int len;
        KeySym ksym;
 
        len = strlen(text);
        buf[0] = 0;
        num = XLookupString(e, buf, sizeof buf, &ksym, 0);
+       if(IsKeypadKey(ksym)) { 
+               if(ksym == XK_KP_Enter) {
+                       ksym = XK_Return;
+               } else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) {
+                       ksym = (ksym - XK_KP_0) + XK_0;
+               }
+       }
        if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
                        || IsMiscFunctionKey(ksym) || IsPFKey(ksym)
                        || IsPrivateKeypadKey(ksym))
@@ -282,12 +301,8 @@ kpress(XKeyEvent * e) {
                }
                break;
        case XK_BackSpace:
-               if((i = len)) {
-                       prev_nitem = nitem;
-                       do {
-                               text[--i] = 0;
-                               match(text);
-                       } while(i && nitem && prev_nitem == nitem);
+               if(len) {
+                       text[--len] = 0;
                        match(text);
                }
                break;
@@ -418,35 +433,31 @@ main(int argc, char *argv[]) {
        XModifierKeymap *modmap;
        XSetWindowAttributes wa;
 
-       if(isatty(STDIN_FILENO)) {
-               fputs("error: dmenu can't run in an interactive shell\n", stdout);
-               usage();
-       }
        /* command line args */
        for(i = 1; i < argc; i++)
-               if(!strncmp(argv[i], "-b", 3)) {
+               if(!strcmp(argv[i], "-b")) {
                        bottom = True;
                }
-               else if(!strncmp(argv[i], "-fn", 4)) {
+               else if(!strcmp(argv[i], "-fn")) {
                        if(++i < argc) font = argv[i];
                }
-               else if(!strncmp(argv[i], "-nb", 4)) {
+               else if(!strcmp(argv[i], "-nb")) {
                        if(++i < argc) normbg = argv[i];
                }
-               else if(!strncmp(argv[i], "-nf", 4)) {
+               else if(!strcmp(argv[i], "-nf")) {
                        if(++i < argc) normfg = argv[i];
                }
-               else if(!strncmp(argv[i], "-p", 3)) {
+               else if(!strcmp(argv[i], "-p")) {
                        if(++i < argc) prompt = argv[i];
                }
-               else if(!strncmp(argv[i], "-sb", 4)) {
+               else if(!strcmp(argv[i], "-sb")) {
                        if(++i < argc) selbg = argv[i];
                }
-               else if(!strncmp(argv[i], "-sf", 4)) {
+               else if(!strcmp(argv[i], "-sf")) {
                        if(++i < argc) selfg = argv[i];
                }
-               else if(!strncmp(argv[i], "-v", 3))
-                       eprint("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n");
+               else if(!strcmp(argv[i], "-v"))
+                       eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk\n");
                else
                        usage();
        setlocale(LC_CTYPE, "");
@@ -455,10 +466,14 @@ main(int argc, char *argv[]) {
                eprint("dmenu: cannot open display\n");
        screen = DefaultScreen(dpy);
        root = RootWindow(dpy, screen);
-       while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
-                        GrabModeAsync, CurrentTime) != GrabSuccess)
-               usleep(1000);
-       maxname = readstdin();
+       if(isatty(STDIN_FILENO)) {
+               maxname = readstdin();
+               running = grabkeyboard();
+       }
+       else { /* prevent keypress loss */
+               running = grabkeyboard();
+               maxname = readstdin();
+       }
        /* init modifier map */
        modmap = XGetModifierMapping(dpy);
        for (i = 0; i < 8; i++) {
@@ -470,11 +485,11 @@ main(int argc, char *argv[]) {
        }
        XFreeModifiermap(modmap);
        /* style */
-       dc.norm[ColBG] = getcolor(normbg);
-       dc.norm[ColFG] = getcolor(normfg);
-       dc.sel[ColBG] = getcolor(selbg);
-       dc.sel[ColFG] = getcolor(selfg);
-       setfont(font);
+       dc.norm[ColBG] = initcolor(normbg);
+       dc.norm[ColFG] = initcolor(normfg);
+       dc.sel[ColBG] = initcolor(selbg);
+       dc.sel[ColFG] = initcolor(selfg);
+       initfont(font);
        /* menu window */
        wa.override_redirect = 1;
        wa.background_pixmap = ParentRelative;
@@ -490,6 +505,8 @@ main(int argc, char *argv[]) {
        dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen));
        dc.gc = XCreateGC(dpy, root, 0, 0);
        XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+       if(!dc.font.set)
+               XSetFont(dpy, dc.gc, dc.font.xfont->fid);
        if(maxname)
                cmdw = textw(maxname);
        if(cmdw > mw / 3)