Compare commits

...

8 Commits
0.8 ... 1.0

10 changed files with 76 additions and 76 deletions

View File

@ -5,3 +5,5 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3
4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5 4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5
25f679fb19686140a907684ffcb423b9e9d44b53 0.6 25f679fb19686140a907684ffcb423b9e9d44b53 0.6
5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7 5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7
409667a57221f7e50ba8b5248f638915cd61b366 0.8
d046c818ea467555cc338751c9bf3024609f1f12 0.9

2
README
View File

@ -1,6 +1,6 @@
dmenu - dynamic menu dmenu - dynamic menu
-------------------- --------------------
dmenu is a generic, highly customizable, and efficient menu for X. dmenu is a generic and efficient menu for X.
Requirements Requirements

View File

@ -8,3 +8,4 @@
#define SELFGCOLOR "#eeeeee" #define SELFGCOLOR "#eeeeee"
#define NORMBGCOLOR "#333333" #define NORMBGCOLOR "#333333"
#define NORMFGCOLOR "#dddddd" #define NORMFGCOLOR "#dddddd"
#define STDIN_TIMEOUT 3 /* seconds */

View File

@ -8,3 +8,4 @@
#define SELFGCOLOR "#eeeeee" #define SELFGCOLOR "#eeeeee"
#define NORMBGCOLOR "#333366" #define NORMBGCOLOR "#333366"
#define NORMFGCOLOR "#cccccc" #define NORMFGCOLOR "#cccccc"
#define STDIN_TIMEOUT 3 /* seconds */

View File

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

53
dmenu.1
View File

@ -6,8 +6,7 @@ dmenu \- dynamic menu
.RB [ \-v ] .RB [ \-v ]
.SH DESCRIPTION .SH DESCRIPTION
.SS Overview .SS Overview
.B dmenu dmenu is a generic menu for X, originally designed for
is a generic menu for X, originally designed for
.BR dwm (1). .BR dwm (1).
It manages huge amounts (up to 10.000 and more) of user defined menu items It manages huge amounts (up to 10.000 and more) of user defined menu items
efficiently. efficiently.
@ -16,49 +15,45 @@ efficiently.
.B \-v .B \-v
prints version information to standard output, then exits. prints version information to standard output, then exits.
.SH USAGE .SH USAGE
.B dmenu dmenu reads a list of newline-separated items from standard input and creates a
reads a list of newline-separated items from standard input and creates a menu. menu. When the user selects an item or enters any text and presses Return, his
When the user selects an item or enters any text and presses Return, his choice choice is printed to standard output and dmenu terminates.
is printed to standard output and .P
.B dmenu dmenu is completely controlled by the keyboard. The following keys are recognized:
terminates.
.B dmenu
is completely controlled by the keyboard. The following keys are recognized:
.TP .TP
Any printable character .B Any printable character
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
Left/Right .B Left/Right
Select the previous/next item. Select the previous/next item.
.TP .TP
Tab .B Tab
Copy the selected item to the input field. Copy the selected item to the input field.
.TP .TP
Return .B Return
Confirm selection and quit (print the selected item to standard output). Confirm selection and quit (print the selected item to standard output). Returns
.B 0
on termination.
.TP .TP
Shift-Return .B Shift-Return
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
.B 0
on termination.
.TP .TP
Escape .B Escape
Quit without selecting an item. Quit without selecting an item. Returns
.B 1
on termination.
.TP .TP
Backspace (Control-h) .B Backspace (Control-h)
Remove enough characters from the input field to change its filtering effect. Remove enough characters from the input field to change its filtering effect.
.TP .TP
Control-u .B Control-u
Remove all characters from the input field. Remove all characters from the input field.
.P
.B dmenu
returns
.B 0
if Return is pressed on termination,
.B 1
if Escape is pressed.
.SH CUSTOMIZATION .SH CUSTOMIZATION
.B dmenu dmenu is customized by creating a custom config.h and (re)compiling the source
is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple. code. This keeps it fast, secure and simple.
.SH SEE ALSO .SH SEE ALSO
.BR dwm (1) .BR dwm (1)

21
dmenu.h
View File

@ -23,26 +23,27 @@ struct Fnt {
int height; int height;
}; };
struct DC { /* draw context */ struct DC {
int x, y, w, h; int x, y, w, h;
unsigned long norm[ColLast]; unsigned long norm[ColLast];
unsigned long sel[ColLast]; unsigned long sel[ColLast];
Drawable drawable; Drawable drawable;
Fnt font; Fnt font;
GC gc; GC gc;
}; }; /* draw context */
extern int screen; extern int screen;
extern Display *dpy; extern Display *dpy;
extern DC dc; extern DC dc; /* global drawing context */
/* draw.c */ /* draw.c */
extern void drawtext(const char *text, unsigned long col[ColLast]); extern void drawtext(const char *text,
extern unsigned long getcolor(const char *colstr); unsigned long col[ColLast]); /* draws text with the defined color tuple */
extern void setfont(const char *fontstr); extern unsigned long getcolor(const char *colstr); /* returns color of colstr */
extern unsigned int textw(const char *text); extern void setfont(const char *fontstr); /* sets global font */
extern unsigned int textw(const char *text); /* returns width of text in px */
/* util.c */ /* util.c */
extern void *emalloc(unsigned int size); extern void *emalloc(unsigned int size); /* allocates memory, exits on error */
extern void eprint(const char *errstr, ...); extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */
extern char *estrdup(const char *str); extern char *estrdup(const char *str); /* duplicates str, exits on allocation error */

15
draw.c
View File

@ -10,8 +10,7 @@
/* static */ /* static */
static unsigned int static unsigned int
textnw(const char *text, unsigned int len) textnw(const char *text, unsigned int len) {
{
XRectangle r; XRectangle r;
if(dc.font.set) { if(dc.font.set) {
@ -24,8 +23,7 @@ textnw(const char *text, unsigned int len)
/* extern */ /* extern */
void void
drawtext(const char *text, unsigned long col[ColLast]) 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;
@ -78,8 +76,7 @@ drawtext(const char *text, unsigned long col[ColLast])
} }
unsigned long unsigned long
getcolor(const char *colstr) getcolor(const char *colstr) {
{
Colormap cmap = DefaultColormap(dpy, screen); Colormap cmap = DefaultColormap(dpy, screen);
XColor color; XColor color;
@ -88,8 +85,7 @@ getcolor(const char *colstr)
} }
void void
setfont(const char *fontstr) setfont(const char *fontstr) {
{
char **missing, *def; char **missing, *def;
int i, n; int i, n;
@ -137,7 +133,6 @@ setfont(const char *fontstr)
} }
unsigned int unsigned int
textw(const char *text) textw(const char *text) {
{
return textnw(text, strlen(text)) + dc.font.height; return textnw(text, strlen(text)) + dc.font.height;
} }

41
main.c
View File

@ -11,6 +11,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/keysym.h> #include <X11/keysym.h>
@ -40,8 +42,7 @@ static Window root;
static Window win; static Window win;
static void static void
calcoffsets() calcoffsets() {
{
unsigned int tw, w; unsigned int tw, w;
if(!curr) if(!curr)
@ -69,8 +70,7 @@ calcoffsets()
} }
static void static void
drawmenu() drawmenu() {
{
Item *i; Item *i;
dc.x = 0; dc.x = 0;
@ -108,8 +108,7 @@ drawmenu()
} }
static void static void
match(char *pattern) match(char *pattern) {
{
unsigned int plen; unsigned int plen;
Item *i, *j; Item *i, *j;
@ -149,8 +148,7 @@ match(char *pattern)
} }
static void static void
kpress(XKeyEvent * e) kpress(XKeyEvent * e) {
{
char buf[32]; char buf[32];
int num, prev_nitem; int num, prev_nitem;
unsigned int i, len; unsigned int i, len;
@ -249,8 +247,7 @@ kpress(XKeyEvent * e)
} }
static char * static char *
readstdin() readstdin() {
{
static char *maxname = NULL; static char *maxname = NULL;
char *p, buf[1024]; char *p, buf[1024];
unsigned int len = 0, max = 0; unsigned int len = 0, max = 0;
@ -287,9 +284,10 @@ Display *dpy;
DC dc = {0}; DC dc = {0};
int int
main(int argc, char *argv[]) main(int argc, char *argv[]) {
{
char *maxname; char *maxname;
fd_set rd;
struct timeval timeout;
Item *i; Item *i;
XEvent ev; XEvent ev;
XSetWindowAttributes wa; XSetWindowAttributes wa;
@ -307,13 +305,23 @@ main(int argc, char *argv[])
screen = DefaultScreen(dpy); screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen); root = RootWindow(dpy, screen);
maxname = readstdin(); /* Note, the select() construction allows to grab all keypresses as
* early as possible, to not loose them. But if there is no standard
/* grab as early as possible, but after reading all items!!! */ * 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, while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
GrabModeAsync, CurrentTime) != GrabSuccess) GrabModeAsync, CurrentTime) != GrabSuccess)
usleep(1000); usleep(1000);
timeout.tv_usec = 0;
timeout.tv_sec = STDIN_TIMEOUT;
FD_ZERO(&rd);
FD_SET(STDIN_FILENO, &rd);
if(select(ConnectionNumber(dpy) + 1, &rd, NULL, NULL, &timeout) < 1)
goto UninitializedEnd;
maxname = readstdin();
/* style */ /* style */
dc.sel[ColBG] = getcolor(SELBGCOLOR); dc.sel[ColBG] = getcolor(SELBGCOLOR);
dc.sel[ColFG] = getcolor(SELFGCOLOR); dc.sel[ColFG] = getcolor(SELFGCOLOR);
@ -366,7 +374,6 @@ main(int argc, char *argv[])
} }
} }
XUngrabKeyboard(dpy, CurrentTime);
while(allitems) { while(allitems) {
i = allitems->next; i = allitems->next;
free(allitems->text); free(allitems->text);
@ -380,6 +387,8 @@ main(int argc, char *argv[])
XFreePixmap(dpy, dc.drawable); XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc); XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, win); XDestroyWindow(dpy, win);
UninitializedEnd:
XUngrabKeyboard(dpy, CurrentTime);
XCloseDisplay(dpy); XCloseDisplay(dpy);
return ret; return ret;

12
util.c
View File

@ -13,16 +13,14 @@
/* static */ /* static */
static void static void
badmalloc(unsigned int size) badmalloc(unsigned int size) {
{
eprint("fatal: could not malloc() %u bytes\n", size); eprint("fatal: could not malloc() %u bytes\n", size);
} }
/* extern */ /* extern */
void * void *
emalloc(unsigned int size) emalloc(unsigned int size) {
{
void *res = malloc(size); void *res = malloc(size);
if(!res) if(!res)
badmalloc(size); badmalloc(size);
@ -30,8 +28,7 @@ emalloc(unsigned int size)
} }
void void
eprint(const char *errstr, ...) eprint(const char *errstr, ...) {
{
va_list ap; va_list ap;
va_start(ap, errstr); va_start(ap, errstr);
@ -41,8 +38,7 @@ eprint(const char *errstr, ...)
} }
char * char *
estrdup(const char *str) estrdup(const char *str) {
{
void *res = strdup(str); void *res = strdup(str);
if(!res) if(!res)
badmalloc(strlen(str)); badmalloc(strlen(str));