patches applied

This commit is contained in:
Luca Bilke 2023-02-09 20:03:46 +01:00
parent 448bc746c4
commit 922d6eabb4
9 changed files with 793 additions and 25 deletions

View File

@ -2,6 +2,7 @@
/* Default settings; can be overriden by command line. */ /* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
static const unsigned int alpha = 0xf0;
/* -fn option overrides fonts[0]; default X11 font or font set */ /* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = { static const char *fonts[] = {
"monospace:size=10" "monospace:size=10"
@ -13,6 +14,13 @@ static const char *colors[SchemeLast][2] = {
[SchemeSel] = { "#eeeeee", "#005577" }, [SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#00ffff" }, [SchemeOut] = { "#000000", "#00ffff" },
}; };
static const unsigned int alphas[SchemeLast][2] = {
[SchemeNorm] = { OPAQUE, alpha },
[SchemeSel] = { OPAQUE, alpha },
[SchemeOut] = { OPAQUE, alpha },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0; static unsigned int lines = 0;

23
config.h Normal file
View File

@ -0,0 +1,23 @@
/* See LICENSE file for copyright and license details. */
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"
};
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#00ffff" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
/*
* Characters not considered part of a word while deleting words
* for example: " /?\"&[]"
*/
static const char worddelimiters[] = " ";

200
dmenu.1 Normal file
View File

@ -0,0 +1,200 @@
.TH DMENU 1 dmenu\-VERSION
.SH NAME
dmenu \- dynamic menu
.SH SYNOPSIS
.B dmenu
.RB [ \-bfirvP ]
.RB [ \-l
.IR lines ]
.RB [ \-m
.IR monitor ]
.RB [ \-p
.IR prompt ]
.RB [ \-fn
.IR font ]
.RB [ \-nb
.IR color ]
.RB [ \-nf
.IR color ]
.RB [ \-sb
.IR color ]
.RB [ \-sf
.IR color ]
.RB [ \-w
.IR windowid ]
.P
.BR dmenu_run " ..."
.SH DESCRIPTION
.B dmenu
is a dynamic menu for X, which reads a list of newline\-separated items from
stdin. When the user selects an item and presses Return, their choice is printed
to stdout and dmenu terminates. Entering text will narrow the items to those
matching the tokens in the input.
.P
.B dmenu_run
is a script used by
.IR dwm (1)
which lists programs in the user's $PATH and runs the result in their $SHELL.
.SH OPTIONS
.TP
.B \-b
dmenu appears at the bottom of the screen.
.TP
.B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This
is faster, but will lock up X until stdin reaches end\-of\-file.
.TP
.B \-i
dmenu matches menu items case insensitively.
.TP
.B \-r
dmenu will reject any input which would result in no matching option left.
.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
.BI \-m " monitor"
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
from 0.
.TP
.BI \-p " prompt"
defines the prompt to be displayed to the left of the input field.
.TP
.BI \-fn " font"
defines the font or font set used.
.TP
.BI \-nb " color"
defines the normal background color.
.IR #RGB ,
.IR #RRGGBB ,
and X color names are supported.
.TP
.BI \-nf " color"
defines the normal foreground color.
.TP
.BI \-sb " color"
defines the selected background color.
.TP
.BI \-sf " color"
defines the selected foreground color.
.TP
.B \-v
prints version information to stdout, then exits.
.TP
.BI \-w " windowid"
embed into windowid.
.SH USAGE
dmenu is completely controlled by the keyboard. Items are selected using the
arrow keys, page up, page down, home, and end.
.TP
.B Tab
Copy the selected item to the input field.
.TP
.B Return
Confirm selection. Prints the selected item to stdout and exits, returning
success.
.TP
.B Ctrl-Return
Confirm selection. Prints the selected item to stdout and continues.
.TP
.B Shift\-Return
Confirm input. Prints the input text to stdout and exits, returning success.
.TP
.B Escape
Exit without selecting an item, returning failure.
.TP
.B Ctrl-Left
Move cursor to the start of the current word
.TP
.B Ctrl-Right
Move cursor to the end of the current word
.TP
.B C\-a
Home
.TP
.B C\-b
Left
.TP
.B C\-c
Escape
.TP
.B C\-d
Delete
.TP
.B C\-e
End
.TP
.B C\-f
Right
.TP
.B C\-g
Escape
.TP
.B C\-h
Backspace
.TP
.B C\-i
Tab
.TP
.B C\-j
Return
.TP
.B C\-J
Shift-Return
.TP
.B C\-k
Delete line right
.TP
.B C\-m
Return
.TP
.B C\-M
Shift-Return
.TP
.B C\-n
Down
.TP
.B C\-p
Up
.TP
.B C\-u
Delete line left
.TP
.B C\-w
Delete word left
.TP
.B C\-y
Paste from primary X selection
.TP
.B C\-Y
Paste from X clipboard
.TP
.B M\-b
Move cursor to the start of the current word
.TP
.B M\-f
Move cursor to the end of the current word
.TP
.B M\-g
Home
.TP
.B M\-G
End
.TP
.B M\-h
Up
.TP
.B M\-j
Page down
.TP
.B M\-k
Page up
.TP
.B M\-l
Down
.SH SEE ALSO
.IR dwm (1),
.IR stest (1)

100
dmenu.c
View File

@ -10,6 +10,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#ifdef XINERAMA #ifdef XINERAMA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
@ -25,6 +26,8 @@
#define LENGTH(X) (sizeof X / sizeof X[0]) #define LENGTH(X) (sizeof X / sizeof X[0])
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
#define OPAQUE 0xffU
/* enums */ /* enums */
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
@ -37,8 +40,9 @@ struct item {
static char text[BUFSIZ] = ""; static char text[BUFSIZ] = "";
static char *embed; static char *embed;
static int bh, mw, mh; 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 int lrpad; /* sum of left and right padding */
static int reject_no_match = 0;
static size_t cursor; static size_t cursor;
static struct item *items = NULL; static struct item *items = NULL;
static struct item *matches, *matchend; static struct item *matches, *matchend;
@ -53,10 +57,16 @@ static XIC xic;
static Drw *drw; static Drw *drw;
static Clr *scheme[SchemeLast]; static Clr *scheme[SchemeLast];
static int useargb = 0;
static Visual *visual;
static int depth;
static Colormap cmap;
#include "config.h" #include "config.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr; static char *(*fstrstr)(const char *, const char *) = strstr;
static void xinitvisual();
static unsigned int static unsigned int
textw_clamp(const char *str, unsigned int n) textw_clamp(const char *str, unsigned int n)
@ -149,6 +159,7 @@ drawmenu(void)
unsigned int curpos; unsigned int curpos;
struct item *item; struct item *item;
int x = 0, y = 0, w; int x = 0, y = 0, w;
char *censort;
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, 0, 0, mw, mh, 1, 1); drw_rect(drw, 0, 0, mw, mh, 1, 1);
@ -160,7 +171,12 @@ drawmenu(void)
/* draw input field */ /* draw input field */
w = (lines > 0 || !matches) ? mw - x : inputw; w = (lines > 0 || !matches) ? mw - x : inputw;
drw_setscheme(drw, scheme[SchemeNorm]); 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]); curpos = TEXTW(text) - TEXTW(&text[cursor]);
if ((curpos += lrpad / 2 - 1) < w) { if ((curpos += lrpad / 2 - 1) < w) {
@ -286,12 +302,26 @@ insert(const char *str, ssize_t n)
{ {
if (strlen(text) + n > sizeof text - 1) if (strlen(text) + n > sizeof text - 1)
return; return;
static char last[BUFSIZ] = "";
if(reject_no_match) {
/* store last text value in case we need to revert it */
memcpy(last, text, BUFSIZ);
}
/* move existing text out of the way, insert new text, and update cursor */ /* move existing text out of the way, insert new text, and update cursor */
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
if (n > 0) if (n > 0)
memcpy(&text[cursor], str, n); memcpy(&text[cursor], str, n);
cursor += n; cursor += n;
match(); match();
if(!matches && reject_no_match) {
/* revert to last text value if theres no match */
memcpy(text, last, BUFSIZ);
cursor -= n;
match();
}
} }
static size_t static size_t
@ -552,6 +582,11 @@ readstdin(void)
char *line = NULL; char *line = NULL;
size_t i, junk, itemsiz = 0; size_t i, junk, itemsiz = 0;
ssize_t len; ssize_t len;
if(passwd){
inputw = lines = 0;
return;
}
/* read each line from stdin and add it to the item list */ /* read each line from stdin and add it to the item list */
for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) { for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) {
@ -627,7 +662,7 @@ setup(void)
#endif #endif
/* init appearance */ /* init appearance */
for (j = 0; j < SchemeLast; j++) for (j = 0; j < SchemeLast; j++)
scheme[j] = drw_scm_create(drw, colors[j], 2); scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2);
clip = XInternAtom(dpy, "CLIPBOARD", False); clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False);
@ -665,6 +700,7 @@ setup(void)
x = info[i].x_org; x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh); y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
mw = info[i].width; mw = info[i].width;
XFree(info); XFree(info);
} else } else
#endif #endif
@ -682,11 +718,13 @@ setup(void)
/* create menu window */ /* create menu window */
swa.override_redirect = True; swa.override_redirect = True;
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; swa.background_pixel = 0;
swa.border_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
CopyFromParent, CopyFromParent, CopyFromParent, depth, CopyFromParent, visual,
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
XSetClassHint(dpy, win, &ch); XSetClassHint(dpy, win, &ch);
@ -714,7 +752,7 @@ setup(void)
static void static void
usage(void) usage(void)
{ {
die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" die("usage: dmenu [-bfirvP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]");
} }
@ -736,7 +774,11 @@ main(int argc, char *argv[])
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp; fstrncmp = strncasecmp;
fstrstr = cistrstr; fstrstr = cistrstr;
} else if (i + 1 == argc) } else if (!strcmp(argv[i], "-P")) /* is the input a password */
passwd = 1;
else if (!strcmp(argv[i], "-r")) /* reject input which results in no match */
reject_no_match = 1;
else if (i + 1 == argc)
usage(); usage();
/* these options take one argument */ /* these options take one argument */
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
@ -771,7 +813,8 @@ main(int argc, char *argv[])
if (!XGetWindowAttributes(dpy, parentwin, &wa)) if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx", die("could not get embedding window attributes: 0x%lx",
parentwin); parentwin);
drw = drw_create(dpy, screen, root, wa.width, wa.height); xinitvisual();
drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded."); die("no fonts could be loaded.");
lrpad = drw->fonts->h; lrpad = drw->fonts->h;
@ -793,3 +836,40 @@ main(int argc, char *argv[])
return 1; /* unreachable */ return 1; /* unreachable */
} }
void
xinitvisual()
{
XVisualInfo *infos;
XRenderPictFormat *fmt;
int nitems;
int i;
XVisualInfo tpl = {
.screen = screen,
.depth = 32,
.class = TrueColor
};
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
visual = NULL;
for(i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
visual = infos[i].visual;
depth = infos[i].depth;
cmap = XCreateColormap(dpy, root, visual, AllocNone);
useargb = 1;
break;
}
}
XFree(infos);
if (! visual) {
visual = DefaultVisual(dpy, screen);
depth = DefaultDepth(dpy, screen);
cmap = DefaultColormap(dpy, screen);
}
}

26
drw.c
View File

@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
} }
Drw * Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
{ {
Drw *drw = ecalloc(1, sizeof(Drw)); Drw *drw = ecalloc(1, sizeof(Drw));
@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
drw->root = root; drw->root = root;
drw->w = w; drw->w = w;
drw->h = h; drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->visual = visual;
drw->gc = XCreateGC(dpy, root, 0, NULL); drw->depth = depth;
drw->cmap = cmap;
drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw; return drw;
@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
drw->h = h; drw->h = h;
if (drw->drawable) if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable); XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
} }
void void
@ -181,21 +184,22 @@ drw_fontset_free(Fnt *font)
} }
void void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname) drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
{ {
if (!drw || !dest || !clrname) if (!drw || !dest || !clrname)
return; return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
DefaultColormap(drw->dpy, drw->screen),
clrname, dest)) clrname, dest))
die("error, cannot allocate color '%s'", clrname); die("error, cannot allocate color '%s'", clrname);
dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
} }
/* Wrapper to create color schemes. The caller has to call free(3) on the /* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */ * returned color scheme when done using it. */
Clr * Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
{ {
size_t i; size_t i;
Clr *ret; Clr *ret;
@ -205,7 +209,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
return NULL; return NULL;
for (i = 0; i < clrcount; i++) for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]); drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
return ret; return ret;
} }
@ -263,9 +267,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
} else { } else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable, d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad; x += lpad;
w -= lpad; w -= lpad;
} }

9
drw.h
View File

@ -20,6 +20,9 @@ typedef struct {
Display *dpy; Display *dpy;
int screen; int screen;
Window root; Window root;
Visual *visual;
unsigned int depth;
Colormap cmap;
Drawable drawable; Drawable drawable;
GC gc; GC gc;
Clr *scheme; Clr *scheme;
@ -27,7 +30,7 @@ typedef struct {
} Drw; } Drw;
/* Drawable abstraction */ /* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap);
void drw_resize(Drw *drw, unsigned int w, unsigned int h); void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw); void drw_free(Drw *drw);
@ -39,8 +42,8 @@ unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */ /* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
/* Cursor abstraction */ /* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape); Cur *drw_cur_create(Drw *drw, int shape);

View File

@ -0,0 +1,267 @@
diff --git a/config.def.h b/config.def.h
index 1edb647..697d511 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
+static const unsigned int alpha = 0xf0;
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"
@@ -13,6 +14,13 @@ static const char *colors[SchemeLast][2] = {
[SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#00ffff" },
};
+
+static const unsigned int alphas[SchemeLast][2] = {
+ [SchemeNorm] = { OPAQUE, alpha },
+ [SchemeSel] = { OPAQUE, alpha },
+ [SchemeOut] = { OPAQUE, alpha },
+};
+
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
diff --git a/dmenu.c b/dmenu.c
index 65f25ce..3e56e1a 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -10,6 +10,7 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
+#include <X11/Xproto.h>
#include <X11/Xutil.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
@@ -25,6 +26,8 @@
#define LENGTH(X) (sizeof X / sizeof X[0])
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define OPAQUE 0xffU
+
/* enums */
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
@@ -53,10 +56,16 @@ static XIC xic;
static Drw *drw;
static Clr *scheme[SchemeLast];
+static int useargb = 0;
+static Visual *visual;
+static int depth;
+static Colormap cmap;
+
#include "config.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr;
+static void xinitvisual();
static void
appenditem(struct item *item, struct item **list, struct item **last)
@@ -602,7 +611,7 @@ setup(void)
#endif
/* init appearance */
for (j = 0; j < SchemeLast; j++)
- scheme[j] = drw_scm_create(drw, colors[j], 2);
+ scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2);
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
@@ -640,6 +649,7 @@ setup(void)
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
mw = info[i].width;
+
XFree(info);
} else
#endif
@@ -657,11 +667,13 @@ setup(void)
/* create menu window */
swa.override_redirect = True;
- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ swa.background_pixel = 0;
+ swa.border_pixel = 0;
+ swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
+ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
+ depth, CopyFromParent, visual,
+ CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa);
XSetClassHint(dpy, win, &ch);
@@ -747,7 +759,8 @@ main(int argc, char *argv[])
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
- drw = drw_create(dpy, screen, root, wa.width, wa.height);
+ xinitvisual();
+ drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
@@ -769,3 +782,40 @@ main(int argc, char *argv[])
return 1; /* unreachable */
}
+
+ void
+xinitvisual()
+{
+ XVisualInfo *infos;
+ XRenderPictFormat *fmt;
+ int nitems;
+ int i;
+
+ XVisualInfo tpl = {
+ .screen = screen,
+ .depth = 32,
+ .class = TrueColor
+ };
+ long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
+
+ infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
+ visual = NULL;
+ for(i = 0; i < nitems; i ++) {
+ fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
+ visual = infos[i].visual;
+ depth = infos[i].depth;
+ cmap = XCreateColormap(dpy, root, visual, AllocNone);
+ useargb = 1;
+ break;
+ }
+ }
+
+ XFree(infos);
+
+ if (! visual) {
+ visual = DefaultVisual(dpy, screen);
+ depth = DefaultDepth(dpy, screen);
+ cmap = DefaultColormap(dpy, screen);
+ }
+}
diff --git a/drw.c b/drw.c
index 4cdbcbe..fe3aadd 100644
--- a/drw.c
+++ b/drw.c
@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen)
}
Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
{
Drw *drw = ecalloc(1, sizeof(Drw));
@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
drw->root = root;
drw->w = w;
drw->h = h;
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
- drw->gc = XCreateGC(dpy, root, 0, NULL);
+ drw->visual = visual;
+ drw->depth = depth;
+ drw->cmap = cmap;
+ drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
+ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
}
void
@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font)
}
void
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
+drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha)
{
if (!drw || !dest || !clrname)
return;
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen),
+ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
+
+ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount)
{
size_t i;
Clr *ret;
@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
return NULL;
for (i = 0; i < clrcount; i++)
- drw_clr_create(drw, &ret[i], clrnames[i]);
+ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
return ret;
}
@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
+ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
x += lpad;
w -= lpad;
}
diff --git a/drw.h b/drw.h
index 4c67419..f6fa5cd 100644
--- a/drw.h
+++ b/drw.h
@@ -20,6 +20,9 @@ typedef struct {
Display *dpy;
int screen;
Window root;
+ Visual *visual;
+ unsigned int depth;
+ Colormap cmap;
Drawable drawable;
GC gc;
Clr *scheme;
@@ -27,7 +30,7 @@ typedef struct {
} Drw;
/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
+Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha);
+Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);

View File

@ -0,0 +1,103 @@
From c4de1032bd4c247bc20b6ab92a10a8d778966679 Mon Sep 17 00:00:00 2001
From: Mehrad Mahmoudian <m.mahmoudian@gmail.com>
Date: Tue, 4 May 2021 12:05:09 +0300
Subject: [PATCH] patched with password patch
---
dmenu.1 | 5 ++++-
dmenu.c | 21 +++++++++++++++++----
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/dmenu.1 b/dmenu.1
index 323f93c..762f707 100644
--- 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
@@ -47,6 +47,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
index 65f25ce..ad8f63b 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -37,7 +37,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;
@@ -132,6 +132,7 @@ drawmenu(void)
unsigned int curpos;
struct item *item;
int x = 0, y = 0, w;
+ char *censort;
drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, 0, 0, mw, mh, 1, 1);
@@ -143,7 +144,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) {
@@ -524,6 +530,11 @@ readstdin(void)
char buf[sizeof text], *p;
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++) {
@@ -689,7 +700,7 @@ setup(void)
static void
usage(void)
{
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
+ fputs("usage: dmenu [-bfivP] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
exit(1);
}
@@ -712,7 +723,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 */
--
2.31.1

View File

@ -0,0 +1,82 @@
diff --git a/dmenu.1 b/dmenu.1
index 9eab758..61084ab 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -3,7 +3,7 @@
dmenu \- dynamic menu
.SH SYNOPSIS
.B dmenu
-.RB [ \-bfiv ]
+.RB [ \-bfirv ]
.RB [ \-l
.IR lines ]
.RB [ \-m
@@ -47,6 +47,9 @@ X until stdin reaches end\-of\-file.
.B \-i
dmenu matches menu items case insensitively.
.TP
+.B \-r
+dmenu will reject any input which would result in no matching option left.
+.TP
.BI \-l " lines"
dmenu lists items vertically, with the given number of lines.
.TP
diff --git a/dmenu.c b/dmenu.c
index d605ab4..7505278 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -38,6 +38,7 @@ static char *embed;
static int bh, mw, mh;
static int inputw = 0, promptw;
static int lrpad; /* sum of left and right padding */
+static int reject_no_match = 0;
static size_t cursor;
static struct item *items = NULL;
static struct item *matches, *matchend;
@@ -268,12 +269,26 @@ insert(const char *str, ssize_t n)
{
if (strlen(text) + n > sizeof text - 1)
return;
+
+ static char last[BUFSIZ] = "";
+ if(reject_no_match) {
+ /* store last text value in case we need to revert it */
+ memcpy(last, text, BUFSIZ);
+ }
+
/* move existing text out of the way, insert new text, and update cursor */
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
if (n > 0)
memcpy(&text[cursor], str, n);
cursor += n;
match();
+
+ if(!matches && reject_no_match) {
+ /* revert to last text value if theres no match */
+ memcpy(text, last, BUFSIZ);
+ cursor -= n;
+ match();
+ }
}
static size_t
@@ -636,7 +651,7 @@ setup(void)
static void
usage(void)
{
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
+ fputs("usage: dmenu [-bfirv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
exit(1);
}
@@ -659,7 +674,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], "-r")) /* reject input which results in no match */
+ reject_no_match = 1;
+ else if (i + 1 == argc)
usage();
/* these options take one argument */
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */