Compare commits

..

9 Commits
2.5 ... 2.7

5 changed files with 52 additions and 53 deletions

View File

@ -25,3 +25,5 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3
9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4 9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4
03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1 03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1
1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2 1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2
041143e9fc544c62edc58af52cae9ac5237e5945 2.5
775f761a5647a05038e091d1c99fc35d3034cd68 2.6

View File

@ -1,5 +1,5 @@
# dmenu version # dmenu version
VERSION = 2.5 VERSION = 2.7
# Customize below to fit your system # Customize below to fit your system

24
dmenu.1
View File

@ -1,4 +1,4 @@
.TH DMENU 1 dmenu-VERSION .TH DMENU 1 dmenu\-VERSION
.SH NAME .SH NAME
dmenu \- dynamic menu dmenu \- dynamic menu
.SH SYNOPSIS .SH SYNOPSIS
@ -53,41 +53,41 @@ dmenu is completely controlled by the keyboard. The following keys are recognize
Appends the character to the text in the input field. This works as a filter: Appends the character to the text in the input field. This works as a filter:
only items containing this text will be displayed. only items containing this text will be displayed.
.TP .TP
.B Left/Right (Mod1-h/Mod1-l) .B Left/Right (Mod1\-h/Mod1\-l)
Select the previous/next item. Select the previous/next item.
.TP .TP
.B PageUp/PageDown (Mod1-k/Mod1-j) .B PageUp/PageDown (Mod1\-k/Mod1\-j)
Select the first item of the previous/next 'page' of items. Select the first item of the previous/next 'page' of items.
.TP .TP
.B Home/End (Mod1-g/Mod1-G) .B Home/End (Mod1\-g/Mod1\-G)
Select the first/last item. Select the first/last item.
.TP .TP
.B Tab (Control-i) .B Tab (Control\-i)
Copy the selected item to the input field. Copy the selected item to the input field.
.TP .TP
.B Return (Control-j) .B Return (Control\-j)
Confirm selection and quit (print the selected item to standard output). Returns Confirm selection and quit (print the selected item to standard output). Returns
.B 0 .B 0
on termination. on termination.
.TP .TP
.B Shift-Return (Control-Shift-j) .B Shift\-Return (Control\-Shift\-j)
Confirm selection and quit (print the text in the input field to standard output). Confirm selection and quit (print the text in the input field to standard output).
Returns Returns
.B 0 .B 0
on termination. on termination.
.TP .TP
.B Escape (Control-bracketleft) .B Escape (Control\-bracketleft)
Quit without selecting an item. Returns Quit without selecting an item. Returns
.B 1 .B 1
on termination. on termination.
.TP .TP
.B Backspace (Control-h) .B Backspace (Control\-h)
Remove enough characters from the input field to change its filtering effect. Remove a character from the input field.
.TP .TP
.B Control-u .B Control\-u
Remove all characters from the input field. Remove all characters from the input field.
.TP .TP
.B Control-w .B Control\-w
Remove all characters of current word from the input field. Remove all characters of current word from the input field.
.SH SEE ALSO .SH SEE ALSO
.BR dwm (1), .BR dwm (1),

15
draw.c
View File

@ -12,7 +12,6 @@ drawtext(const char *text, unsigned long col[ColLast]) {
int x, y, w, h; int x, y, w, h;
static char buf[256]; static char buf[256];
unsigned int len, olen; unsigned int len, olen;
XGCValues gcv;
XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XRectangle r = { dc.x, dc.y, dc.w, dc.h };
XSetForeground(dpy, dc.gc, col[ColBG]); XSetForeground(dpy, dc.gc, col[ColBG]);
@ -41,17 +40,11 @@ drawtext(const char *text, unsigned long col[ColLast]) {
} }
if(w > dc.w) if(w > dc.w)
return; /* too long */ return; /* too long */
gcv.foreground = col[ColFG]; XSetForeground(dpy, dc.gc, col[ColFG]);
if(dc.font.set) { if(dc.font.set)
XChangeGC(dpy, dc.gc, GCForeground, &gcv); XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, else
x, y, buf, len);
}
else {
gcv.font = dc.font.xfont->fid;
XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
}
} }
unsigned int unsigned int

62
main.c
View File

@ -108,6 +108,13 @@ drawmenu(void) {
XFlush(dpy); XFlush(dpy);
} }
static void
grabkeyboard(void) {
while(XGrabKeyboard(dpy, win, True, GrabModeAsync,
GrabModeAsync, CurrentTime) != GrabSuccess)
usleep(1000);
}
static unsigned long static unsigned long
initcolor(const char *colstr) { initcolor(const char *colstr) {
Colormap cmap = DefaultColormap(dpy, screen); Colormap cmap = DefaultColormap(dpy, screen);
@ -196,7 +203,7 @@ match(char *pattern) {
static void static void
kpress(XKeyEvent * e) { kpress(XKeyEvent * e) {
char buf[32]; char buf[32];
int i, num, prev_nitem; int i, num;
unsigned int len; unsigned int len;
KeySym ksym; KeySym ksym;
@ -282,12 +289,8 @@ kpress(XKeyEvent * e) {
} }
break; break;
case XK_BackSpace: case XK_BackSpace:
if((i = len)) { if(len) {
prev_nitem = nitem; text[--len] = 0;
do {
text[--i] = 0;
match(text);
} while(i && nitem && prev_nitem == nitem);
match(text); match(text);
} }
break; break;
@ -418,12 +421,6 @@ main(int argc, char *argv[]) {
XModifierKeymap *modmap; XModifierKeymap *modmap;
XSetWindowAttributes wa; XSetWindowAttributes wa;
if(argc == 2 && !strncmp("-v", argv[1], 3))
eprint("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n");
else if(isatty(STDIN_FILENO)) {
fputs("error: dmenu can't run in an interactive shell\n", stdout);
usage();
}
/* command line args */ /* command line args */
for(i = 1; i < argc; i++) for(i = 1; i < argc; i++)
if(!strncmp(argv[i], "-b", 3)) { if(!strncmp(argv[i], "-b", 3)) {
@ -447,6 +444,8 @@ main(int argc, char *argv[]) {
else if(!strncmp(argv[i], "-sf", 4)) { else if(!strncmp(argv[i], "-sf", 4)) {
if(++i < argc) selfg = argv[i]; 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 else
usage(); usage();
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
@ -455,20 +454,6 @@ main(int argc, char *argv[]) {
eprint("dmenu: cannot open display\n"); eprint("dmenu: cannot open display\n");
screen = DefaultScreen(dpy); screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen); root = RootWindow(dpy, screen);
while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
GrabModeAsync, CurrentTime) != GrabSuccess)
usleep(1000);
maxname = readstdin();
/* init modifier map */
modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++) {
for (j = 0; j < modmap->max_keypermod; j++) {
if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
}
}
XFreeModifiermap(modmap);
/* style */ /* style */
dc.norm[ColBG] = initcolor(normbg); dc.norm[ColBG] = initcolor(normbg);
dc.norm[ColFG] = initcolor(normfg); dc.norm[ColFG] = initcolor(normfg);
@ -490,6 +475,27 @@ main(int argc, char *argv[]) {
dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen));
dc.gc = XCreateGC(dpy, root, 0, 0); dc.gc = XCreateGC(dpy, root, 0, 0);
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
if(!dc.font.set)
XSetFont(dpy, dc.gc, dc.font.xfont->fid);
drawmenu();
XMapRaised(dpy, win);
if(isatty(STDIN_FILENO)) {
maxname = readstdin();
grabkeyboard();
}
else { /* prevent keypress loss */
grabkeyboard();
maxname = readstdin();
}
/* init modifier map */
modmap = XGetModifierMapping(dpy);
for(i = 0; i < 8; i++)
for(j = 0; j < modmap->max_keypermod; j++) {
if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
}
XFreeModifiermap(modmap);
if(maxname) if(maxname)
cmdw = textw(maxname); cmdw = textw(maxname);
if(cmdw > mw / 3) if(cmdw > mw / 3)
@ -500,8 +506,6 @@ main(int argc, char *argv[]) {
promptw = mw / 5; promptw = mw / 5;
text[0] = 0; text[0] = 0;
match(text); match(text);
XMapRaised(dpy, win);
drawmenu();
XSync(dpy, False); XSync(dpy, False);
/* main event loop */ /* main event loop */