Compare commits

...

22 Commits
2.0 ... 2.4.2

Author SHA1 Message Date
a71424ac0e ok 2.4.2 2007-02-23 13:51:06 +01:00
f1ab687c62 Added tag 2.4.1 for changeset 03e83e2788c8 2007-02-23 13:28:43 +01:00
68a24f5535 hotfix 2007-02-23 13:28:38 +01:00
47b37834c4 Added tag 2.4 for changeset 9e9036cbfb4b 2007-02-23 10:42:00 +01:00
5f436fdcb7 added dmenu_path convenience script 2007-02-23 10:16:43 +01:00
de34639883 made Fnt an anonymous struct 2007-02-22 18:16:35 +01:00
18592825d2 Added tag 2.3 for changeset b6e09682c8adcb6569656bee73c311f9ab457715 2007-02-21 11:05:19 +01:00
3bc1f99e3c applied the fix inspired by a recent wmii commit 2007-02-21 10:59:36 +01:00
8a10b35c64 renamed getcolor to initcolor 2007-02-20 13:57:05 +01:00
e4fc905317 s/setfont/initfont/ 2007-02-20 13:54:37 +01:00
a1913a6af7 readded draw.c again (except getcolor and setfont) 2007-02-20 13:54:00 +01:00
66b2e8379f removed -t, now using isatty() instead of select() to prevent execution from an interactive shell 2007-02-19 21:18:36 +01:00
665488a6ee removed draw.c, implemented C-w handling (backward word deletion) 2007-02-19 15:49:50 +01:00
1e01ca0317 Added tag 2.2 for changeset 90f0e34e7f11 2007-02-14 09:42:02 +01:00
f3c12a7bff fixed Copyright notice in Makefile 2007-02-08 14:10:17 +01:00
3ba8b71aba nah nah nah, I can't get used to the bottom bar, pushing the conditional dmenu again 2007-02-08 11:17:11 +01:00
2bac5599b3 letting dmenu appear at the bottom by default 2007-02-08 11:10:29 +01:00
dbccf6fbff got rid of LD, inspired by JGs patch to wmii 2007-02-05 11:10:41 +01:00
aea9bfec5e Added tag 2.1 for changeset 7656557298c9 2007-01-17 11:10:31 +01:00
6175a39e8e hotfix changes 2007-01-17 11:10:26 +01:00
2c7ff85f24 Added tag 2.1 for changeset d91c79020430 2007-01-17 11:10:09 +01:00
447046f7ae Added tag 2.0 for changeset 1fce5c464fcd 2007-01-16 11:42:09 +01:00
9 changed files with 130 additions and 138 deletions

View File

@ -18,3 +18,9 @@ dcc5427f99f51a978386a0dd770467cd911ac84b 1.6
3696d77aaf02f5d15728dde3b9e35abcaf291496 1.7.1
d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8
c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9
1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0
7656557298c954469a6a9564e6649b1fb5db663e 2.1
90f0e34e7f118c9ad3227a1606211ee825942b1c 2.2
b6e09682c8adcb6569656bee73c311f9ab457715 2.3
9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4
03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1

View File

@ -1,5 +1,5 @@
# dmenu - dynamic menu
# (C)opyright MMVII Anselm R. Garbe
# (C)opyright MMVI-MMVII Anselm R. Garbe
include config.mk
@ -13,7 +13,6 @@ options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@echo "LD = ${LD}"
.c.o:
@echo CC $<
@ -22,8 +21,8 @@ options:
${OBJ}: dmenu.h config.mk
dmenu: ${OBJ}
@echo LD $@
@${LD} -o $@ ${OBJ} ${LDFLAGS}
@echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean:
@ -33,7 +32,7 @@ clean:
dist: clean
@echo creating dist tarball
@mkdir -p dmenu-${VERSION}
@cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.h ${SRC} dmenu-${VERSION}
@cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.h dmenu_path ${SRC} dmenu-${VERSION}
@tar -cf dmenu-${VERSION}.tar dmenu-${VERSION}
@gzip dmenu-${VERSION}.tar
@rm -rf dmenu-${VERSION}
@ -41,16 +40,17 @@ dist: clean
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f dmenu ${DESTDIR}${PREFIX}/bin
@cp -f dmenu dmenu_path ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu
@chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@sed 's/VERSION/${VERSION}/g' < dmenu.1 > ${DESTDIR}${MANPREFIX}/man1/dmenu.1
@sed "s/VERSION/${VERSION}/g" < dmenu.1 > ${DESTDIR}${MANPREFIX}/man1/dmenu.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1
uninstall:
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/dmenu
@rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_path
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1

View File

@ -1,5 +1,5 @@
# dmenu version
VERSION = 2.0
VERSION = 2.4.2
# Customize below to fit your system
@ -27,4 +27,3 @@ LDFLAGS = ${LIBS}
# compiler and linker
CC = cc
LD = ${CC}

View File

@ -10,7 +10,6 @@ dmenu \- dynamic menu
.RB [ \-p " <prompt>"]
.RB [ \-sb " <color>"]
.RB [ \-sf " <color>"]
.RB [ \-t " <seconds>"]
.RB [ \-v ]
.SH DESCRIPTION
.SS Overview
@ -41,9 +40,6 @@ defines the selected background color (#RGB, #RRGGBB, and color names are suppor
.B \-sf <color>
defines the selected foreground color (#RGB, #RRGGBB, and color names are supported).
.TP
.B \-t <seconds>
defines the seconds to wait for standard input, before exiting (default is 3).
.TP
.B \-v
prints version information to standard output, then exits.
.SH USAGE
@ -90,6 +86,9 @@ Remove enough characters from the input field to change its filtering effect.
.TP
.B Control-u
Remove all characters from the input field.
.TP
.B Control-w
Remove all characters of current word from the input field.
.SH SEE ALSO
.BR dwm (1),
.BR wmii (1) .

31
dmenu.h
View File

@ -14,36 +14,29 @@
/* color */
enum { ColFG, ColBG, ColLast };
typedef struct DC DC;
typedef struct Fnt Fnt;
struct Fnt {
typedef struct {
int x, y, w, h;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
Drawable drawable;
GC gc;
struct {
XFontStruct *xfont;
XFontSet set;
int ascent;
int descent;
int height;
};
struct DC {
int x, y, w, h;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
Drawable drawable;
Fnt font;
GC gc;
}; /* draw context */
} font;
} DC; /* draw context */
extern int screen;
extern Display *dpy;
extern DC dc; /* global drawing context */
/* draw.c */
extern void drawtext(const char *text,
unsigned long col[ColLast]); /* draws text with the defined color tuple */
extern unsigned long getcolor(const char *colstr); /* returns color of colstr */
extern void setfont(const char *fontstr); /* sets global font */
extern unsigned int textw(const char *text); /* returns width of text in px */
extern void drawtext(const char *text, unsigned long col[ColLast]);
extern unsigned int textw(const char *text);
extern unsigned int textnw(const char *text, unsigned int len);
/* util.c */
extern void *emalloc(unsigned int size); /* allocates memory, exits on error */

2
dmenu_path Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | sort -u

76
draw.c
View File

@ -1,23 +1,10 @@
/* (C)opyright MMIV-MMVII Anselm R. Garbe <garbeam at gmail dot com>
/* (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.
*/
#include "dmenu.h"
#include <stdio.h>
#include <string.h>
/* static */
static unsigned int
textnw(const char *text, unsigned int len) {
XRectangle r;
if(dc.font.set) {
XmbTextExtents(dc.font.set, text, len, NULL, &r);
return r.width;
}
return XTextWidth(dc.font.xfont, text, len);
}
/* extern */
void
@ -67,55 +54,18 @@ drawtext(const char *text, unsigned long col[ColLast]) {
}
}
unsigned long
getcolor(const char *colstr) {
Colormap cmap = DefaultColormap(dpy, screen);
XColor color;
if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
eprint("error, cannot allocate color '%s'\n", colstr);
return color.pixel;
}
void
setfont(const char *fontstr) {
char *def, **missing;
int i, n;
missing = NULL;
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
if(missing)
XFreeStringList(missing);
if(dc.font.set) {
XFontSetExtents *font_extents;
XFontStruct **xfonts;
char **font_names;
dc.font.ascent = dc.font.descent = 0;
font_extents = XExtentsOfFontSet(dc.font.set);
n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
if(dc.font.ascent < (*xfonts)->ascent)
dc.font.ascent = (*xfonts)->ascent;
if(dc.font.descent < (*xfonts)->descent)
dc.font.descent = (*xfonts)->descent;
xfonts++;
}
}
else {
if(dc.font.xfont)
XFreeFont(dpy, dc.font.xfont);
dc.font.xfont = NULL;
if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
eprint("error, cannot load font: '%s'\n", fontstr);
dc.font.ascent = dc.font.xfont->ascent;
dc.font.descent = dc.font.xfont->descent;
}
dc.font.height = dc.font.ascent + dc.font.descent;
}
unsigned int
textw(const char *text) {
return textnw(text, strlen(text)) + dc.font.height;
}
unsigned int
textnw(const char *text, unsigned int len) {
XRectangle r;
if(dc.font.set) {
XmbTextExtents(dc.font.set, text, len, NULL, &r);
return r.width;
}
return XTextWidth(dc.font.xfont, text, len);
}

125
main.c
View File

@ -3,15 +3,12 @@
* See LICENSE file for license details.
*/
#include "dmenu.h"
#include <ctype.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@ -111,6 +108,54 @@ drawmenu(void) {
XFlush(dpy);
}
static unsigned long
initcolor(const char *colstr) {
Colormap cmap = DefaultColormap(dpy, screen);
XColor color;
if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
eprint("error, cannot allocate color '%s'\n", colstr);
return color.pixel;
}
static void
initfont(const char *fontstr) {
char *def, **missing;
int i, n;
missing = NULL;
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
if(missing)
XFreeStringList(missing);
if(dc.font.set) {
XFontSetExtents *font_extents;
XFontStruct **xfonts;
char **font_names;
dc.font.ascent = dc.font.descent = 0;
font_extents = XExtentsOfFontSet(dc.font.set);
n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
if(dc.font.ascent < (*xfonts)->ascent)
dc.font.ascent = (*xfonts)->ascent;
if(dc.font.descent < (*xfonts)->descent)
dc.font.descent = (*xfonts)->descent;
xfonts++;
}
}
else {
if(dc.font.xfont)
XFreeFont(dpy, dc.font.xfont);
dc.font.xfont = NULL;
if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
eprint("error, cannot load font: '%s'\n", fontstr);
dc.font.ascent = dc.font.xfont->ascent;
dc.font.descent = dc.font.xfont->descent;
}
dc.font.height = dc.font.ascent + dc.font.descent;
}
static void
match(char *pattern) {
unsigned int plen;
@ -151,8 +196,8 @@ match(char *pattern) {
static void
kpress(XKeyEvent * e) {
char buf[32];
int num, prev_nitem;
unsigned int i, len;
int i, num, prev_nitem;
unsigned int len;
KeySym ksym;
len = strlen(text);
@ -188,6 +233,18 @@ kpress(XKeyEvent * e) {
match(text);
drawmenu();
return;
case XK_w:
case XK_W:
if(len) {
i = len - 1;
while(i >= 0 && text[i] == ' ')
text[i--] = 0;
while(i >= 0 && text[i] != ' ')
text[i--] = 0;
match(text);
drawmenu();
}
return;
}
}
if(CLEANMASK(e->state) & Mod1Mask) {
@ -334,6 +391,12 @@ readstdin(void) {
return maxname;
}
static void
usage(void) {
eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n"
" [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n");
}
/* extern */
int screen;
@ -349,16 +412,16 @@ main(int argc, char *argv[]) {
char *normfg = NORMFGCOLOR;
char *selbg = SELBGCOLOR;
char *selfg = SELFGCOLOR;
fd_set rd;
int i, j, my;
struct timeval timeout;
int i, j;
Item *itm;
XEvent ev;
XModifierKeymap *modmap;
XSetWindowAttributes wa;
timeout.tv_usec = 0;
timeout.tv_sec = 3;
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)) {
@ -382,61 +445,44 @@ main(int argc, char *argv[]) {
else if(!strncmp(argv[i], "-sf", 4)) {
if(++i < argc) selfg = argv[i];
}
else if(!strncmp(argv[i], "-t", 3)) {
if(++i < argc) timeout.tv_sec = atoi(argv[i]);
}
else if(!strncmp(argv[i], "-v", 3)) {
fputs("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout);
exit(EXIT_SUCCESS);
}
else if(!strncmp(argv[i], "-v", 3))
eprint("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n");
else
eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n"
" [-sb <color>] [-sf <color>] [-t <seconds>] [-v]\n", stdout);
usage();
setlocale(LC_CTYPE, "");
dpy = XOpenDisplay(0);
if(!dpy)
eprint("dmenu: cannot open display\n");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
/* Note, the select() construction allows to grab all keypresses as
* early as possible, to not loose them. But if there is no standard
* input supplied, we will make sure to exit after MAX_WAIT_STDIN
* seconds. This is convenience behavior for rapid typers.
*/
while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
GrabModeAsync, CurrentTime) != GrabSuccess)
usleep(1000);
FD_ZERO(&rd);
FD_SET(STDIN_FILENO, &rd);
if(select(ConnectionNumber(dpy) + 1, &rd, NULL, NULL, &timeout) < 1)
goto UninitializedEnd;
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))
if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
}
}
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;
wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask;
my = 0;
mw = DisplayWidth(dpy, screen);
mh = dc.font.height + 2;
if(bottom)
my += DisplayHeight(dpy, screen) - mh;
win = XCreateWindow(dpy, root, 0, 0, mw, mh, 0,
win = XCreateWindow(dpy, root, 0,
bottom ? DisplayHeight(dpy, screen) - mh : 0, mw, mh, 0,
DefaultDepth(dpy, screen), CopyFromParent,
DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
@ -486,7 +532,6 @@ main(int argc, char *argv[]) {
XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, win);
UninitializedEnd:
XUngrabKeyboard(dpy, CurrentTime);
XCloseDisplay(dpy);
return ret;

2
util.c
View File

@ -6,8 +6,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void *
emalloc(unsigned int size) {