dmenu-nihal

My personal build of dmenu
git clone git://nihaljere.xyz/dmenu-nihal
Log | Files | Refs | README | LICENSE

commit cdb914bc2b986eeff409315148d59b589551583f
parent 20c7db628e315acb77a8e67ace7710253dbee6f8
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Thu,  2 Jul 2020 20:39:57 -0500

Merge branch 'password'

Diffstat:
Mdmenu.1 | 5++++-
Mdmenu.c | 40+++++++++++++++++++++++++++-------------
2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/dmenu.1 b/dmenu.1 @@ -3,7 +3,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-bfiv ] +.RB [ \-bfivP ] .RB [ \-l .IR lines ] .RB [ \-m @@ -50,6 +50,9 @@ is faster, but will lock up X until stdin reaches end\-of\-file. .B \-i dmenu matches menu items case insensitively. .TP +.B \-P +dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored. +.TP .BI \-l " lines" dmenu lists items vertically, with the given number of lines. .TP diff --git a/dmenu.c b/dmenu.c @@ -22,9 +22,9 @@ /* macros */ #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ @@ -39,7 +39,7 @@ struct item { static char text[BUFSIZ] = ""; static char *embed; static int bh, mw, mh; -static int inputw = 0, promptw; +static int inputw = 0, promptw, passwd = 0; static int lrpad; /* sum of left and right padding */ static size_t cursor; static struct item *items = NULL; @@ -143,6 +143,7 @@ drawmenu(void) unsigned int curpos; struct item *item; int x = 0, y = 0, fh = drw->fonts->h, w; + char *censort; drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, 0, 0, mw, mh, 1, 1); @@ -154,7 +155,12 @@ drawmenu(void) /* draw input field */ w = (lines > 0 || !matches) ? mw - x : inputw; drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); + if (passwd) { + censort = ecalloc(1, sizeof(text)); + memset(censort, '.', strlen(text)); + drw_text(drw, x, 0, w, bh, lrpad / 2, censort, 0); + free(censort); + } else drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); curpos = TEXTW(text) - TEXTW(&text[cursor]); if ((curpos += lrpad / 2 - 1) < w) { @@ -214,7 +220,7 @@ grabkeyboard(void) /* try to grab keyboard, we may have to wait for another process to ungrab */ for (i = 0; i < 1000; i++) { if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) + GrabModeAsync, CurrentTime) == GrabSuccess) return; nanosleep(&ts, NULL); } @@ -426,7 +432,7 @@ keypress(XKeyEvent *ev) case XK_c: ksym = XK_Escape; break; case XK_d: ksym = XK_Delete; break; case XK_e: ksym = XK_End; break; - case XK_f: ksym = XK_Right; break; + case XK_f: ksym = XK_Right; break; case XK_g: ksym = XK_Escape; break; case XK_h: ksym = XK_BackSpace; break; case XK_i: ksym = XK_Tab; break; @@ -453,7 +459,7 @@ keypress(XKeyEvent *ev) case XK_y: /* paste selection */ case XK_Y: XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); + utf8, utf8, win, CurrentTime); return; case XK_Left: movewordedge(-1); @@ -606,8 +612,8 @@ paste(void) /* we have been given the current selection, now insert it into input */ if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p) - == Success && p) { + utf8, &da, &di, &dl, &dl, (unsigned char **)&p) + == Success && p) { insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); XFree(p); } @@ -621,6 +627,11 @@ readstdin(void) size_t i, imax = 0, size = 0; unsigned int tmpmax = 0; + if (passwd) { + inputw = lines = 0; + return; + } + /* read each line from stdin and add it to the item list */ for (i = 0; fgets(buf, sizeof buf, stdin); i++) { if (i + 1 >= size / sizeof *items) @@ -762,6 +773,7 @@ setup(void) y = topbar ? 0 : wa.height - mh; mw = wa.width; } + } inputw = MIN(inputw, mw/3); match(); @@ -782,7 +794,7 @@ setup(void) die("XOpenIM failed: could not open input device"); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, win, XNFocusWindow, win, NULL); + XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); if (embed) { @@ -829,7 +841,9 @@ main(int argc, char *argv[]) else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; - } else if (i + 1 == argc) + } else if (!strcmp(argv[i], "-P")) /* is the input a password */ + passwd = 1; + else if (i + 1 == argc) usage(); /* these options take one argument */ else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ @@ -867,7 +881,7 @@ main(int argc, char *argv[]) parentwin = root; if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", - parentwin); + parentwin); drw = drw_create(dpy, screen, root, wa.width, wa.height); if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded.");