From 42e005e045e5d18b9430b99be014243decdb0f3f Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" Date: Fri, 4 Aug 2006 09:35:27 +0200 Subject: [PATCH 001/590] initial import --- dmenubar/LICENSE | 21 ++ dmenubar/Makefile | 61 ++++++ dmenubar/README | 48 +++++ dmenubar/config.arg.h | 9 + dmenubar/config.default.h | 9 + dmenubar/config.h | 9 + dmenubar/config.mk | 24 +++ dmenubar/dmenu.1 | 68 ++++++ dmenubar/dmenu.h | 58 ++++++ dmenubar/draw.c | 171 +++++++++++++++ dmenubar/main.c | 426 ++++++++++++++++++++++++++++++++++++++ dmenubar/util.c | 68 ++++++ 12 files changed, 972 insertions(+) create mode 100644 dmenubar/LICENSE create mode 100644 dmenubar/Makefile create mode 100644 dmenubar/README create mode 100644 dmenubar/config.arg.h create mode 100644 dmenubar/config.default.h create mode 100644 dmenubar/config.h create mode 100644 dmenubar/config.mk create mode 100644 dmenubar/dmenu.1 create mode 100644 dmenubar/dmenu.h create mode 100644 dmenubar/draw.c create mode 100644 dmenubar/main.c create mode 100644 dmenubar/util.c diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE new file mode 100644 index 0000000..aa0a3ab --- /dev/null +++ b/dmenubar/LICENSE @@ -0,0 +1,21 @@ +MIT/X Consortium License + +(C)opyright MMVI Anselm R. Garbe + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/dmenubar/Makefile b/dmenubar/Makefile new file mode 100644 index 0000000..0cfd20d --- /dev/null +++ b/dmenubar/Makefile @@ -0,0 +1,61 @@ +# dmenu - dynamic menu +# (C)opyright MMVI Anselm R. Garbe + +include config.mk + +SRC = draw.c main.c util.c +OBJ = ${SRC:.c=.o} + +all: options dmenu + @echo finished + +options: + @echo dmenu build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + @echo CC $< + @${CC} -c ${CFLAGS} $< + +${OBJ}: dmenu.h config.h + +config.h: + @echo creating $@ from config.default.h + @cp config.default.h $@ + +dmenu: ${OBJ} + @echo LD $@ + @${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + @echo cleaning + @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz + +dist: clean + @echo creating dist tarball + @mkdir -p dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk \ + dmenu.1 dmenu.h ${SRC} dmenu-${VERSION} + @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} + @gzip dmenu-${VERSION}.tar + @rm -rf dmenu-${VERSION} + +install: all + @echo installing executable file to ${DESTDIR}${PREFIX}/bin + @mkdir -p ${DESTDIR}${PREFIX}/bin + @cp -f dmenu ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu + @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 + @mkdir -p ${DESTDIR}${MANPREFIX}/man1 + @cp -f dmenu.1 ${DESTDIR}${MANPREFIX}/man1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 + +uninstall: + @echo removing executable file from ${DESTDIR}${PREFIX}/bin + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu + @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 + @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 + +.PHONY: all options clean dist install uninstall diff --git a/dmenubar/README b/dmenubar/README new file mode 100644 index 0000000..5915a27 --- /dev/null +++ b/dmenubar/README @@ -0,0 +1,48 @@ +dwm - dynamic window manager +---------------------------- +dwm is an extremely fast, small, and dynamic X11 window manager. + + +Requirements +------------ +In order to build dwm you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (dwm is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install dwm (if +necessary as root): + + make clean install + + +Running dwm +----------- +Add the following line to your .xinitrc to start dwm using startx: + + exec dwm + +In order to connect dwm to a specific display, make sure that +the DISPLAY environment variable is set correctly, e.g.: + + DISPLAY=foo.bar:1 exec dwm + +(This will start dwm on display :1 of the host foo.bar.) + +In order to display status info in the bar, you can do something +like this in your .xinitrc: + + while true + do + echo `date` `uptime | sed 's/.*://; s/,//g'` + sleep 1 + done | dwm + + +Configuration +------------- +The configuration of dwm is done by creating a custom config.h +and (re)compiling the source code. diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h new file mode 100644 index 0000000..008161d --- /dev/null +++ b/dmenubar/config.arg.h @@ -0,0 +1,9 @@ +/* + * (C)opyright MMVI Anselm R. Garbe + * See LICENSE file for license details. + */ + +#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" +#define BGCOLOR "#0a2c2d" +#define FGCOLOR "#ddeeee" +#define BORDERCOLOR "#176164" diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h new file mode 100644 index 0000000..cf1baea --- /dev/null +++ b/dmenubar/config.default.h @@ -0,0 +1,9 @@ +/* + * (C)opyright MMVI Anselm R. Garbe + * See LICENSE file for license details. + */ + +#define FONT "fixed" +#define BGCOLOR "#666699" +#define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/config.h b/dmenubar/config.h new file mode 100644 index 0000000..008161d --- /dev/null +++ b/dmenubar/config.h @@ -0,0 +1,9 @@ +/* + * (C)opyright MMVI Anselm R. Garbe + * See LICENSE file for license details. + */ + +#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" +#define BGCOLOR "#0a2c2d" +#define FGCOLOR "#ddeeee" +#define BORDERCOLOR "#176164" diff --git a/dmenubar/config.mk b/dmenubar/config.mk new file mode 100644 index 0000000..a4d21ac --- /dev/null +++ b/dmenubar/config.mk @@ -0,0 +1,24 @@ +# dwm version +VERSION = 0.0 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +# includes and libs +INCS = -I/usr/lib -I${X11INC} +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 + +# flags +CFLAGS = -O3 ${INCS} -DVERSION=\"${VERSION}\" +LDFLAGS = ${LIBS} +#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = -g ${LIBS} + +# compiler +CC = cc diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 new file mode 100644 index 0000000..da69047 --- /dev/null +++ b/dmenubar/dmenu.1 @@ -0,0 +1,68 @@ +.TH DMENU 1 d-0.0 +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-v ] +.RB [ \-t +.IR title ] +.SH DESCRIPTION +.SS Overview +.B dmenu +is a generic, highly customizable, and efficient menu for the X Window System, +originally designed for +.BR dwm (1). +It supports arbitrary, user defined menu contents. +.SS Options +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-t " title" +displays +.I title +above the menu. +.SS Usage +.B dmenu +reads a list of newline-separated items from stdin and creates a menu. +When the user selects an item or enters any text and presses Enter, his choice +is printed to stdout and +.B dmenu +terminates. +.SS Keyboard Control +.B dmenu +is completely controlled by the keyboard. The following keys are recognized: +.TP 2 +Any printable character +appends the character to the text in the input field. This works as a filter: +only items containing this text will be displayed. +.TP 2 +Left/Right (Control-p/Control-n) +select the previous/next item. +.TP 2 +Tab (Control-i) +copy the selected item to the input field. +.TP 2 +Enter (Control-j) +confirm selection and quit (print the selected item to stdout). +.TP 2 +Shift-Enter (Shift-Control-j) +confirm selection and quit (print the text in the input field to stdout). +.TP 2 +Escape (Control-[) +quit without selecting an item. +.TP 2 +Backspace (Control-h) +remove enough characters from the input field to change its filtering effect. +.TP 2 +Control-u +remove all characters from the input field. +.SS Exit codes +.B dmenu +returns +.B 0 +if Enter is pressed on termination, +.B 1 +if Escape is pressed. +.SH SEE ALSO +.BR dwm (1) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h new file mode 100644 index 0000000..8d630ba --- /dev/null +++ b/dmenubar/dmenu.h @@ -0,0 +1,58 @@ +/* + * (C)opyright MMVI Anselm R. Garbe + * See LICENSE file for license details. + */ + +#include "config.h" +#include +#include + +typedef struct Brush Brush; +typedef struct DC DC; +typedef struct Fnt Fnt; + +struct Fnt { + XFontStruct *xfont; + XFontSet set; + int ascent; + int descent; + int height; +}; + +struct DC { /* draw context */ + int x, y, w, h; + unsigned long bg; + unsigned long fg; + unsigned long border; + Drawable drawable; + Fnt font; + GC gc; +}; + +struct Brush { + GC gc; + Drawable drawable; + int x, y, w, h; + Fnt font; + unsigned long bg; + unsigned long fg; + unsigned long border; +}; + + + +/* draw.c */ +extern void draw(Display *dpy, Brush *b, Bool border, const char *text); +extern void loadcolors(Display *dpy, int screen, Brush *b, + const char *bg, const char *fg, const char *bo); +extern void loadfont(Display *dpy, Fnt *font, const char *fontstr); +extern unsigned int textnw(Fnt *font, char *text, unsigned int len); +extern unsigned int textw(Fnt *font, char *text); +extern unsigned int texth(Fnt *font); + +/* util.c */ +extern void *emalloc(unsigned int size); +extern void *emallocz(unsigned int size); +extern void eprint(const char *errstr, ...); +extern char *estrdup(const char *str); +extern void swap(void **p1, void **p2); diff --git a/dmenubar/draw.c b/dmenubar/draw.c new file mode 100644 index 0000000..d747629 --- /dev/null +++ b/dmenubar/draw.c @@ -0,0 +1,171 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe + * See LICENSE file for license details. + */ + +#include +#include + +#include "dmenu.h" + +static void +drawborder(Display *dpy, Brush *b) +{ + XPoint points[5]; + XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter); + XSetForeground(dpy, b->gc, b->border); + points[0].x = b->x; + points[0].y = b->y; + points[1].x = b->w - 1; + points[1].y = 0; + points[2].x = 0; + points[2].y = b->h - 1; + points[3].x = -(b->w - 1); + points[3].y = 0; + points[4].x = 0; + points[4].y = -(b->h - 1); + XDrawLines(dpy, b->drawable, b->gc, points, 5, CoordModePrevious); +} + +void +draw(Display *dpy, Brush *b, Bool border, const char *text) +{ + unsigned int x, y, w, h, len; + static char buf[256]; + XGCValues gcv; + XRectangle r = { b->x, b->y, b->w, b->h }; + + XSetForeground(dpy, b->gc, b->bg); + XFillRectangles(dpy, b->drawable, b->gc, &r, 1); + + w = 0; + if(border) + drawborder(dpy, b); + + if(!text) + return; + + len = strlen(text); + if(len >= sizeof(buf)) + len = sizeof(buf) - 1; + memcpy(buf, text, len); + buf[len] = 0; + + h = b->font.ascent + b->font.descent; + y = b->y + (b->h / 2) - (h / 2) + b->font.ascent; + x = b->x + (h / 2); + + /* shorten text if necessary */ + while(len && (w = textnw(&b->font, buf, len)) > b->w - h) + buf[--len] = 0; + + if(w > b->w) + return; /* too long */ + + gcv.foreground = b->fg; + gcv.background = b->bg; + if(b->font.set) { + XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv); + XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc, + x, y, buf, len); + } + else { + gcv.font = b->font.xfont->fid; + XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv); + XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len); + } +} + +static unsigned long +xloadcolors(Display *dpy, Colormap cmap, const char *colstr) +{ + XColor color; + XAllocNamedColor(dpy, cmap, colstr, &color, &color); + return color.pixel; +} + +void +loadcolors(Display *dpy, int screen, Brush *b, + const char *bg, const char *fg, const char *border) +{ + Colormap cmap = DefaultColormap(dpy, screen); + b->bg = xloadcolors(dpy, cmap, bg); + b->fg = xloadcolors(dpy, cmap, fg); + b->border = xloadcolors(dpy, cmap, border); +} + +unsigned int +textnw(Fnt *font, char *text, unsigned int len) +{ + XRectangle r; + if(font->set) { + XmbTextExtents(font->set, text, len, NULL, &r); + return r.width; + } + return XTextWidth(font->xfont, text, len); +} + +unsigned int +textw(Fnt *font, char *text) +{ + return textnw(font, text, strlen(text)); +} + +unsigned int +texth(Fnt *font) +{ + return font->height + 4; +} + +void +loadfont(Display *dpy, Fnt *font, const char *fontstr) +{ + char **missing, *def; + int n; + + missing = NULL; + def = "?"; + setlocale(LC_ALL, ""); + if(font->set) + XFreeFontSet(dpy, font->set); + font->set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); + if(missing) { + while(n--) + fprintf(stderr, "missing fontset: %s\n", missing[n]); + XFreeStringList(missing); + if(font->set) { + XFreeFontSet(dpy, font->set); + font->set = NULL; + } + } + if(font->set) { + XFontSetExtents *font_extents; + XFontStruct **xfonts; + char **font_names; + unsigned int i; + + font->ascent = font->descent = 0; + font_extents = XExtentsOfFontSet(font->set); + n = XFontsOfFontSet(font->set, &xfonts, &font_names); + for(i = 0, font->ascent = 0, font->descent = 0; i < n; i++) { + if(font->ascent < (*xfonts)->ascent) + font->ascent = (*xfonts)->ascent; + if(font->descent < (*xfonts)->descent) + font->descent = (*xfonts)->descent; + xfonts++; + } + } + else { + if(font->xfont) + XFreeFont(dpy, font->xfont); + font->xfont = NULL; + font->xfont = XLoadQueryFont(dpy, fontstr); + if (!font->xfont) + font->xfont = XLoadQueryFont(dpy, "fixed"); + if (!font->xfont) + eprint("error, cannot load 'fixed' font\n"); + font->ascent = font->xfont->ascent; + font->descent = font->xfont->descent; + } + font->height = font->ascent + font->descent; +} diff --git a/dmenubar/main.c b/dmenubar/main.c new file mode 100644 index 0000000..18263d5 --- /dev/null +++ b/dmenubar/main.c @@ -0,0 +1,426 @@ +/* + * (C)opyright MMVI Anselm R. Garbe + * (C)opyright MMVI Sander van Dijk + * See LICENSE file for license details. + */ + +#include "dmenu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct Item Item; + +struct Item { + Item *next; /* traverses all items */ + Item *left, *right; /* traverses items matching current search pattern */ + char *text; +}; + +static Display *dpy; +static Window root; +static Window win; +static Bool done = False; + +static Item *allitem = NULL; /* first of all items */ +static Item *item = NULL; /* first of pattern matching items */ +static Item *sel = NULL; +static Item *nextoff = NULL; +static Item *prevoff = NULL; +static Item *curroff = NULL; + +static int screen, mx, my, mw, mh; +static char *title = NULL; +static char text[4096]; +static int ret = 0; +static int nitem = 0; +static unsigned int cmdw = 0; +static unsigned int tw = 0; +static unsigned int cw = 0; +static const int seek = 30; /* 30px */ + +static Brush brush = {0}; + +static void draw_menu(); +static void kpress(XKeyEvent * e); + +static char version[] = "dmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; + +static void +update_offsets() +{ + unsigned int tw, w = cmdw + 2 * seek; + + if(!curroff) + return; + + for(nextoff = curroff; nextoff; nextoff=nextoff->right) { + tw = textw(&brush.font, nextoff->text); + if(tw > mw / 3) + tw = mw / 3; + w += tw + brush.font.height; + if(w > mw) + break; + } + + w = cmdw + 2 * seek; + for(prevoff = curroff; prevoff && prevoff->left; prevoff=prevoff->left) { + tw = textw(&brush.font, prevoff->left->text); + if(tw > mw / 3) + tw = mw / 3; + w += tw + brush.font.height; + if(w > mw) + break; + } +} + +static void +update_items(char *pattern) +{ + unsigned int plen = strlen(pattern); + Item *i, *j; + + if(!pattern) + return; + + if(!title || *pattern) + cmdw = cw; + else + cmdw = tw; + + item = j = NULL; + nitem = 0; + + for(i = allitem; i; i=i->next) + if(!plen || !strncmp(pattern, i->text, plen)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + for(i = allitem; i; i=i->next) + if(plen && strncmp(pattern, i->text, plen) + && strstr(i->text, pattern)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + + curroff = prevoff = nextoff = sel = item; + + update_offsets(); +} + +/* creates brush structs for brush mode drawing */ +static void +draw_menu() +{ + Item *i; + + brush.x = 0; + brush.y = 0; + brush.w = mw; + brush.h = mh; + draw(dpy, &brush, False, 0); + + /* print command */ + if(!title || text[0]) { + cmdw = cw; + if(cmdw && item) + brush.w = cmdw; + draw(dpy, &brush, False, text); + } + else { + cmdw = tw; + brush.w = cmdw; + draw(dpy, &brush, False, title); + } + brush.x += brush.w; + + if(curroff) { + brush.w = seek; + draw(dpy, &brush, False, (curroff && curroff->left) ? "<" : 0); + brush.x += brush.w; + + /* determine maximum items */ + for(i = curroff; i != nextoff; i=i->right) { + brush.border = False; + brush.w = textw(&brush.font, i->text); + if(brush.w > mw / 3) + brush.w = mw / 3; + brush.w += brush.font.height; + if(sel == i) { + swap((void **)&brush.fg, (void **)&brush.bg); + draw(dpy, &brush, True, i->text); + swap((void **)&brush.fg, (void **)&brush.bg); + } + else + draw(dpy, &brush, False, i->text); + brush.x += brush.w; + } + + brush.x = mw - seek; + brush.w = seek; + draw(dpy, &brush, False, nextoff ? ">" : 0); + } + XCopyArea(dpy, brush.drawable, win, brush.gc, 0, 0, mw, mh, 0, 0); + XFlush(dpy); +} + +static void +kpress(XKeyEvent * e) +{ + KeySym ksym; + char buf[32]; + int num, prev_nitem; + unsigned int i, len = strlen(text); + + buf[0] = 0; + num = XLookupString(e, buf, sizeof(buf), &ksym, 0); + + if(IsFunctionKey(ksym) || IsKeypadKey(ksym) + || IsMiscFunctionKey(ksym) || IsPFKey(ksym) + || IsPrivateKeypadKey(ksym)) + return; + + /* first check if a control mask is omitted */ + if(e->state & ControlMask) { + switch (ksym) { + default: /* ignore other control sequences */ + return; + break; + case XK_h: + ksym = XK_BackSpace; + break; + case XK_U: + case XK_u: + text[0] = 0; + update_items(text); + draw_menu(); + return; + break; + case XK_bracketleft: + ksym = XK_Escape; + break; + } + } + switch(ksym) { + case XK_Left: + if(!(sel && sel->left)) + return; + sel=sel->left; + if(sel->right == curroff) { + curroff = prevoff; + update_offsets(); + } + break; + case XK_Tab: + if(!sel) + return; + strncpy(text, sel->text, sizeof(text)); + update_items(text); + break; + case XK_Right: + if(!(sel && sel->right)) + return; + sel=sel->right; + if(sel == nextoff) { + curroff = nextoff; + update_offsets(); + } + break; + case XK_Return: + if(e->state & ShiftMask) { + if(text) + fprintf(stdout, "%s", text); + } + else if(sel) + fprintf(stdout, "%s", sel->text); + else if(text) + fprintf(stdout, "%s", text); + fflush(stdout); + done = True; + break; + case XK_Escape: + ret = 1; + done = True; + break; + case XK_BackSpace: + if((i = len)) { + prev_nitem = nitem; + do { + text[--i] = 0; + update_items(text); + } while(i && nitem && prev_nitem == nitem); + update_items(text); + } + break; + default: + if(num && !iscntrl((int) buf[0])) { + buf[num] = 0; + if(len > 0) + strncat(text, buf, sizeof(text)); + else + strncpy(text, buf, sizeof(text)); + update_items(text); + } + } + draw_menu(); +} + +static char * +read_allitems() +{ + static char *maxname = NULL; + char *p, buf[1024]; + unsigned int len = 0, max = 0; + Item *i, *new; + + i = 0; + while(fgets(buf, sizeof(buf), stdin)) { + len = strlen(buf); + if (buf[len - 1] == '\n') + buf[len - 1] = 0; + p = estrdup(buf); + if(max < len) { + maxname = p; + max = len; + } + + new = emalloc(sizeof(Item)); + new->next = new->left = new->right = NULL; + new->text = p; + if(!i) + allitem = new; + else + i->next = new; + i = new; + } + + return maxname; +} + +int +main(int argc, char *argv[]) +{ + int i; + XSetWindowAttributes wa; + char *maxname; + XEvent ev; + + /* command line args */ + for(i = 1; i < argc; i++) { + if (argv[i][0] == '-') + switch (argv[i][1]) { + case 'v': + fprintf(stdout, "%s", version); + exit(0); + break; + case 't': + if(++i < argc) { + title = argv[i]; + break; + } + default: + eprint("usage: dmenu [-v] [-t ]\n"); + break; + } + else + eprint("usage: dmenu [-v] [-t <title>]\n"); + } + + dpy = XOpenDisplay(0); + if(!dpy) + eprint("dmenu: cannot open dpy\n"); + screen = DefaultScreen(dpy); + root = RootWindow(dpy, screen); + + maxname = read_allitems(); + + /* grab as early as possible, but after reading all items!!! */ + while(XGrabKeyboard(dpy, root, True, GrabModeAsync, + GrabModeAsync, CurrentTime) != GrabSuccess) + usleep(1000); + + /* style */ + loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR); + loadfont(dpy, &brush.font, FONT); + + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; + + mx = my = 0; + mw = DisplayWidth(dpy, screen); + mh = texth(&brush.font); + + win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); + XFlush(dpy); + + /* pixmap */ + brush.gc = XCreateGC(dpy, root, 0, 0); + brush.drawable = XCreatePixmap(dpy, win, mw, mh, + DefaultDepth(dpy, screen)); + XFlush(dpy); + + if(maxname) + cw = textw(&brush.font, maxname) + brush.font.height; + if(cw > mw / 3) + cw = mw / 3; + + if(title) { + tw = textw(&brush.font, title) + brush.font.height; + if(tw > mw / 3) + tw = mw / 3; + } + + cmdw = title ? tw : cw; + + text[0] = 0; + update_items(text); + XMapRaised(dpy, win); + draw_menu(); + XFlush(dpy); + + /* main event loop */ + while(!done && !XNextEvent(dpy, &ev)) { + switch (ev.type) { + case KeyPress: + kpress(&ev.xkey); + break; + case Expose: + if(ev.xexpose.count == 0) + draw_menu(); + break; + default: + break; + } + } + + XUngrabKeyboard(dpy, CurrentTime); + XFreePixmap(dpy, brush.drawable); + XFreeGC(dpy, brush.gc); + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); + + return ret; +} diff --git a/dmenubar/util.c b/dmenubar/util.c new file mode 100644 index 0000000..dff7af7 --- /dev/null +++ b/dmenubar/util.c @@ -0,0 +1,68 @@ +/* + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ +#include "dmenu.h" +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <unistd.h> + +/* static */ + +static void +bad_malloc(unsigned int size) +{ + eprint("fatal: could not malloc() %u bytes\n", size); +} + +/* extern */ + +void * +emalloc(unsigned int size) +{ + void *res = malloc(size); + if(!res) + bad_malloc(size); + return res; +} + +void * +emallocz(unsigned int size) +{ + void *res = calloc(1, size); + + if(!res) + bad_malloc(size); + return res; +} + +void +eprint(const char *errstr, ...) +{ + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +char * +estrdup(const char *str) +{ + void *res = strdup(str); + if(!res) + bad_malloc(strlen(str)); + return res; +} + +void +swap(void **p1, void **p2) +{ + void *tmp = *p1; + *p1 = *p2; + *p2 = tmp; +} From df9ed5f5f57e18b9e8b6e079b73d62b87a211a1e Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 10:23:36 +0200 Subject: [PATCH 002/590] rearranged several stuff --- dmenubar/LICENSE | 1 + dmenubar/config.mk | 2 +- dmenubar/dmenu.h | 29 ++--- dmenubar/draw.c | 188 ++++++++++++++++----------------- dmenubar/main.c | 256 +++++++++++++++++++++------------------------ dmenubar/util.c | 18 ---- 6 files changed, 222 insertions(+), 272 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index aa0a3ab..67e22c3 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,6 +1,7 @@ MIT/X Consortium License (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +(C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/config.mk b/dmenubar/config.mk index a4d21ac..2531d27 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,4 +1,4 @@ -# dwm version +# dmenu version VERSION = 0.0 # Customize below to fit your system diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 8d630ba..75b6266 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -7,6 +7,8 @@ #include <X11/Xlib.h> #include <X11/Xlocale.h> +#define SPACE 30 /* px */ + typedef struct Brush Brush; typedef struct DC DC; typedef struct Fnt Fnt; @@ -29,30 +31,17 @@ struct DC { /* draw context */ GC gc; }; -struct Brush { - GC gc; - Drawable drawable; - int x, y, w, h; - Fnt font; - unsigned long bg; - unsigned long fg; - unsigned long border; -}; - - +extern int screen; +extern Display *dpy; +extern DC dc; /* draw.c */ -extern void draw(Display *dpy, Brush *b, Bool border, const char *text); -extern void loadcolors(Display *dpy, int screen, Brush *b, - const char *bg, const char *fg, const char *bo); -extern void loadfont(Display *dpy, Fnt *font, const char *fontstr); -extern unsigned int textnw(Fnt *font, char *text, unsigned int len); -extern unsigned int textw(Fnt *font, char *text); -extern unsigned int texth(Fnt *font); +extern void drawtext(const char *text, Bool invert, Bool border); +extern unsigned long getcolor(const char *colstr); +extern void setfont(const char *fontstr); +extern unsigned int textw(const char *text); /* util.c */ extern void *emalloc(unsigned int size); -extern void *emallocz(unsigned int size); extern void eprint(const char *errstr, ...); extern char *estrdup(const char *str); -extern void swap(void **p1, void **p2); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index d747629..e0ff001 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -2,45 +2,62 @@ * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ - +#include "dmenu.h" #include <stdio.h> #include <string.h> +#include <X11/Xlocale.h> -#include "dmenu.h" +/* static */ static void -drawborder(Display *dpy, Brush *b) +drawborder(void) { XPoint points[5]; - XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter); - XSetForeground(dpy, b->gc, b->border); - points[0].x = b->x; - points[0].y = b->y; - points[1].x = b->w - 1; + + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + XSetForeground(dpy, dc.gc, dc.border); + points[0].x = dc.x; + points[0].y = dc.y; + points[1].x = dc.w - 1; points[1].y = 0; points[2].x = 0; - points[2].y = b->h - 1; - points[3].x = -(b->w - 1); + points[2].y = dc.h - 1; + points[3].x = -(dc.w - 1); points[3].y = 0; points[4].x = 0; - points[4].y = -(b->h - 1); - XDrawLines(dpy, b->drawable, b->gc, points, 5, CoordModePrevious); + points[4].y = -(dc.h - 1); + XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); } -void -draw(Display *dpy, Brush *b, Bool border, const char *text) +static unsigned int +textnw(const char *text, unsigned int len) { - unsigned int x, y, w, h, len; - static char buf[256]; - XGCValues gcv; - XRectangle r = { b->x, b->y, b->w, b->h }; + XRectangle r; - XSetForeground(dpy, b->gc, b->bg); - XFillRectangles(dpy, b->drawable, b->gc, &r, 1); + if(dc.font.set) { + XmbTextExtents(dc.font.set, text, len, NULL, &r); + return r.width; + } + return XTextWidth(dc.font.xfont, text, len); +} + +/* extern */ + +void +drawtext(const char *text, Bool invert, Bool border) +{ + int x, y, w, h; + static char buf[256]; + unsigned int len; + XGCValues gcv; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); w = 0; if(border) - drawborder(dpy, b); + drawborder(); if(!text) return; @@ -51,121 +68,94 @@ draw(Display *dpy, Brush *b, Bool border, const char *text) memcpy(buf, text, len); buf[len] = 0; - h = b->font.ascent + b->font.descent; - y = b->y + (b->h / 2) - (h / 2) + b->font.ascent; - x = b->x + (h / 2); + h = dc.font.ascent + dc.font.descent; + y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; + x = dc.x + (h / 2); /* shorten text if necessary */ - while(len && (w = textnw(&b->font, buf, len)) > b->w - h) + while(len && (w = textnw(buf, len)) > dc.w - h) buf[--len] = 0; - if(w > b->w) + if(w > dc.w) return; /* too long */ - gcv.foreground = b->fg; - gcv.background = b->bg; - if(b->font.set) { - XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv); - XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc, + gcv.foreground = invert ? dc.bg : dc.fg; + gcv.background = invert ? dc.fg : dc.bg; + if(dc.font.set) { + XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); + XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); } else { - gcv.font = b->font.xfont->fid; - XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv); - XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len); + gcv.font = dc.font.xfont->fid; + XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); + XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len); } } -static unsigned long -xloadcolors(Display *dpy, Colormap cmap, const char *colstr) +unsigned long +getcolor(const char *colstr) { + Colormap cmap = DefaultColormap(dpy, screen); XColor color; + XAllocNamedColor(dpy, cmap, colstr, &color, &color); return color.pixel; } void -loadcolors(Display *dpy, int screen, Brush *b, - const char *bg, const char *fg, const char *border) -{ - Colormap cmap = DefaultColormap(dpy, screen); - b->bg = xloadcolors(dpy, cmap, bg); - b->fg = xloadcolors(dpy, cmap, fg); - b->border = xloadcolors(dpy, cmap, border); -} - -unsigned int -textnw(Fnt *font, char *text, unsigned int len) -{ - XRectangle r; - if(font->set) { - XmbTextExtents(font->set, text, len, NULL, &r); - return r.width; - } - return XTextWidth(font->xfont, text, len); -} - -unsigned int -textw(Fnt *font, char *text) -{ - return textnw(font, text, strlen(text)); -} - -unsigned int -texth(Fnt *font) -{ - return font->height + 4; -} - -void -loadfont(Display *dpy, Fnt *font, const char *fontstr) +setfont(const char *fontstr) { char **missing, *def; - int n; + int i, n; missing = NULL; - def = "?"; setlocale(LC_ALL, ""); - if(font->set) - XFreeFontSet(dpy, font->set); - font->set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) { while(n--) fprintf(stderr, "missing fontset: %s\n", missing[n]); XFreeStringList(missing); - if(font->set) { - XFreeFontSet(dpy, font->set); - font->set = NULL; + if(dc.font.set) { + XFreeFontSet(dpy, dc.font.set); + dc.font.set = NULL; } } - if(font->set) { + if(dc.font.set) { XFontSetExtents *font_extents; XFontStruct **xfonts; char **font_names; - unsigned int i; - font->ascent = font->descent = 0; - font_extents = XExtentsOfFontSet(font->set); - n = XFontsOfFontSet(font->set, &xfonts, &font_names); - for(i = 0, font->ascent = 0, font->descent = 0; i < n; i++) { - if(font->ascent < (*xfonts)->ascent) - font->ascent = (*xfonts)->ascent; - if(font->descent < (*xfonts)->descent) - font->descent = (*xfonts)->descent; + 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(font->xfont) - XFreeFont(dpy, font->xfont); - font->xfont = NULL; - font->xfont = XLoadQueryFont(dpy, fontstr); - if (!font->xfont) - font->xfont = XLoadQueryFont(dpy, "fixed"); - if (!font->xfont) - eprint("error, cannot load 'fixed' font\n"); - font->ascent = font->xfont->ascent; - font->descent = font->xfont->descent; + if(dc.font.xfont) + XFreeFont(dpy, dc.font.xfont); + dc.font.xfont = NULL; + dc.font.xfont = XLoadQueryFont(dpy, fontstr); + if (!dc.font.xfont) + dc.font.xfont = XLoadQueryFont(dpy, "fixed"); + if (!dc.font.xfont) + eprint("error, cannot init 'fixed' font\n"); + dc.font.ascent = dc.font.xfont->ascent; + dc.font.descent = dc.font.xfont->descent; } - font->height = font->ascent + font->descent; + dc.font.height = dc.font.ascent + dc.font.descent; +} + +unsigned int +textw(const char *text) +{ + return textnw(text, strlen(text)) + dc.font.height; } diff --git a/dmenubar/main.c b/dmenubar/main.c index 18263d5..14524c9 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -16,74 +16,112 @@ #include <X11/keysym.h> typedef struct Item Item; - struct Item { Item *next; /* traverses all items */ Item *left, *right; /* traverses items matching current search pattern */ char *text; }; -static Display *dpy; -static Window root; -static Window win; -static Bool done = False; +/* static */ -static Item *allitem = NULL; /* first of all items */ -static Item *item = NULL; /* first of pattern matching items */ -static Item *sel = NULL; -static Item *nextoff = NULL; -static Item *prevoff = NULL; -static Item *curroff = NULL; - -static int screen, mx, my, mw, mh; -static char *title = NULL; -static char text[4096]; +static char *title, text[4096]; +static int mx, my, mw, mh; static int ret = 0; static int nitem = 0; static unsigned int cmdw = 0; static unsigned int tw = 0; static unsigned int cw = 0; -static const int seek = 30; /* 30px */ - -static Brush brush = {0}; - -static void draw_menu(); -static void kpress(XKeyEvent * e); - -static char version[] = "dmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; +static Bool done = False; +static Item *allitems = NULL; /* first of all items */ +static Item *item = NULL; /* first of pattern matching items */ +static Item *sel = NULL; +static Item *next = NULL; +static Item *prev = NULL; +static Item *curr = NULL; +static Window root; +static Window win; static void -update_offsets() +calcoffsets() { - unsigned int tw, w = cmdw + 2 * seek; + unsigned int tw, w; - if(!curroff) + if(!curr) return; - for(nextoff = curroff; nextoff; nextoff=nextoff->right) { - tw = textw(&brush.font, nextoff->text); + w = cmdw + 2 * SPACE; + for(next = curr; next; next=next->right) { + tw = textw(next->text); if(tw > mw / 3) tw = mw / 3; - w += tw + brush.font.height; + w += tw; if(w > mw) break; } - w = cmdw + 2 * seek; - for(prevoff = curroff; prevoff && prevoff->left; prevoff=prevoff->left) { - tw = textw(&brush.font, prevoff->left->text); + w = cmdw + 2 * SPACE; + for(prev = curr; prev && prev->left; prev=prev->left) { + tw = textw(prev->left->text); if(tw > mw / 3) tw = mw / 3; - w += tw + brush.font.height; + w += tw; if(w > mw) break; } } static void -update_items(char *pattern) +drawmenu() { - unsigned int plen = strlen(pattern); + Item *i; + + dc.x = 0; + dc.y = 0; + dc.w = mw; + dc.h = mh; + drawtext(NULL, False, False); + + /* print command */ + if(!title || text[0]) { + cmdw = cw; + if(cmdw && item) + dc.w = cmdw; + drawtext(text, False, False); + } + else { + cmdw = tw; + dc.w = cmdw; + drawtext(title, False, False); + } + dc.x += dc.w; + + if(curr) { + dc.w = SPACE; + drawtext((curr && curr->left) ? "<" : NULL, False, False); + dc.x += dc.w; + + /* determine maximum items */ + for(i = curr; i != next; i=i->right) { + dc.border = False; + dc.w = textw(i->text); + if(dc.w > mw / 3) + dc.w = mw / 3; + drawtext(i->text, sel == i, sel == i); + dc.x += dc.w; + } + + dc.x = mw - SPACE; + dc.w = SPACE; + drawtext(next ? ">" : NULL, False, False); + } + XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); + XFlush(dpy); +} + +static void +input(char *pattern) +{ + unsigned int plen; Item *i, *j; if(!pattern) @@ -94,10 +132,11 @@ update_items(char *pattern) else cmdw = tw; + plen = strlen(pattern); item = j = NULL; nitem = 0; - for(i = allitem; i; i=i->next) + for(i = allitems; i; i=i->next) if(!plen || !strncmp(pattern, i->text, plen)) { if(!j) item = i; @@ -108,7 +147,7 @@ update_items(char *pattern) j = i; nitem++; } - for(i = allitem; i; i=i->next) + for(i = allitems; i; i=i->next) if(plen && strncmp(pattern, i->text, plen) && strstr(i->text, pattern)) { if(!j) @@ -121,75 +160,19 @@ update_items(char *pattern) nitem++; } - curroff = prevoff = nextoff = sel = item; - - update_offsets(); -} - -/* creates brush structs for brush mode drawing */ -static void -draw_menu() -{ - Item *i; - - brush.x = 0; - brush.y = 0; - brush.w = mw; - brush.h = mh; - draw(dpy, &brush, False, 0); - - /* print command */ - if(!title || text[0]) { - cmdw = cw; - if(cmdw && item) - brush.w = cmdw; - draw(dpy, &brush, False, text); - } - else { - cmdw = tw; - brush.w = cmdw; - draw(dpy, &brush, False, title); - } - brush.x += brush.w; - - if(curroff) { - brush.w = seek; - draw(dpy, &brush, False, (curroff && curroff->left) ? "<" : 0); - brush.x += brush.w; - - /* determine maximum items */ - for(i = curroff; i != nextoff; i=i->right) { - brush.border = False; - brush.w = textw(&brush.font, i->text); - if(brush.w > mw / 3) - brush.w = mw / 3; - brush.w += brush.font.height; - if(sel == i) { - swap((void **)&brush.fg, (void **)&brush.bg); - draw(dpy, &brush, True, i->text); - swap((void **)&brush.fg, (void **)&brush.bg); - } - else - draw(dpy, &brush, False, i->text); - brush.x += brush.w; - } - - brush.x = mw - seek; - brush.w = seek; - draw(dpy, &brush, False, nextoff ? ">" : 0); - } - XCopyArea(dpy, brush.drawable, win, brush.gc, 0, 0, mw, mh, 0, 0); - XFlush(dpy); + curr = prev = next = sel = item; + calcoffsets(); } static void kpress(XKeyEvent * e) { - KeySym ksym; char buf[32]; int num, prev_nitem; - unsigned int i, len = strlen(text); + unsigned int i, len; + KeySym ksym; + len = strlen(text); buf[0] = 0; num = XLookupString(e, buf, sizeof(buf), &ksym, 0); @@ -210,8 +193,8 @@ kpress(XKeyEvent * e) case XK_U: case XK_u: text[0] = 0; - update_items(text); - draw_menu(); + input(text); + drawmenu(); return; break; case XK_bracketleft: @@ -224,24 +207,24 @@ kpress(XKeyEvent * e) if(!(sel && sel->left)) return; sel=sel->left; - if(sel->right == curroff) { - curroff = prevoff; - update_offsets(); + if(sel->right == curr) { + curr = prev; + calcoffsets(); } break; case XK_Tab: if(!sel) return; strncpy(text, sel->text, sizeof(text)); - update_items(text); + input(text); break; case XK_Right: if(!(sel && sel->right)) return; sel=sel->right; - if(sel == nextoff) { - curroff = nextoff; - update_offsets(); + if(sel == next) { + curr = next; + calcoffsets(); } break; case XK_Return: @@ -265,9 +248,9 @@ kpress(XKeyEvent * e) prev_nitem = nitem; do { text[--i] = 0; - update_items(text); + input(text); } while(i && nitem && prev_nitem == nitem); - update_items(text); + input(text); } break; default: @@ -277,14 +260,14 @@ kpress(XKeyEvent * e) strncat(text, buf, sizeof(text)); else strncpy(text, buf, sizeof(text)); - update_items(text); + input(text); } } - draw_menu(); + drawmenu(); } static char * -read_allitems() +readinput() { static char *maxname = NULL; char *p, buf[1024]; @@ -306,7 +289,7 @@ read_allitems() new->next = new->left = new->right = NULL; new->text = p; if(!i) - allitem = new; + allitems = new; else i->next = new; i = new; @@ -315,21 +298,27 @@ read_allitems() return maxname; } +/* extern */ + +int screen; +Display *dpy; +DC dc = {0}; + int main(int argc, char *argv[]) { - int i; - XSetWindowAttributes wa; char *maxname; + int i; XEvent ev; + XSetWindowAttributes wa; /* command line args */ for(i = 1; i < argc; i++) { if (argv[i][0] == '-') switch (argv[i][1]) { case 'v': - fprintf(stdout, "%s", version); - exit(0); + fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); + exit(EXIT_SUCCESS); break; case 't': if(++i < argc) { @@ -350,7 +339,7 @@ main(int argc, char *argv[]) screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - maxname = read_allitems(); + maxname = readinput(); /* grab as early as possible, but after reading all items!!! */ while(XGrabKeyboard(dpy, root, True, GrabModeAsync, @@ -358,8 +347,10 @@ main(int argc, char *argv[]) usleep(1000); /* style */ - loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR); - loadfont(dpy, &brush.font, FONT); + dc.bg = getcolor(BGCOLOR); + dc.fg = getcolor(FGCOLOR); + dc.border = getcolor(BORDERCOLOR); + setfont(FONT); wa.override_redirect = 1; wa.background_pixmap = ParentRelative; @@ -367,28 +358,25 @@ main(int argc, char *argv[]) mx = my = 0; mw = DisplayWidth(dpy, screen); - mh = texth(&brush.font); + mh = dc.font.height + 4; win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); - XFlush(dpy); /* pixmap */ - brush.gc = XCreateGC(dpy, root, 0, 0); - brush.drawable = XCreatePixmap(dpy, win, mw, mh, - DefaultDepth(dpy, screen)); - XFlush(dpy); + dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, root, 0, 0); if(maxname) - cw = textw(&brush.font, maxname) + brush.font.height; + cw = textw(maxname); if(cw > mw / 3) cw = mw / 3; if(title) { - tw = textw(&brush.font, title) + brush.font.height; + tw = textw(title); if(tw > mw / 3) tw = mw / 3; } @@ -396,10 +384,10 @@ main(int argc, char *argv[]) cmdw = title ? tw : cw; text[0] = 0; - update_items(text); + input(text); XMapRaised(dpy, win); - draw_menu(); - XFlush(dpy); + drawmenu(); + XSync(dpy, False); /* main event loop */ while(!done && !XNextEvent(dpy, &ev)) { @@ -409,7 +397,7 @@ main(int argc, char *argv[]) break; case Expose: if(ev.xexpose.count == 0) - draw_menu(); + drawmenu(); break; default: break; @@ -417,8 +405,8 @@ main(int argc, char *argv[]) } XUngrabKeyboard(dpy, CurrentTime); - XFreePixmap(dpy, brush.drawable); - XFreeGC(dpy, brush.gc); + XFreePixmap(dpy, dc.drawable); + XFreeGC(dpy, dc.gc); XDestroyWindow(dpy, win); XCloseDisplay(dpy); diff --git a/dmenubar/util.c b/dmenubar/util.c index dff7af7..1b9bc57 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -29,16 +29,6 @@ emalloc(unsigned int size) return res; } -void * -emallocz(unsigned int size) -{ - void *res = calloc(1, size); - - if(!res) - bad_malloc(size); - return res; -} - void eprint(const char *errstr, ...) { @@ -58,11 +48,3 @@ estrdup(const char *str) bad_malloc(strlen(str)); return res; } - -void -swap(void **p1, void **p2) -{ - void *tmp = *p1; - *p1 = *p2; - *p2 = tmp; -} From 5ccd388d47dcc5ded9c45de5f7058073e0ee6631 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 10:31:05 +0200 Subject: [PATCH 003/590] remove stderr spitting --- dmenubar/draw.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index e0ff001..7507595 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -115,8 +115,6 @@ setfont(const char *fontstr) XFreeFontSet(dpy, dc.font.set); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) { - while(n--) - fprintf(stderr, "missing fontset: %s\n", missing[n]); XFreeStringList(missing); if(dc.font.set) { XFreeFontSet(dpy, dc.font.set); From c22bf1d29c7e11fde3472104453542fb0a64ece3 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 10:31:25 +0200 Subject: [PATCH 004/590] prepared 0.1 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 2531d27..27e1e2e 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.0 +VERSION = 0.1 # Customize below to fit your system From a3cc865f15880d38d33978312b1365a20478d089 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 10:31:51 +0200 Subject: [PATCH 005/590] Added tag 0.1 for changeset fcc8a282cb52c6a9343b461026b386825590cd31 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 dmenubar/.hgtags diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags new file mode 100644 index 0000000..d3f3eac --- /dev/null +++ b/dmenubar/.hgtags @@ -0,0 +1 @@ +fcc8a282cb52c6a9343b461026b386825590cd31 0.1 From 21fcab3b2ae9edd6dbf07f492b99c65c122e4622 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 10:32:15 +0200 Subject: [PATCH 006/590] removed config.h --- dmenubar/config.h | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 dmenubar/config.h diff --git a/dmenubar/config.h b/dmenubar/config.h deleted file mode 100644 index 008161d..0000000 --- a/dmenubar/config.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#0a2c2d" -#define FGCOLOR "#ddeeee" -#define BORDERCOLOR "#176164" From 294b42fa5f51bcee6364f4eda76b29840bf9daf9 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 10:34:44 +0200 Subject: [PATCH 007/590] fixed dist target --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 0cfd20d..cbe4026 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -36,7 +36,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk \ + @cp -R LICENSE Makefile README config.*.h config.mk \ dmenu.1 dmenu.h ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar From f54c9e289f60abb8bd7ecf5cec3c3fe4fc378b8b Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 17:15:07 +0200 Subject: [PATCH 008/590] fixed README of dmenu --- dmenubar/README | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/dmenubar/README b/dmenubar/README index 5915a27..2aecc78 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,11 +1,12 @@ -dwm - dynamic window manager ----------------------------- -dwm is an extremely fast, small, and dynamic X11 window manager. +dmenu - dynamic menu +-------------------- +dwm is a generic, highly customizable, and efficient menu for the X Window +System. Requirements ------------ -In order to build dwm you need the Xlib header files. +In order to build dmenu you need the Xlib header files. Installation @@ -13,36 +14,18 @@ Installation Edit config.mk to match your local setup (dwm is installed into the /usr/local namespace by default). -Afterwards enter the following command to build and install dwm (if +Afterwards enter the following command to build and install dmenu (if necessary as root): make clean install -Running dwm ------------ -Add the following line to your .xinitrc to start dwm using startx: - - exec dwm - -In order to connect dwm to a specific display, make sure that -the DISPLAY environment variable is set correctly, e.g.: - - DISPLAY=foo.bar:1 exec dwm - -(This will start dwm on display :1 of the host foo.bar.) - -In order to display status info in the bar, you can do something -like this in your .xinitrc: - - while true - do - echo `date` `uptime | sed 's/.*://; s/,//g'` - sleep 1 - done | dwm +Running dmenu +------------- +See the man page for details. Configuration ------------- -The configuration of dwm is done by creating a custom config.h +The configuration of dmenu is done by creating a custom config.h and (re)compiling the source code. From 1887c46f92dbba2a42bf67490b5202035f37dd58 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Fri, 4 Aug 2006 17:17:03 +0200 Subject: [PATCH 009/590] yet another fix --- dmenubar/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/README b/dmenubar/README index 2aecc78..218c6a6 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,7 +1,7 @@ dmenu - dynamic menu -------------------- -dwm is a generic, highly customizable, and efficient menu for the X Window -System. +dwm is a generic, highly customizable, and efficient menu for the +X Window System. Requirements From 4c81a74ed241cab4bae710a4d31552c857eb7ee0 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Sat, 5 Aug 2006 14:05:04 +0200 Subject: [PATCH 010/590] small change --- dmenubar/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 14524c9..32b08b9 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -335,7 +335,7 @@ main(int argc, char *argv[]) dpy = XOpenDisplay(0); if(!dpy) - eprint("dmenu: cannot open dpy\n"); + eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); From e55c52827477225dcd1e5dfa54476a7d6a9a60aa Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Sat, 5 Aug 2006 14:57:51 +0200 Subject: [PATCH 011/590] menu now also uses -Os --- dmenubar/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 27e1e2e..bcd012f 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.1 +VERSION = 0.2 # Customize below to fit your system @@ -15,7 +15,7 @@ INCS = -I/usr/lib -I${X11INC} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags -CFLAGS = -O3 ${INCS} -DVERSION=\"${VERSION}\" +CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" LDFLAGS = ${LIBS} #CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = -g ${LIBS} From dc85885c0702e1f05eb0dfa625b0f4b74e4202b5 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 07:30:13 +0200 Subject: [PATCH 012/590] removed -t title crap from dmenu --- dmenubar/dmenu.1 | 7 ------ dmenubar/main.c | 62 ++++++++++-------------------------------------- 2 files changed, 12 insertions(+), 57 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index da69047..4dbef65 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -4,8 +4,6 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu .RB [ \-v ] -.RB [ \-t -.IR title ] .SH DESCRIPTION .SS Overview .B dmenu @@ -17,11 +15,6 @@ It supports arbitrary, user defined menu contents. .TP .B \-v prints version information to stdout, then exits. -.TP -.BI \-t " title" -displays -.I title -above the menu. .SS Usage .B dmenu reads a list of newline-separated items from stdin and creates a menu. diff --git a/dmenubar/main.c b/dmenubar/main.c index 32b08b9..f151819 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -24,13 +24,11 @@ struct Item { /* static */ -static char *title, text[4096]; +static char text[4096]; static int mx, my, mw, mh; static int ret = 0; static int nitem = 0; static unsigned int cmdw = 0; -static unsigned int tw = 0; -static unsigned int cw = 0; static Bool done = False; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ @@ -82,18 +80,10 @@ drawmenu() drawtext(NULL, False, False); /* print command */ - if(!title || text[0]) { - cmdw = cw; - if(cmdw && item) - dc.w = cmdw; - drawtext(text, False, False); - } - else { - cmdw = tw; + if(cmdw && item) dc.w = cmdw; - drawtext(title, False, False); - } - dc.x += dc.w; + drawtext(text[0] ? text : NULL, False, False); + dc.x += cmdw; if(curr) { dc.w = SPACE; @@ -127,11 +117,6 @@ input(char *pattern) if(!pattern) return; - if(!title || *pattern) - cmdw = cw; - else - cmdw = tw; - plen = strlen(pattern); item = j = NULL; nitem = 0; @@ -308,30 +293,15 @@ int main(int argc, char *argv[]) { char *maxname; - int i; XEvent ev; XSetWindowAttributes wa; - /* command line args */ - for(i = 1; i < argc; i++) { - if (argv[i][0] == '-') - switch (argv[i][1]) { - case 'v': - fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); - exit(EXIT_SUCCESS); - break; - case 't': - if(++i < argc) { - title = argv[i]; - break; - } - default: - eprint("usage: dmenu [-v] [-t <title>]\n"); - break; - } - else - eprint("usage: dmenu [-v] [-t <title>]\n"); + if(argc == 2 && !strncmp("-v", argv[1], 3)) { + fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); + exit(EXIT_SUCCESS); } + else if(argc != 1) + eprint("usage: dmenu [-v]\n"); dpy = XOpenDisplay(0); if(!dpy) @@ -371,17 +341,9 @@ main(int argc, char *argv[]) dc.gc = XCreateGC(dpy, root, 0, 0); if(maxname) - cw = textw(maxname); - if(cw > mw / 3) - cw = mw / 3; - - if(title) { - tw = textw(title); - if(tw > mw / 3) - tw = mw / 3; - } - - cmdw = title ? tw : cw; + cmdw = textw(maxname); + if(cmdw > mw / 3) + cmdw = mw / 3; text[0] = 0; input(text); From 4afb1bca3f550561873b65cbfe757fbce076506f Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 07:36:18 +0200 Subject: [PATCH 013/590] updated man page --- dmenubar/dmenu.1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 4dbef65..aa3c776 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -57,5 +57,9 @@ returns if Enter is pressed on termination, .B 1 if Escape is pressed. +.SH CUSTOMIZATION +.B dwm +is customized by creating a custom config.h and (re)compiling the source +code. This keeps it fast, secure and simple. .SH SEE ALSO .BR dwm (1) From e0726de3f957d3a590a5816a81445ca51fb74b9c Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 07:37:32 +0200 Subject: [PATCH 014/590] updated man page --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index aa3c776..354a75e 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -58,7 +58,7 @@ if Enter is pressed on termination, .B 1 if Escape is pressed. .SH CUSTOMIZATION -.B dwm +.B dmenu is customized by creating a custom config.h and (re)compiling the source code. This keeps it fast, secure and simple. .SH SEE ALSO From 16e4d69fff8b1090fda5a6b411e97c2503ea0f9b Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 07:39:31 +0200 Subject: [PATCH 015/590] renamed some functions to make it more readable --- dmenubar/main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index f151819..ee32011 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -109,7 +109,7 @@ drawmenu() } static void -input(char *pattern) +match(char *pattern) { unsigned int plen; Item *i, *j; @@ -178,7 +178,7 @@ kpress(XKeyEvent * e) case XK_U: case XK_u: text[0] = 0; - input(text); + match(text); drawmenu(); return; break; @@ -201,7 +201,7 @@ kpress(XKeyEvent * e) if(!sel) return; strncpy(text, sel->text, sizeof(text)); - input(text); + match(text); break; case XK_Right: if(!(sel && sel->right)) @@ -233,9 +233,9 @@ kpress(XKeyEvent * e) prev_nitem = nitem; do { text[--i] = 0; - input(text); + match(text); } while(i && nitem && prev_nitem == nitem); - input(text); + match(text); } break; default: @@ -245,14 +245,14 @@ kpress(XKeyEvent * e) strncat(text, buf, sizeof(text)); else strncpy(text, buf, sizeof(text)); - input(text); + match(text); } } drawmenu(); } static char * -readinput() +readstdin() { static char *maxname = NULL; char *p, buf[1024]; @@ -309,7 +309,7 @@ main(int argc, char *argv[]) screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - maxname = readinput(); + maxname = readstdin(); /* grab as early as possible, but after reading all items!!! */ while(XGrabKeyboard(dpy, root, True, GrabModeAsync, @@ -346,7 +346,7 @@ main(int argc, char *argv[]) cmdw = mw / 3; text[0] = 0; - input(text); + match(text); XMapRaised(dpy, win); drawmenu(); XSync(dpy, False); From ecec3c87ae3ccd775ae2225fdd1d606ad7733780 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 08:40:26 +0200 Subject: [PATCH 016/590] fixed a bad mistake setting the dmenu border to False; --- dmenubar/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index ee32011..561f88f 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -92,7 +92,6 @@ drawmenu() /* determine maximum items */ for(i = curr; i != next; i=i->right) { - dc.border = False; dc.w = textw(i->text); if(dc.w > mw / 3) dc.w = mw / 3; From 895db5e046fa019bae55fc6e5ee2d0de137b2e79 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 08:45:47 +0200 Subject: [PATCH 017/590] added stripping to dmenu target --- dmenubar/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index cbe4026..fc8dcd2 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -28,6 +28,7 @@ config.h: dmenu: ${OBJ} @echo LD $@ @${CC} -o $@ ${OBJ} ${LDFLAGS} + @strip $@ clean: @echo cleaning From 86f8f62a642f6103ddd7c32a4f038e212d21bb1f Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 08:52:37 +0200 Subject: [PATCH 018/590] Added tag 0.2 for changeset 656be0f47df545dfdd2e1e0663663b8b1b26f031 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index d3f3eac..5fd0570 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -1 +1,2 @@ fcc8a282cb52c6a9343b461026b386825590cd31 0.1 +656be0f47df545dfdd2e1e0663663b8b1b26f031 0.2 From 70f521e1e44e4345059f6392ec21e025866856d6 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 09:40:28 +0200 Subject: [PATCH 019/590] next attempt for bright background switch --- dmenubar/config.arg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 008161d..a1f243b 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#0a2c2d" -#define FGCOLOR "#ddeeee" -#define BORDERCOLOR "#176164" +#define BGCOLOR "#eaffff" +#define FGCOLOR "#000000" +#define BORDERCOLOR "#8888cc" From f787fd5255378b5d8a13045af2324a7eb83573a6 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 10:28:42 +0200 Subject: [PATCH 020/590] also made my colors tasting better with my overall colorscheme --- dmenubar/config.arg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index a1f243b..b2953f3 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#eaffff" -#define FGCOLOR "#000000" -#define BORDERCOLOR "#8888cc" +#define BGCOLOR "#663333" +#define FGCOLOR "#ffffff" +#define BORDERCOLOR "#993333" From 2695be4b7de7ce1cff84d3796b79992ea635643d Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 10:32:18 +0200 Subject: [PATCH 021/590] next version is 0.3 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index bcd012f..572d192 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.2 +VERSION = 0.3 # Customize below to fit your system From 9cc1b6dcb8be407580df88689248e549405f655d Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 11:10:05 +0200 Subject: [PATCH 022/590] settle with grey --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index b2953f3..39f2351 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#663333" +#define BGCOLOR "#444444" #define FGCOLOR "#ffffff" -#define BORDERCOLOR "#993333" +#define BORDERCOLOR "#222222" From 86b2abdb83a4527e6cfb6d3edcd8931a235d4619 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 11:11:17 +0200 Subject: [PATCH 023/590] fixed dmenu.1 version info --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 354a75e..f49dda9 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -1,4 +1,4 @@ -.TH DMENU 1 d-0.0 +.TH DMENU 1 d-0.3 .SH NAME dmenu \- dynamic menu .SH SYNOPSIS From 3fa69e4bef73d2ff20a26c7cdda9bbe1d87b64a3 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 11:58:23 +0200 Subject: [PATCH 024/590] appliead Sanders manpage/Makefile pacth --- dmenubar/Makefile | 2 +- dmenubar/dmenu.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index fc8dcd2..d170037 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -50,7 +50,7 @@ install: all @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 @mkdir -p ${DESTDIR}${MANPREFIX}/man1 - @cp -f dmenu.1 ${DESTDIR}${MANPREFIX}/man1 + @sed 's/VERSION/${VERSION}/g' < dmenu.1 > ${DESTDIR}${MANPREFIX}/man1/dmenu.1 @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 uninstall: diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index f49dda9..3387c7a 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -1,4 +1,4 @@ -.TH DMENU 1 d-0.3 +.TH DMENU 1 dmenu-VERSION .SH NAME dmenu \- dynamic menu .SH SYNOPSIS From b11c12a1c0394e5f638ab5598009b26ea0c01d0d Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 12:21:31 +0200 Subject: [PATCH 025/590] font size changed as well --- dmenubar/config.arg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 39f2351..5e63805 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -3,7 +3,7 @@ * See LICENSE file for license details. */ -#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*" +#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" #define BGCOLOR "#444444" #define FGCOLOR "#ffffff" #define BORDERCOLOR "#222222" From 6cc4d37f376cab1aaac1cc015329f70ffcf8e0d4 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 14:07:04 +0200 Subject: [PATCH 026/590] made dmenu(1) more dwm(1) alike --- dmenubar/dmenu.1 | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 3387c7a..7a45503 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -15,46 +15,45 @@ It supports arbitrary, user defined menu contents. .TP .B \-v prints version information to stdout, then exits. -.SS Usage +.SH USAGE .B dmenu reads a list of newline-separated items from stdin and creates a menu. -When the user selects an item or enters any text and presses Enter, his choice +When the user selects an item or enters any text and presses Return, his choice is printed to stdout and .B dmenu terminates. -.SS Keyboard Control .B dmenu is completely controlled by the keyboard. The following keys are recognized: -.TP 2 +.TP 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. -.TP 2 +.TP Left/Right (Control-p/Control-n) -select the previous/next item. -.TP 2 +Select the previous/next item. +.TP Tab (Control-i) -copy the selected item to the input field. -.TP 2 -Enter (Control-j) -confirm selection and quit (print the selected item to stdout). -.TP 2 -Shift-Enter (Shift-Control-j) -confirm selection and quit (print the text in the input field to stdout). -.TP 2 +Copy the selected item to the input field. +.TP +Return (Control-j) +Confirm selection and quit (print the selected item to stdout). +.TP +Shift-Return (Shift-Control-j) +Confirm selection and quit (print the text in the input field to stdout). +.TP Escape (Control-[) -quit without selecting an item. -.TP 2 +Quit without selecting an item. +.TP Backspace (Control-h) -remove enough characters from the input field to change its filtering effect. -.TP 2 +Remove enough characters from the input field to change its filtering effect. +.TP Control-u -remove all characters from the input field. -.SS Exit codes +Remove all characters from the input field. +.P .B dmenu returns .B 0 -if Enter is pressed on termination, +if Return is pressed on termination, .B 1 if Escape is pressed. .SH CUSTOMIZATION From e7502fe8769203119fdc049a6cc2d0a2d458bbf7 Mon Sep 17 00:00:00 2001 From: "arg@10ksloc.org" <unknown> Date: Mon, 7 Aug 2006 17:17:27 +0200 Subject: [PATCH 027/590] removed unnecessary typedef --- dmenubar/dmenu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 75b6266..2a8796f 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -9,7 +9,6 @@ #define SPACE 30 /* px */ -typedef struct Brush Brush; typedef struct DC DC; typedef struct Fnt Fnt; From 81c97ec0129b979beb0d4fc3f3445557a466b8fc Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 8 Aug 2006 11:07:12 +0200 Subject: [PATCH 028/590] using a better colorscheme --- dmenubar/config.arg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 5e63805..9785a4b 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -5,5 +5,5 @@ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" #define BGCOLOR "#444444" -#define FGCOLOR "#ffffff" +#define FGCOLOR "#ffffaa" #define BORDERCOLOR "#222222" From c5275af65875254a0870382e0169638bb3790d43 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 8 Aug 2006 11:18:23 +0200 Subject: [PATCH 029/590] dito --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 9785a4b..cb0e1b6 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#444444" +#define BGCOLOR "#800000" #define FGCOLOR "#ffffaa" -#define BORDERCOLOR "#222222" +#define BORDERCOLOR "#000000" From cc4e305be1bfb6f64d2e45d5ca8de506a10ddf83 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 8 Aug 2006 11:47:58 +0200 Subject: [PATCH 030/590] noborder --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index cb0e1b6..127edab 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#800000" +#define BGCOLOR "#004080" #define FGCOLOR "#ffffaa" -#define BORDERCOLOR "#000000" +#define BORDERCOLOR "#004080" From 5eec4420fcceff5cbf25b6bab6a4b98a64060ed7 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 8 Aug 2006 12:47:58 +0200 Subject: [PATCH 031/590] default colors are best --- dmenubar/config.arg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 127edab..066c1a4 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#004080" -#define FGCOLOR "#ffffaa" -#define BORDERCOLOR "#004080" +#define BGCOLOR "#666699" +#define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#9999CC" From 346122f7b0529b17a6fd0bd2f0995304550bebdd Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 8 Aug 2006 17:14:35 +0200 Subject: [PATCH 032/590] fixes to README --- dmenubar/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/README b/dmenubar/README index 218c6a6..96f8b9a 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,6 +1,6 @@ dmenu - dynamic menu -------------------- -dwm is a generic, highly customizable, and efficient menu for the +dmenu is a generic, highly customizable, and efficient menu for the X Window System. @@ -11,7 +11,7 @@ In order to build dmenu you need the Xlib header files. Installation ------------ -Edit config.mk to match your local setup (dwm is installed into +Edit config.mk to match your local setup (dmenu is installed into the /usr/local namespace by default). Afterwards enter the following command to build and install dmenu (if From 96b22369120bae88efbb4652fe65cf1789385195 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Wed, 9 Aug 2006 18:45:32 +0200 Subject: [PATCH 033/590] removed control sequences which actually aren't implemented anymore (only the real unix control sequences are implemented) --- dmenubar/dmenu.1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 7a45503..db919db 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -29,16 +29,16 @@ Any printable character Appends the character to the text in the input field. This works as a filter: only items containing this text will be displayed. .TP -Left/Right (Control-p/Control-n) +Left/Right Select the previous/next item. .TP -Tab (Control-i) +Tab Copy the selected item to the input field. .TP -Return (Control-j) +Return Confirm selection and quit (print the selected item to stdout). .TP -Shift-Return (Shift-Control-j) +Shift-Return Confirm selection and quit (print the text in the input field to stdout). .TP Escape (Control-[) From b5b01c0f24630f74901975fa630864440be88d7f Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 10:09:44 +0200 Subject: [PATCH 034/590] removed C-[ from source and man page --- dmenubar/dmenu.1 | 2 +- dmenubar/main.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index db919db..926b559 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -41,7 +41,7 @@ Confirm selection and quit (print the selected item to stdout). Shift-Return Confirm selection and quit (print the text in the input field to stdout). .TP -Escape (Control-[) +Escape Quit without selecting an item. .TP Backspace (Control-h) diff --git a/dmenubar/main.c b/dmenubar/main.c index 561f88f..3458fd5 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -174,16 +174,12 @@ kpress(XKeyEvent * e) case XK_h: ksym = XK_BackSpace; break; - case XK_U: case XK_u: text[0] = 0; match(text); drawmenu(); return; break; - case XK_bracketleft: - ksym = XK_Escape; - break; } } switch(ksym) { From fc3abad9ac631eaf0f484dbc31eac1b59e877b64 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 10:10:32 +0200 Subject: [PATCH 035/590] added uppercase chars for C-u and C-h as well --- dmenubar/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dmenubar/main.c b/dmenubar/main.c index 3458fd5..3b9a24b 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -172,9 +172,11 @@ kpress(XKeyEvent * e) return; break; case XK_h: + case XK_H: ksym = XK_BackSpace; break; case XK_u: + case XK_U: text[0] = 0; match(text); drawmenu(); From b5f20cf31062886fa0da7a181be56f101b99397e Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 10:21:50 +0200 Subject: [PATCH 036/590] swapping my default colors --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 066c1a4..c5e1874 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#666699" -#define FGCOLOR "#eeeeee" +#define BGCOLOR "#eeeeee" +#define FGCOLOR "#666699" #define BORDERCOLOR "#9999CC" From e94a87eb46d33b875f42674161dbe8a6400f752d Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 10:28:58 +0200 Subject: [PATCH 037/590] removed unnecessary border color --- dmenubar/config.arg.h | 1 - dmenubar/config.default.h | 1 - dmenubar/dmenu.h | 3 +-- dmenubar/draw.c | 25 +------------------------ dmenubar/main.c | 11 +++++------ 5 files changed, 7 insertions(+), 34 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index c5e1874..30c422d 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -6,4 +6,3 @@ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" #define BGCOLOR "#eeeeee" #define FGCOLOR "#666699" -#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index cf1baea..0b1abb4 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -6,4 +6,3 @@ #define FONT "fixed" #define BGCOLOR "#666699" #define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 2a8796f..f118196 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -24,7 +24,6 @@ struct DC { /* draw context */ int x, y, w, h; unsigned long bg; unsigned long fg; - unsigned long border; Drawable drawable; Fnt font; GC gc; @@ -35,7 +34,7 @@ extern Display *dpy; extern DC dc; /* draw.c */ -extern void drawtext(const char *text, Bool invert, Bool border); +extern void drawtext(const char *text, Bool invert); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textw(const char *text); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 7507595..4e079e5 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -9,26 +9,6 @@ /* static */ -static void -drawborder(void) -{ - XPoint points[5]; - - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - XSetForeground(dpy, dc.gc, dc.border); - points[0].x = dc.x; - points[0].y = dc.y; - points[1].x = dc.w - 1; - points[1].y = 0; - points[2].x = 0; - points[2].y = dc.h - 1; - points[3].x = -(dc.w - 1); - points[3].y = 0; - points[4].x = 0; - points[4].y = -(dc.h - 1); - XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); -} - static unsigned int textnw(const char *text, unsigned int len) { @@ -44,7 +24,7 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, Bool invert, Bool border) +drawtext(const char *text, Bool invert) { int x, y, w, h; static char buf[256]; @@ -54,10 +34,7 @@ drawtext(const char *text, Bool invert, Bool border) XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - w = 0; - if(border) - drawborder(); if(!text) return; diff --git a/dmenubar/main.c b/dmenubar/main.c index 3b9a24b..14581c4 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -77,17 +77,17 @@ drawmenu() dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, False, False); + drawtext(NULL, False); /* print command */ if(cmdw && item) dc.w = cmdw; - drawtext(text[0] ? text : NULL, False, False); + drawtext(text[0] ? text : NULL, False); dc.x += cmdw; if(curr) { dc.w = SPACE; - drawtext((curr && curr->left) ? "<" : NULL, False, False); + drawtext((curr && curr->left) ? "<" : NULL, False); dc.x += dc.w; /* determine maximum items */ @@ -95,13 +95,13 @@ drawmenu() dc.w = textw(i->text); if(dc.w > mw / 3) dc.w = mw / 3; - drawtext(i->text, sel == i, sel == i); + drawtext(i->text, sel == i); dc.x += dc.w; } dc.x = mw - SPACE; dc.w = SPACE; - drawtext(next ? ">" : NULL, False, False); + drawtext(next ? ">" : NULL, False); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -316,7 +316,6 @@ main(int argc, char *argv[]) /* style */ dc.bg = getcolor(BGCOLOR); dc.fg = getcolor(FGCOLOR); - dc.border = getcolor(BORDERCOLOR); setfont(FONT); wa.override_redirect = 1; From 02c882c8e59cd3b8991ee7dcb658c24527e67371 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 11:07:06 +0200 Subject: [PATCH 038/590] drawing border around sel item --- dmenubar/dmenu.h | 2 +- dmenubar/draw.c | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index f118196..ddea3dd 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -34,7 +34,7 @@ extern Display *dpy; extern DC dc; /* draw.c */ -extern void drawtext(const char *text, Bool invert); +extern void drawtext(const char *text, Bool sel); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textw(const char *text); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 4e079e5..1d6bf21 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -24,18 +24,18 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, Bool invert) +drawtext(const char *text, Bool sel) { int x, y, w, h; static char buf[256]; unsigned int len; XGCValues gcv; + XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); + XSetForeground(dpy, dc.gc, sel ? dc.fg : dc.bg); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); w = 0; - if(!text) return; @@ -56,8 +56,8 @@ drawtext(const char *text, Bool invert) if(w > dc.w) return; /* too long */ - gcv.foreground = invert ? dc.bg : dc.fg; - gcv.background = invert ? dc.fg : dc.bg; + gcv.foreground = sel ? dc.bg : dc.fg; + gcv.background = sel ? dc.fg : dc.bg; if(dc.font.set) { XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc, @@ -68,6 +68,21 @@ drawtext(const char *text, Bool invert) XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len); } + if(sel) { + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + points[0].x = dc.x; + points[0].y = dc.y; + points[1].x = dc.w - 1; + points[1].y = 0; + points[2].x = 0; + points[2].y = dc.h - 1; + points[3].x = -(dc.w - 1); + points[3].y = 0; + points[4].x = 0; + points[4].y = -(dc.h - 1); + XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); + } + } unsigned long From 80068121a7811f7259ec42952a6b95b502036d66 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 11:13:21 +0200 Subject: [PATCH 039/590] readded border colors, this sucks least --- dmenubar/config.arg.h | 1 + dmenubar/config.default.h | 1 + dmenubar/dmenu.h | 3 ++- dmenubar/draw.c | 48 +++++++++++++++++++++++---------------- dmenubar/main.c | 11 +++++---- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 30c422d..c5e1874 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -6,3 +6,4 @@ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" #define BGCOLOR "#eeeeee" #define FGCOLOR "#666699" +#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index 0b1abb4..cf1baea 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -6,3 +6,4 @@ #define FONT "fixed" #define BGCOLOR "#666699" #define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index ddea3dd..2a8796f 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -24,6 +24,7 @@ struct DC { /* draw context */ int x, y, w, h; unsigned long bg; unsigned long fg; + unsigned long border; Drawable drawable; Fnt font; GC gc; @@ -34,7 +35,7 @@ extern Display *dpy; extern DC dc; /* draw.c */ -extern void drawtext(const char *text, Bool sel); +extern void drawtext(const char *text, Bool invert, Bool border); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textw(const char *text); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 1d6bf21..7507595 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -9,6 +9,26 @@ /* static */ +static void +drawborder(void) +{ + XPoint points[5]; + + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + XSetForeground(dpy, dc.gc, dc.border); + points[0].x = dc.x; + points[0].y = dc.y; + points[1].x = dc.w - 1; + points[1].y = 0; + points[2].x = 0; + points[2].y = dc.h - 1; + points[3].x = -(dc.w - 1); + points[3].y = 0; + points[4].x = 0; + points[4].y = -(dc.h - 1); + XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); +} + static unsigned int textnw(const char *text, unsigned int len) { @@ -24,18 +44,21 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, Bool sel) +drawtext(const char *text, Bool invert, Bool border) { int x, y, w, h; static char buf[256]; unsigned int len; XGCValues gcv; - XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - XSetForeground(dpy, dc.gc, sel ? dc.fg : dc.bg); + XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + w = 0; + if(border) + drawborder(); + if(!text) return; @@ -56,8 +79,8 @@ drawtext(const char *text, Bool sel) if(w > dc.w) return; /* too long */ - gcv.foreground = sel ? dc.bg : dc.fg; - gcv.background = sel ? dc.fg : dc.bg; + gcv.foreground = invert ? dc.bg : dc.fg; + gcv.background = invert ? dc.fg : dc.bg; if(dc.font.set) { XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc, @@ -68,21 +91,6 @@ drawtext(const char *text, Bool sel) XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len); } - if(sel) { - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - points[0].x = dc.x; - points[0].y = dc.y; - points[1].x = dc.w - 1; - points[1].y = 0; - points[2].x = 0; - points[2].y = dc.h - 1; - points[3].x = -(dc.w - 1); - points[3].y = 0; - points[4].x = 0; - points[4].y = -(dc.h - 1); - XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); - } - } unsigned long diff --git a/dmenubar/main.c b/dmenubar/main.c index 14581c4..3b9a24b 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -77,17 +77,17 @@ drawmenu() dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, False); + drawtext(NULL, False, False); /* print command */ if(cmdw && item) dc.w = cmdw; - drawtext(text[0] ? text : NULL, False); + drawtext(text[0] ? text : NULL, False, False); dc.x += cmdw; if(curr) { dc.w = SPACE; - drawtext((curr && curr->left) ? "<" : NULL, False); + drawtext((curr && curr->left) ? "<" : NULL, False, False); dc.x += dc.w; /* determine maximum items */ @@ -95,13 +95,13 @@ drawmenu() dc.w = textw(i->text); if(dc.w > mw / 3) dc.w = mw / 3; - drawtext(i->text, sel == i); + drawtext(i->text, sel == i, sel == i); dc.x += dc.w; } dc.x = mw - SPACE; dc.w = SPACE; - drawtext(next ? ">" : NULL, False); + drawtext(next ? ">" : NULL, False, False); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -316,6 +316,7 @@ main(int argc, char *argv[]) /* style */ dc.bg = getcolor(BGCOLOR); dc.fg = getcolor(FGCOLOR); + dc.border = getcolor(BORDERCOLOR); setfont(FONT); wa.override_redirect = 1; From e1dcf37ae9fe087d7dfac3f025b6391ea0ac7fea Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Thu, 10 Aug 2006 15:19:03 +0200 Subject: [PATCH 040/590] Added tag 0.3 for changeset d352e9dc112ee96aa5cad961a0ed880ae9ce7276 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 5fd0570..d19e856 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -1,2 +1,3 @@ fcc8a282cb52c6a9343b461026b386825590cd31 0.1 656be0f47df545dfdd2e1e0663663b8b1b26f031 0.2 +d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 From 541132435e77de89504f8604d8377ebe3df8a033 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Fri, 11 Aug 2006 11:52:34 +0200 Subject: [PATCH 041/590] simplified drawborder --- dmenubar/config.mk | 2 +- dmenubar/draw.c | 38 ++++++++++++++++---------------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 572d192..cc19e19 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.3 +VERSION = 0.4 # Customize below to fit your system diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 7507595..383e130 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -9,26 +9,6 @@ /* static */ -static void -drawborder(void) -{ - XPoint points[5]; - - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - XSetForeground(dpy, dc.gc, dc.border); - points[0].x = dc.x; - points[0].y = dc.y; - points[1].x = dc.w - 1; - points[1].y = 0; - points[2].x = 0; - points[2].y = dc.h - 1; - points[3].x = -(dc.w - 1); - points[3].y = 0; - points[4].x = 0; - points[4].y = -(dc.h - 1); - XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); -} - static unsigned int textnw(const char *text, unsigned int len) { @@ -50,14 +30,28 @@ drawtext(const char *text, Bool invert, Bool border) static char buf[256]; unsigned int len; XGCValues gcv; + XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); w = 0; - if(border) - drawborder(); + if(border) { + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + XSetForeground(dpy, dc.gc, dc.border); + points[0].x = dc.x; + points[0].y = dc.y; + points[1].x = dc.w - 1; + points[1].y = 0; + points[2].x = 0; + points[2].y = dc.h - 1; + points[3].x = -(dc.w - 1); + points[3].y = 0; + points[4].x = 0; + points[4].y = -(dc.h - 1); + XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); + } if(!text) return; From aa38e274de2ebad782ae41334937331339591e30 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Fri, 11 Aug 2006 18:12:07 +0200 Subject: [PATCH 042/590] applied my new color scheme --- dmenubar/config.arg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index c5e1874..670b1b2 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#eeeeee" -#define FGCOLOR "#666699" -#define BORDERCOLOR "#9999CC" +#define BGCOLOR "#0d121d" +#define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#3f484d" From e1223229f03ed7c01975c67a7536a856a6b12603 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 14 Aug 2006 08:42:23 +0200 Subject: [PATCH 043/590] applied Sanders LD patch --- dmenubar/Makefile | 3 ++- dmenubar/config.mk | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index d170037..8c3d904 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -14,6 +14,7 @@ options: @echo "CFLAGS = ${CFLAGS}" @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" + @echo "LD = ${LD}" .c.o: @echo CC $< @@ -27,7 +28,7 @@ config.h: dmenu: ${OBJ} @echo LD $@ - @${CC} -o $@ ${OBJ} ${LDFLAGS} + @${LD} -o $@ ${OBJ} ${LDFLAGS} @strip $@ clean: diff --git a/dmenubar/config.mk b/dmenubar/config.mk index cc19e19..cd14ca4 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -22,3 +22,4 @@ LDFLAGS = ${LIBS} # compiler CC = cc +LD = ${CC} From 20bb5a96a0c75779128865add2119613f5365f1b Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 14 Aug 2006 08:44:54 +0200 Subject: [PATCH 044/590] added comment --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index cd14ca4..6ffffdb 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -20,6 +20,6 @@ LDFLAGS = ${LIBS} #CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = -g ${LIBS} -# compiler +# compiler and linker CC = cc LD = ${CC} From a514879a5c6a28bc06b20563349474696564a88a Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 14 Aug 2006 08:52:28 +0200 Subject: [PATCH 045/590] fixed string cutting --- dmenubar/draw.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 383e130..066a0bf 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -28,7 +28,7 @@ drawtext(const char *text, Bool invert, Bool border) { int x, y, w, h; static char buf[256]; - unsigned int len; + unsigned int len, olen; XGCValues gcv; XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; @@ -56,7 +56,7 @@ drawtext(const char *text, Bool invert, Bool border) if(!text) return; - len = strlen(text); + olen = len = strlen(text); if(len >= sizeof(buf)) len = sizeof(buf) - 1; memcpy(buf, text, len); @@ -69,6 +69,14 @@ drawtext(const char *text, Bool invert, Bool border) /* shorten text if necessary */ while(len && (w = textnw(buf, len)) > dc.w - h) buf[--len] = 0; + if(len < olen) { + if(len > 3) + memcpy(buf + len - 4, "...\0", 4); + else if(len > 2) + memcpy(buf + len - 3, "..\0", 3); + else if(len > 1) + memcpy(buf + len - 2, ".\0", 2); + } if(w > dc.w) return; /* too long */ From a026533b5d804e932871d52bb947ca32c4fe0cc1 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 14 Aug 2006 10:56:57 +0200 Subject: [PATCH 046/590] fixed string cutting --- dmenubar/draw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 066a0bf..dddede0 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -70,12 +70,12 @@ drawtext(const char *text, Bool invert, Bool border) while(len && (w = textnw(buf, len)) > dc.w - h) buf[--len] = 0; if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; if(len > 3) - memcpy(buf + len - 4, "...\0", 4); - else if(len > 2) - memcpy(buf + len - 3, "..\0", 3); - else if(len > 1) - memcpy(buf + len - 2, ".\0", 2); + buf[len - 3] = '.'; } if(w > dc.w) From ea95610e5e6a14cfc61b754a275ec249be76afd9 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 14 Aug 2006 16:11:38 +0200 Subject: [PATCH 047/590] removed finished message --- dmenubar/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 8c3d904..1e430f3 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -7,7 +7,6 @@ SRC = draw.c main.c util.c OBJ = ${SRC:.c=.o} all: options dmenu - @echo finished options: @echo dmenu build options: From e24aa111ef1e5a12808cd6bd6b362f3e456e2a86 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 15 Aug 2006 10:39:26 +0200 Subject: [PATCH 048/590] Added tag 0.4 for changeset 7acf0dde1120542917bae12e0e42293f9d2cc899 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index d19e856..d696034 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -1,3 +1,4 @@ fcc8a282cb52c6a9343b461026b386825590cd31 0.1 656be0f47df545dfdd2e1e0663663b8b1b26f031 0.2 d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 +7acf0dde1120542917bae12e0e42293f9d2cc899 0.4 From 52a2460422c1ca9f97f4d434822ca75405621bdc Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Tue, 15 Aug 2006 16:56:55 +0200 Subject: [PATCH 049/590] fixed the same issue in dmenu --- dmenubar/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 6ffffdb..3001240 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.4 +VERSION = 0.5 # Customize below to fit your system @@ -11,7 +11,7 @@ X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib # includes and libs -INCS = -I/usr/lib -I${X11INC} +INCS = -I/usr/include -I${X11INC} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags From 691f08fb9cf96987e8ddf2767a65e8692a115685 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Wed, 16 Aug 2006 08:57:10 +0200 Subject: [PATCH 050/590] applied sanders Makefile patch --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 1e430f3..2fa60d4 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -19,7 +19,7 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: dmenu.h config.h +${OBJ}: dmenu.h config.h config.mk config.h: @echo creating $@ from config.default.h From d4c19aeda500a3d53bd51662f178cb6a43184072 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Wed, 16 Aug 2006 12:37:01 +0200 Subject: [PATCH 051/590] applied sanders patch --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 3001240..06bf870 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -11,7 +11,7 @@ X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib # includes and libs -INCS = -I/usr/include -I${X11INC} +INCS = _I. -I/usr/include -I${X11INC} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags From d0ea4724730dc479f163490494f7202b847763c2 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Wed, 16 Aug 2006 19:25:04 +0200 Subject: [PATCH 052/590] fixed a typo in config.mk, fixed cleanup code in dmenu (now frees all allocated stuff) --- dmenubar/config.mk | 2 +- dmenubar/main.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 06bf870..fd06d4b 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -11,7 +11,7 @@ X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib # includes and libs -INCS = _I. -I/usr/include -I${X11INC} +INCS = -I. -I/usr/include -I${X11INC} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags diff --git a/dmenubar/main.c b/dmenubar/main.c index 3b9a24b..2f20efb 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -29,7 +29,7 @@ static int mx, my, mw, mh; static int ret = 0; static int nitem = 0; static unsigned int cmdw = 0; -static Bool done = False; +static Bool running = True; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; @@ -219,11 +219,11 @@ kpress(XKeyEvent * e) else if(text) fprintf(stdout, "%s", text); fflush(stdout); - done = True; + running = False; break; case XK_Escape: ret = 1; - done = True; + running = False; break; case XK_BackSpace: if((i = len)) { @@ -290,6 +290,7 @@ int main(int argc, char *argv[]) { char *maxname; + Item *i; XEvent ev; XSetWindowAttributes wa; @@ -349,7 +350,7 @@ main(int argc, char *argv[]) XSync(dpy, False); /* main event loop */ - while(!done && !XNextEvent(dpy, &ev)) { + while(running && !XNextEvent(dpy, &ev)) { switch (ev.type) { case KeyPress: kpress(&ev.xkey); @@ -364,6 +365,16 @@ main(int argc, char *argv[]) } XUngrabKeyboard(dpy, CurrentTime); + while(allitems) { + i = allitems->next; + free(allitems->text); + free(allitems); + allitems = i; + } + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else + XFreeFont(dpy, dc.font.xfont); XFreePixmap(dpy, dc.drawable); XFreeGC(dpy, dc.gc); XDestroyWindow(dpy, win); From 1f9dd3bad523a60fbc6af0ea9d5ffb4834240024 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 21 Aug 2006 07:31:33 +0200 Subject: [PATCH 053/590] small changes in dmenu.1 --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 926b559..8f56491 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -7,7 +7,7 @@ dmenu \- dynamic menu .SH DESCRIPTION .SS Overview .B dmenu -is a generic, highly customizable, and efficient menu for the X Window System, +is a generic, highly customizable, and efficient menu for X, originally designed for .BR dwm (1). It supports arbitrary, user defined menu contents. From 9c4fc8f0d692ee9c3f07f08c917912301a64a505 Mon Sep 17 00:00:00 2001 From: "Anselm R.Garbe" <arg@10ksloc.org> Date: Mon, 21 Aug 2006 07:34:16 +0200 Subject: [PATCH 054/590] renamed bad_malloc into badmalloc as well --- dmenubar/util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/util.c b/dmenubar/util.c index 1b9bc57..0e8828c 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -13,7 +13,7 @@ /* static */ static void -bad_malloc(unsigned int size) +badmalloc(unsigned int size) { eprint("fatal: could not malloc() %u bytes\n", size); } @@ -25,7 +25,7 @@ emalloc(unsigned int size) { void *res = malloc(size); if(!res) - bad_malloc(size); + badmalloc(size); return res; } @@ -45,6 +45,6 @@ estrdup(const char *str) { void *res = strdup(str); if(!res) - bad_malloc(strlen(str)); + badmalloc(strlen(str)); return res; } From 34f8b3cd524daf79a74853aa81258d58a747b18e Mon Sep 17 00:00:00 2001 From: "arg@localhost.10kloc.org" <unknown> Date: Mon, 21 Aug 2006 17:45:46 +0200 Subject: [PATCH 055/590] applied OpenBSD changes.. --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 670b1b2..066c1a4 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#0d121d" +#define BGCOLOR "#666699" #define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#3f484d" +#define BORDERCOLOR "#9999CC" From db63cf7f93460dc7ffdde499ca70314cba4099d2 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Tue, 22 Aug 2006 09:49:56 +0200 Subject: [PATCH 056/590] fixed --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 066c1a4..c5e1874 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#666699" -#define FGCOLOR "#eeeeee" +#define BGCOLOR "#eeeeee" +#define FGCOLOR "#666699" #define BORDERCOLOR "#9999CC" From f5c019cfa0e7658daecb78c1318d7776ed5a1539 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Tue, 22 Aug 2006 10:01:45 +0200 Subject: [PATCH 057/590] font fix --- dmenubar/config.arg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index c5e1874..654d02d 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -3,7 +3,7 @@ * See LICENSE file for license details. */ -#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#eeeeee" -#define FGCOLOR "#666699" -#define BORDERCOLOR "#9999CC" +#define FONT "-*-snap-*-*-*-*-*-*-*-*-*-*-*-*" +#define BGCOLOR "#0d121d" +#define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#3f484d" From 31e56c9462a035103ccaa3c5cd2ff05d546840f2 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Wed, 23 Aug 2006 18:55:48 +0200 Subject: [PATCH 058/590] back to terminus font --- dmenubar/config.arg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 654d02d..670b1b2 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -3,7 +3,7 @@ * See LICENSE file for license details. */ -#define FONT "-*-snap-*-*-*-*-*-*-*-*-*-*-*-*" +#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" #define BGCOLOR "#0d121d" #define FGCOLOR "#eeeeee" #define BORDERCOLOR "#3f484d" From 4ffe16adf617e3286a3c8e1578d4eb50d7c9a995 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Wed, 23 Aug 2006 19:05:20 +0200 Subject: [PATCH 059/590] sanitizing my colorscheme --- dmenubar/config.arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 670b1b2..066c1a4 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#0d121d" +#define BGCOLOR "#666699" #define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#3f484d" +#define BORDERCOLOR "#9999CC" From 42253b397e7668203619edcda5969459c20c47f4 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 09:27:01 +0200 Subject: [PATCH 060/590] removed unnecessary Xlib call --- dmenubar/draw.c | 3 +-- dmenubar/main.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index dddede0..38ae8c3 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -38,8 +38,6 @@ drawtext(const char *text, Bool invert, Bool border) w = 0; if(border) { - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - XSetForeground(dpy, dc.gc, dc.border); points[0].x = dc.x; points[0].y = dc.y; points[1].x = dc.w - 1; @@ -50,6 +48,7 @@ drawtext(const char *text, Bool invert, Bool border) points[3].y = 0; points[4].x = 0; points[4].y = -(dc.h - 1); + XSetForeground(dpy, dc.gc, dc.border); XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); } diff --git a/dmenubar/main.c b/dmenubar/main.c index 2f20efb..840a7bc 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -337,6 +337,7 @@ main(int argc, char *argv[]) /* pixmap */ dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, 0); + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); if(maxname) cmdw = textw(maxname); From a5d2b429010b7363433d0a19c18ea27aed84f34c Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 10:22:30 +0200 Subject: [PATCH 061/590] prepared dmenu-0.5 --- dmenubar/README | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/README b/dmenubar/README index 96f8b9a..33e60ee 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,7 +1,6 @@ dmenu - dynamic menu -------------------- -dmenu is a generic, highly customizable, and efficient menu for the -X Window System. +dmenu is a generic, highly customizable, and efficient menu for X. Requirements From 349a556556582dfb20e5fb74e987e654741e4d05 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 10:22:51 +0200 Subject: [PATCH 062/590] Added tag 0.5 for changeset 4a0ecd881c4fc15de4a0bebd79308b064be020ef --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index d696034..24f9ca8 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -2,3 +2,4 @@ fcc8a282cb52c6a9343b461026b386825590cd31 0.1 656be0f47df545dfdd2e1e0663663b8b1b26f031 0.2 d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 7acf0dde1120542917bae12e0e42293f9d2cc899 0.4 +4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5 From 7bd6f6c05c3b008f41c7ea0b31504851bd90c5fa Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 11:47:08 +0200 Subject: [PATCH 063/590] migrated dmenu to use 4 instead of 3 colors --- dmenubar/config.arg.h | 7 ++++--- dmenubar/config.default.h | 7 ++++--- dmenubar/config.mk | 2 +- dmenubar/dmenu.h | 7 +++---- dmenubar/draw.c | 19 +++++++------------ dmenubar/main.c | 17 +++++++++-------- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 066c1a4..5dbbb7c 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,7 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#666699" -#define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#9999CC" +#define NORMBGCOLOR "#666699" +#define NORMFGCOLOR "#eeeeee" +#define SELBGCOLOR "#eeeeee" +#define SELFGCOLOR "#666699" diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index cf1baea..6949cea 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -4,6 +4,7 @@ */ #define FONT "fixed" -#define BGCOLOR "#666699" -#define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#9999CC" +#define NORMBGCOLOR "#666699" +#define NORMFGCOLOR "#eeeeee" +#define SELBGCOLOR "#eeeeee" +#define SELBFCOLOR "#666699" diff --git a/dmenubar/config.mk b/dmenubar/config.mk index fd06d4b..889afec 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.5 +VERSION = 0.6 # Customize below to fit your system diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 2a8796f..a739fa5 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -22,9 +22,8 @@ struct Fnt { struct DC { /* draw context */ int x, y, w, h; - unsigned long bg; - unsigned long fg; - unsigned long border; + unsigned long bg[2]; + unsigned long fg[2]; Drawable drawable; Fnt font; GC gc; @@ -35,7 +34,7 @@ extern Display *dpy; extern DC dc; /* draw.c */ -extern void drawtext(const char *text, Bool invert, Bool border); +extern void drawtext(const char *text, unsigned int colidx, Bool border); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textw(const char *text); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 38ae8c3..6802403 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -24,7 +24,7 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, Bool invert, Bool border) +drawtext(const char *text, unsigned int colidx, Bool border) { int x, y, w, h; static char buf[256]; @@ -33,10 +33,11 @@ drawtext(const char *text, Bool invert, Bool border) XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); + XSetForeground(dpy, dc.gc, dc.bg[colidx]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); w = 0; + XSetForeground(dpy, dc.gc, dc.fg[colidx]); if(border) { points[0].x = dc.x; points[0].y = dc.y; @@ -48,7 +49,6 @@ drawtext(const char *text, Bool invert, Bool border) points[3].y = 0; points[4].x = 0; points[4].y = -(dc.h - 1); - XSetForeground(dpy, dc.gc, dc.border); XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); } @@ -80,17 +80,12 @@ drawtext(const char *text, Bool invert, Bool border) if(w > dc.w) return; /* too long */ - gcv.foreground = invert ? dc.bg : dc.fg; - gcv.background = invert ? dc.fg : dc.bg; - if(dc.font.set) { - XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); - XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc, - x, y, buf, len); - } + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); else { gcv.font = dc.font.xfont->fid; - XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); - XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len); + XChangeGC(dpy, dc.gc, GCFont, &gcv); + XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); } } diff --git a/dmenubar/main.c b/dmenubar/main.c index 840a7bc..c3cad1d 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -77,17 +77,17 @@ drawmenu() dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, False, False); + drawtext(NULL, 0, False); /* print command */ if(cmdw && item) dc.w = cmdw; - drawtext(text[0] ? text : NULL, False, False); + drawtext(text[0] ? text : NULL, 0, False); dc.x += cmdw; if(curr) { dc.w = SPACE; - drawtext((curr && curr->left) ? "<" : NULL, False, False); + drawtext((curr && curr->left) ? "<" : NULL, 0, False); dc.x += dc.w; /* determine maximum items */ @@ -95,13 +95,13 @@ drawmenu() dc.w = textw(i->text); if(dc.w > mw / 3) dc.w = mw / 3; - drawtext(i->text, sel == i, sel == i); + drawtext(i->text, sel == i ? 1 : 0, sel == i); dc.x += dc.w; } dc.x = mw - SPACE; dc.w = SPACE; - drawtext(next ? ">" : NULL, False, False); + drawtext(next ? ">" : NULL, 0, False); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -315,9 +315,10 @@ main(int argc, char *argv[]) usleep(1000); /* style */ - dc.bg = getcolor(BGCOLOR); - dc.fg = getcolor(FGCOLOR); - dc.border = getcolor(BORDERCOLOR); + dc.bg[0] = getcolor(NORMBGCOLOR); + dc.fg[0] = getcolor(NORMFGCOLOR); + dc.bg[1] = getcolor(SELBGCOLOR); + dc.fg[1] = getcolor(SELFGCOLOR); setfont(FONT); wa.override_redirect = 1; From fa4d50ecce95431bae47986e3dcaaed2f0228540 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 11:57:58 +0200 Subject: [PATCH 064/590] small color change --- dmenubar/config.arg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 5dbbb7c..91b014f 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -7,4 +7,4 @@ #define NORMBGCOLOR "#666699" #define NORMFGCOLOR "#eeeeee" #define SELBGCOLOR "#eeeeee" -#define SELFGCOLOR "#666699" +#define SELFGCOLOR "#000088" From 29cc31c59b1aa449c9905db482b4efeab5cdbb58 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 12:03:40 +0200 Subject: [PATCH 065/590] fixed minor bug --- dmenubar/config.default.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index 6949cea..48c810a 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -7,4 +7,4 @@ #define NORMBGCOLOR "#666699" #define NORMFGCOLOR "#eeeeee" #define SELBGCOLOR "#eeeeee" -#define SELBFCOLOR "#666699" +#define SELFGCOLOR "#666699" From f680ab626cc7388732b867cdefcbc073be8c0732 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 24 Aug 2006 12:04:41 +0200 Subject: [PATCH 066/590] removed useless call --- dmenubar/draw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 6802403..ba1fafd 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -29,7 +29,6 @@ drawtext(const char *text, unsigned int colidx, Bool border) int x, y, w, h; static char buf[256]; unsigned int len, olen; - XGCValues gcv; XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; @@ -83,8 +82,7 @@ drawtext(const char *text, unsigned int colidx, Bool border) if(dc.font.set) XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); else { - gcv.font = dc.font.xfont->fid; - XChangeGC(dpy, dc.gc, GCFont, &gcv); + XSetFont(dpy, dc.gc, dc.font.xfont->fid); XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); } } From 8f696f3c27aa0897538f0a82992448da66d8470b Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 25 Aug 2006 07:54:20 +0200 Subject: [PATCH 067/590] back to 3 colors --- dmenubar/config.arg.h | 7 +++---- dmenubar/config.default.h | 7 +++---- dmenubar/dmenu.h | 7 ++++--- dmenubar/draw.c | 21 ++++++++++++++------- dmenubar/main.c | 17 ++++++++--------- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 91b014f..066c1a4 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,7 +4,6 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define NORMBGCOLOR "#666699" -#define NORMFGCOLOR "#eeeeee" -#define SELBGCOLOR "#eeeeee" -#define SELFGCOLOR "#000088" +#define BGCOLOR "#666699" +#define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index 48c810a..cf1baea 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -4,7 +4,6 @@ */ #define FONT "fixed" -#define NORMBGCOLOR "#666699" -#define NORMFGCOLOR "#eeeeee" -#define SELBGCOLOR "#eeeeee" -#define SELFGCOLOR "#666699" +#define BGCOLOR "#666699" +#define FGCOLOR "#eeeeee" +#define BORDERCOLOR "#9999CC" diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index a739fa5..2a8796f 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -22,8 +22,9 @@ struct Fnt { struct DC { /* draw context */ int x, y, w, h; - unsigned long bg[2]; - unsigned long fg[2]; + unsigned long bg; + unsigned long fg; + unsigned long border; Drawable drawable; Fnt font; GC gc; @@ -34,7 +35,7 @@ extern Display *dpy; extern DC dc; /* draw.c */ -extern void drawtext(const char *text, unsigned int colidx, Bool border); +extern void drawtext(const char *text, Bool invert, Bool border); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textw(const char *text); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index ba1fafd..38ae8c3 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -24,19 +24,19 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, unsigned int colidx, Bool border) +drawtext(const char *text, Bool invert, Bool border) { int x, y, w, h; static char buf[256]; unsigned int len, olen; + XGCValues gcv; XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - XSetForeground(dpy, dc.gc, dc.bg[colidx]); + XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); w = 0; - XSetForeground(dpy, dc.gc, dc.fg[colidx]); if(border) { points[0].x = dc.x; points[0].y = dc.y; @@ -48,6 +48,7 @@ drawtext(const char *text, unsigned int colidx, Bool border) points[3].y = 0; points[4].x = 0; points[4].y = -(dc.h - 1); + XSetForeground(dpy, dc.gc, dc.border); XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); } @@ -79,11 +80,17 @@ drawtext(const char *text, unsigned int colidx, Bool border) if(w > dc.w) return; /* too long */ - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + gcv.foreground = invert ? dc.bg : dc.fg; + gcv.background = invert ? dc.fg : dc.bg; + if(dc.font.set) { + XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); + XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc, + x, y, buf, len); + } else { - XSetFont(dpy, dc.gc, dc.font.xfont->fid); - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); + gcv.font = dc.font.xfont->fid; + XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); + XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len); } } diff --git a/dmenubar/main.c b/dmenubar/main.c index c3cad1d..840a7bc 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -77,17 +77,17 @@ drawmenu() dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, 0, False); + drawtext(NULL, False, False); /* print command */ if(cmdw && item) dc.w = cmdw; - drawtext(text[0] ? text : NULL, 0, False); + drawtext(text[0] ? text : NULL, False, False); dc.x += cmdw; if(curr) { dc.w = SPACE; - drawtext((curr && curr->left) ? "<" : NULL, 0, False); + drawtext((curr && curr->left) ? "<" : NULL, False, False); dc.x += dc.w; /* determine maximum items */ @@ -95,13 +95,13 @@ drawmenu() dc.w = textw(i->text); if(dc.w > mw / 3) dc.w = mw / 3; - drawtext(i->text, sel == i ? 1 : 0, sel == i); + drawtext(i->text, sel == i, sel == i); dc.x += dc.w; } dc.x = mw - SPACE; dc.w = SPACE; - drawtext(next ? ">" : NULL, 0, False); + drawtext(next ? ">" : NULL, False, False); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -315,10 +315,9 @@ main(int argc, char *argv[]) usleep(1000); /* style */ - dc.bg[0] = getcolor(NORMBGCOLOR); - dc.fg[0] = getcolor(NORMFGCOLOR); - dc.bg[1] = getcolor(SELBGCOLOR); - dc.fg[1] = getcolor(SELFGCOLOR); + dc.bg = getcolor(BGCOLOR); + dc.fg = getcolor(FGCOLOR); + dc.border = getcolor(BORDERCOLOR); setfont(FONT); wa.override_redirect = 1; From b71725e35d64d01869f5822fa43c5fb3bb39966e Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 25 Aug 2006 14:45:17 +0200 Subject: [PATCH 068/590] updated dmenu to borderless drawing as well --- dmenubar/config.arg.h | 7 ++++--- dmenubar/config.default.h | 7 ++++--- dmenubar/dmenu.h | 10 ++++++---- dmenubar/draw.c | 33 ++++++++------------------------- dmenubar/main.c | 19 ++++++++++--------- 5 files changed, 32 insertions(+), 44 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 066c1a4..1e0ff8c 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,6 +4,7 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define BGCOLOR "#666699" -#define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#9999CC" +#define SELBGCOLOR "#666699" +#define SELFGCOLOR "#eeeeee" +#define NORMBGCOLOR "#333366" +#define NORMFGCOLOR "#cccccc" diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index cf1baea..1f66553 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -4,6 +4,7 @@ */ #define FONT "fixed" -#define BGCOLOR "#666699" -#define FGCOLOR "#eeeeee" -#define BORDERCOLOR "#9999CC" +#define SELBGCOLOR "#666699" +#define SELFGCOLOR "#eeeeee" +#define NORMBGCOLOR "#333366" +#define NORMFGCOLOR "#cccccc" diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 2a8796f..337e094 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -9,6 +9,9 @@ #define SPACE 30 /* px */ +/* color */ +enum { ColFG, ColBG, ColLast }; + typedef struct DC DC; typedef struct Fnt Fnt; @@ -22,9 +25,8 @@ struct Fnt { struct DC { /* draw context */ int x, y, w, h; - unsigned long bg; - unsigned long fg; - unsigned long border; + unsigned long norm[ColLast]; + unsigned long sel[ColLast]; Drawable drawable; Fnt font; GC gc; @@ -35,7 +37,7 @@ extern Display *dpy; extern DC dc; /* draw.c */ -extern void drawtext(const char *text, Bool invert, Bool border); +extern void drawtext(const char *text, unsigned long col[ColLast]); extern unsigned long getcolor(const char *colstr); extern void setfont(const char *fontstr); extern unsigned int textw(const char *text); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 38ae8c3..d0f21cd 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -24,37 +24,21 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, Bool invert, Bool border) +drawtext(const char *text, unsigned long col[ColLast]) { int x, y, w, h; static char buf[256]; unsigned int len, olen; XGCValues gcv; - XPoint points[5]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg); + XSetForeground(dpy, dc.gc, col[ColBG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - w = 0; - if(border) { - points[0].x = dc.x; - points[0].y = dc.y; - points[1].x = dc.w - 1; - points[1].y = 0; - points[2].x = 0; - points[2].y = dc.h - 1; - points[3].x = -(dc.w - 1); - points[3].y = 0; - points[4].x = 0; - points[4].y = -(dc.h - 1); - XSetForeground(dpy, dc.gc, dc.border); - XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); - } - if(!text) return; + w = 0; olen = len = strlen(text); if(len >= sizeof(buf)) len = sizeof(buf) - 1; @@ -80,17 +64,16 @@ drawtext(const char *text, Bool invert, Bool border) if(w > dc.w) return; /* too long */ - gcv.foreground = invert ? dc.bg : dc.fg; - gcv.background = invert ? dc.fg : dc.bg; + gcv.foreground = col[ColFG]; if(dc.font.set) { - XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv); - XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc, + XChangeGC(dpy, dc.gc, GCForeground, &gcv); + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); } else { gcv.font = dc.font.xfont->fid; - XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv); - XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len); + XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv); + XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); } } diff --git a/dmenubar/main.c b/dmenubar/main.c index 840a7bc..51fa20f 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -77,17 +77,17 @@ drawmenu() dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, False, False); + drawtext(NULL, dc.norm); /* print command */ if(cmdw && item) dc.w = cmdw; - drawtext(text[0] ? text : NULL, False, False); + drawtext(text[0] ? text : NULL, dc.norm); dc.x += cmdw; if(curr) { dc.w = SPACE; - drawtext((curr && curr->left) ? "<" : NULL, False, False); + drawtext((curr && curr->left) ? "<" : NULL, dc.norm); dc.x += dc.w; /* determine maximum items */ @@ -95,13 +95,13 @@ drawmenu() dc.w = textw(i->text); if(dc.w > mw / 3) dc.w = mw / 3; - drawtext(i->text, sel == i, sel == i); + drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } dc.x = mw - SPACE; dc.w = SPACE; - drawtext(next ? ">" : NULL, False, False); + drawtext(next ? ">" : NULL, dc.norm); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -315,9 +315,10 @@ main(int argc, char *argv[]) usleep(1000); /* style */ - dc.bg = getcolor(BGCOLOR); - dc.fg = getcolor(FGCOLOR); - dc.border = getcolor(BORDERCOLOR); + dc.sel[ColBG] = getcolor(SELBGCOLOR); + dc.sel[ColFG] = getcolor(SELFGCOLOR); + dc.norm[ColBG] = getcolor(NORMBGCOLOR); + dc.norm[ColFG] = getcolor(NORMFGCOLOR); setfont(FONT); wa.override_redirect = 1; @@ -326,7 +327,7 @@ main(int argc, char *argv[]) mx = my = 0; mw = DisplayWidth(dpy, screen); - mh = dc.font.height + 4; + mh = dc.font.height + 2; win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, From ca9e2c02305eb57475a91ead6020c6fd136524fa Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 25 Aug 2006 17:44:40 +0200 Subject: [PATCH 069/590] small color fixes --- dmenubar/config.arg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index 1e0ff8c..a23a773 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -4,7 +4,7 @@ */ #define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define SELBGCOLOR "#666699" -#define SELFGCOLOR "#eeeeee" -#define NORMBGCOLOR "#333366" +#define SELBGCOLOR "#0055bb" +#define SELFGCOLOR "#ffffff" +#define NORMBGCOLOR "#444444" #define NORMFGCOLOR "#cccccc" From c59226591358ced9426381ba9177ca16503fad7e Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 25 Aug 2006 18:03:30 +0200 Subject: [PATCH 070/590] switching back to a dark color scheme with larger font --- dmenubar/config.arg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index a23a773..cb9f566 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -3,8 +3,8 @@ * See LICENSE file for license details. */ -#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define SELBGCOLOR "#0055bb" -#define SELFGCOLOR "#ffffff" -#define NORMBGCOLOR "#444444" -#define NORMFGCOLOR "#cccccc" +#define FONT "-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*" +#define SELBGCOLOR "#333366" +#define SELFGCOLOR "#eeeeee" +#define NORMBGCOLOR "#333333" +#define NORMFGCOLOR "#dddddd" From 384bb4152be7e18982678f8375e991880d210fdd Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 25 Aug 2006 18:15:24 +0200 Subject: [PATCH 071/590] fixed --- dmenubar/config.arg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index cb9f566..a19e463 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -3,7 +3,7 @@ * See LICENSE file for license details. */ -#define FONT "-*-terminus-medium-*-*-*-14-*-*-*-*-*-iso10646-*" +#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" #define SELBGCOLOR "#333366" #define SELFGCOLOR "#eeeeee" #define NORMBGCOLOR "#333333" From 18c0d8c9b088737414e232703dc2b5b9a9170e3c Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 28 Aug 2006 07:22:38 +0200 Subject: [PATCH 072/590] updated man page --- dmenubar/dmenu.1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 8f56491..fb0a5fe 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -14,12 +14,12 @@ It supports arbitrary, user defined menu contents. .SS Options .TP .B \-v -prints version information to stdout, then exits. +prints version information to standard output, then exits. .SH USAGE .B dmenu -reads a list of newline-separated items from stdin and creates a menu. +reads a list of newline-separated items from standard input and creates a menu. When the user selects an item or enters any text and presses Return, his choice -is printed to stdout and +is printed to standard output and .B dmenu terminates. .B dmenu @@ -36,10 +36,10 @@ Tab Copy the selected item to the input field. .TP Return -Confirm selection and quit (print the selected item to stdout). +Confirm selection and quit (print the selected item to standard output). .TP Shift-Return -Confirm selection and quit (print the text in the input field to stdout). +Confirm selection and quit (print the text in the input field to standard output). .TP Escape Quit without selecting an item. From 00e7c69307ae4824ca4612777c93678ec27676f9 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 28 Aug 2006 10:20:10 +0200 Subject: [PATCH 073/590] Added tag 0.6 for changeset 25f679fb19686140a907684ffcb423b9e9d44b53 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 24f9ca8..c97ccb5 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -3,3 +3,4 @@ fcc8a282cb52c6a9343b461026b386825590cd31 0.1 d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 7acf0dde1120542917bae12e0e42293f9d2cc899 0.4 4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5 +25f679fb19686140a907684ffcb423b9e9d44b53 0.6 From 6b980e7a2d734f8ebe79d03254f01ef6231bd3c1 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 28 Aug 2006 12:26:25 +0200 Subject: [PATCH 074/590] updated version --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 889afec..7005311 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.6 +VERSION = 0.7 # Customize below to fit your system From 342a42d4f4f0bf09b248f1a33ecc07cde0f33499 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 4 Sep 2006 07:28:03 +0200 Subject: [PATCH 075/590] small change of main event loop --- dmenubar/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 51fa20f..6ca043d 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -354,6 +354,8 @@ main(int argc, char *argv[]) /* main event loop */ while(running && !XNextEvent(dpy, &ev)) { switch (ev.type) { + default: /* ignore all crap */ + break; case KeyPress: kpress(&ev.xkey); break; @@ -361,8 +363,6 @@ main(int argc, char *argv[]) if(ev.xexpose.count == 0) drawmenu(); break; - default: - break; } } From c1f27157b0e26285bb38c0227e50f5be9b47a7b3 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 4 Sep 2006 17:17:08 +0200 Subject: [PATCH 076/590] Added tag 0.7 for changeset 5fc20d7158bd16b4d5f8d1c25e177680b6d54252 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index c97ccb5..e144d8c 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -4,3 +4,4 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 7acf0dde1120542917bae12e0e42293f9d2cc899 0.4 4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5 25f679fb19686140a907684ffcb423b9e9d44b53 0.6 +5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7 From 3d1889a95a8612a526000728c7e53bad74d6c4aa Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 4 Sep 2006 19:47:09 +0200 Subject: [PATCH 077/590] fixed man page --- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 7005311..bbeda5d 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.7 +VERSION = 0.8 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index fb0a5fe..0fa21f9 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -7,10 +7,10 @@ dmenu \- dynamic menu .SH DESCRIPTION .SS Overview .B dmenu -is a generic, highly customizable, and efficient menu for X, -originally designed for +is a generic menu for X, originally designed for .BR dwm (1). -It supports arbitrary, user defined menu contents. +It manages huge amounts (up to 10.000 and more) of user defined menu items +efficiently. .SS Options .TP .B \-v From 3d9f262e848ca0c4287f0a8fdd42d75a4391b0d7 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Wed, 6 Sep 2006 10:53:15 +0200 Subject: [PATCH 078/590] Added tag 0.8 for changeset 409667a57221f7e50ba8b5248f638915cd61b366 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index e144d8c..ccfb9b5 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -5,3 +5,4 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5 25f679fb19686140a907684ffcb423b9e9d44b53 0.6 5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7 +409667a57221f7e50ba8b5248f638915cd61b366 0.8 From c165ba591e86c68f01fd0a36135689432c75a463 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 7 Sep 2006 09:36:53 +0200 Subject: [PATCH 079/590] made dmenu.1 also concise --- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 48 ++++++++++++++++++++++------------------------ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index bbeda5d..df43482 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.8 +VERSION = 0.9 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 0fa21f9..fa3adc0 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -6,8 +6,7 @@ dmenu \- dynamic menu .RB [ \-v ] .SH DESCRIPTION .SS Overview -.B dmenu -is a generic menu for X, originally designed for +dmenu is a generic menu for X, originally designed for .BR dwm (1). It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. @@ -16,49 +15,48 @@ efficiently. .B \-v prints version information to standard output, then exits. .SH USAGE -.B dmenu -reads a list of newline-separated items from standard input and creates a menu. -When the user selects an item or enters any text and presses Return, his choice -is printed to standard output and -.B dmenu -terminates. -.B dmenu -is completely controlled by the keyboard. The following keys are recognized: +dmenu reads a list of newline-separated items from standard input and creates a +menu. When the user selects an item or enters any text and presses Return, his +choice is printed to standard output and dmenu terminates. +.P +dmenu is completely controlled by the keyboard. The following keys are recognized: .TP -Any printable character -Appends the character to the text in the input field. This works as a filter: +.B Any printable character +Appends the character to the text in the input field. This works as a filter: only items containing this text will be displayed. .TP -Left/Right +.B Left/Right Select the previous/next item. .TP -Tab +.B Tab Copy the selected item to the input field. .TP -Return +.B Return Confirm selection and quit (print the selected item to standard output). .TP -Shift-Return +.B Shift-Return Confirm selection and quit (print the text in the input field to standard output). .TP -Escape +.B Escape Quit without selecting an item. .TP -Backspace (Control-h) +.B Backspace (Control-h) Remove enough characters from the input field to change its filtering effect. .TP -Control-u +.B Control-u Remove all characters from the input field. .P -.B dmenu -returns +dwm returns .B 0 -if Return is pressed on termination, +if +.B Return +is pressed and .B 1 -if Escape is pressed. +if +.B Escape +is pressed on termination. .SH CUSTOMIZATION -.B dmenu -is customized by creating a custom config.h and (re)compiling the source +dmenu is customized by creating a custom config.h and (re)compiling the source code. This keeps it fast, secure and simple. .SH SEE ALSO .BR dwm (1) From 4f2a14f16023b11888277b2b5e9c2db14b690b9a Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 7 Sep 2006 09:40:09 +0200 Subject: [PATCH 080/590] another fix --- dmenubar/dmenu.1 | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index fa3adc0..7495ef3 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -32,29 +32,26 @@ Select the previous/next item. Copy the selected item to the input field. .TP .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 .B Shift-Return Confirm selection and quit (print the text in the input field to standard output). +Returns +.B 0 +on termination. .TP .B Escape -Quit without selecting an item. +Quit without selecting an item. Returns +.B 1 +on termination. .TP .B Backspace (Control-h) Remove enough characters from the input field to change its filtering effect. .TP .B Control-u Remove all characters from the input field. -.P -dwm returns -.B 0 -if -.B Return -is pressed and -.B 1 -if -.B Escape -is pressed on termination. .SH CUSTOMIZATION dmenu is customized by creating a custom config.h and (re)compiling the source code. This keeps it fast, secure and simple. From cc8e4a407e41435632312e2737058dd577db3ad2 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 7 Sep 2006 19:12:04 +0200 Subject: [PATCH 081/590] new version of dmenu --- dmenubar/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/README b/dmenubar/README index 33e60ee..d66a689 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,6 +1,6 @@ dmenu - dynamic menu -------------------- -dmenu is a generic, highly customizable, and efficient menu for X. +dmenu is a generic and efficient menu for X. Requirements From a041c50e6f421afc75e41885ed1eec388b23b235 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 8 Sep 2006 07:33:20 +0200 Subject: [PATCH 082/590] implemented early keyboard grab for dmenu with a timeout for stdin data writers to prevent endless grabbings of the keyboard --- dmenubar/config.arg.h | 1 + dmenubar/config.default.h | 1 + dmenubar/main.c | 23 +++++++++++++++++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h index a19e463..5b99a2c 100644 --- a/dmenubar/config.arg.h +++ b/dmenubar/config.arg.h @@ -8,3 +8,4 @@ #define SELFGCOLOR "#eeeeee" #define NORMBGCOLOR "#333333" #define NORMFGCOLOR "#dddddd" +#define STDIN_TIMEOUT 3 /* seconds */ diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h index 1f66553..0bae3a1 100644 --- a/dmenubar/config.default.h +++ b/dmenubar/config.default.h @@ -8,3 +8,4 @@ #define SELFGCOLOR "#eeeeee" #define NORMBGCOLOR "#333366" #define NORMFGCOLOR "#cccccc" +#define STDIN_TIMEOUT 3 /* seconds */ diff --git a/dmenubar/main.c b/dmenubar/main.c index 6ca043d..03c8b1f 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -11,6 +11,8 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <sys/select.h> +#include <sys/time.h> #include <X11/cursorfont.h> #include <X11/Xutil.h> #include <X11/keysym.h> @@ -290,6 +292,8 @@ int main(int argc, char *argv[]) { char *maxname; + fd_set rd; + struct timeval timeout; Item *i; XEvent ev; XSetWindowAttributes wa; @@ -307,13 +311,23 @@ main(int argc, char *argv[]) screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - maxname = readstdin(); - - /* grab as early as possible, but after reading all items!!! */ + /* 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); + 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 */ dc.sel[ColBG] = getcolor(SELBGCOLOR); dc.sel[ColFG] = getcolor(SELFGCOLOR); @@ -366,7 +380,6 @@ main(int argc, char *argv[]) } } - XUngrabKeyboard(dpy, CurrentTime); while(allitems) { i = allitems->next; free(allitems->text); @@ -380,6 +393,8 @@ main(int argc, char *argv[]) XFreePixmap(dpy, dc.drawable); XFreeGC(dpy, dc.gc); XDestroyWindow(dpy, win); +UninitializedEnd: + XUngrabKeyboard(dpy, CurrentTime); XCloseDisplay(dpy); return ret; From 6cf3779adc55b24891b254f4d7cf92b45bd2f55e Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 8 Sep 2006 08:31:19 +0200 Subject: [PATCH 083/590] Added tag 0.9 for changeset d046c818ea467555cc338751c9bf3024609f1f12 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index ccfb9b5..a2534f7 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -6,3 +6,4 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 25f679fb19686140a907684ffcb423b9e9d44b53 0.6 5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7 409667a57221f7e50ba8b5248f638915cd61b366 0.8 +d046c818ea467555cc338751c9bf3024609f1f12 0.9 From 25449aa5da81e66e7d85101a0e718850d56c296c Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Mon, 11 Sep 2006 13:18:09 +0200 Subject: [PATCH 084/590] commented dmenu --- dmenubar/config.mk | 2 +- dmenubar/dmenu.h | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index df43482..3af05bd 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 0.9 +VERSION = 1.0 # Customize below to fit your system diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 337e094..eed5689 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -23,26 +23,27 @@ struct Fnt { int height; }; -struct DC { /* draw context */ +struct DC { int x, y, w, h; unsigned long norm[ColLast]; unsigned long sel[ColLast]; Drawable drawable; Fnt font; GC gc; -}; +}; /* draw context */ extern int screen; extern Display *dpy; -extern DC dc; +extern DC dc; /* global drawing context */ /* draw.c */ -extern void drawtext(const char *text, unsigned long col[ColLast]); -extern unsigned long getcolor(const char *colstr); -extern void setfont(const char *fontstr); -extern unsigned int textw(const char *text); +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 */ /* util.c */ -extern void *emalloc(unsigned int size); -extern void eprint(const char *errstr, ...); -extern char *estrdup(const char *str); +extern void *emalloc(unsigned int size); /* allocates memory, exits on error */ +extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ +extern char *estrdup(const char *str); /* duplicates str, exits on allocation error */ From cbc33184e4159248eddc617a0bb7a48acf745f60 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Tue, 12 Sep 2006 10:59:00 +0200 Subject: [PATCH 085/590] made function signatures more consistent to my coding style --- dmenubar/draw.c | 15 +++++---------- dmenubar/main.c | 18 ++++++------------ dmenubar/util.c | 12 ++++-------- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index d0f21cd..10a011d 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -10,8 +10,7 @@ /* static */ static unsigned int -textnw(const char *text, unsigned int len) -{ +textnw(const char *text, unsigned int len) { XRectangle r; if(dc.font.set) { @@ -24,8 +23,7 @@ textnw(const char *text, unsigned int len) /* extern */ void -drawtext(const char *text, unsigned long col[ColLast]) -{ +drawtext(const char *text, unsigned long col[ColLast]) { int x, y, w, h; static char buf[256]; unsigned int len, olen; @@ -78,8 +76,7 @@ drawtext(const char *text, unsigned long col[ColLast]) } unsigned long -getcolor(const char *colstr) -{ +getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -88,8 +85,7 @@ getcolor(const char *colstr) } void -setfont(const char *fontstr) -{ +setfont(const char *fontstr) { char **missing, *def; int i, n; @@ -137,7 +133,6 @@ setfont(const char *fontstr) } unsigned int -textw(const char *text) -{ +textw(const char *text) { return textnw(text, strlen(text)) + dc.font.height; } diff --git a/dmenubar/main.c b/dmenubar/main.c index 03c8b1f..60567b2 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -42,8 +42,7 @@ static Window root; static Window win; static void -calcoffsets() -{ +calcoffsets() { unsigned int tw, w; if(!curr) @@ -71,8 +70,7 @@ calcoffsets() } static void -drawmenu() -{ +drawmenu() { Item *i; dc.x = 0; @@ -110,8 +108,7 @@ drawmenu() } static void -match(char *pattern) -{ +match(char *pattern) { unsigned int plen; Item *i, *j; @@ -151,8 +148,7 @@ match(char *pattern) } static void -kpress(XKeyEvent * e) -{ +kpress(XKeyEvent * e) { char buf[32]; int num, prev_nitem; unsigned int i, len; @@ -251,8 +247,7 @@ kpress(XKeyEvent * e) } static char * -readstdin() -{ +readstdin() { static char *maxname = NULL; char *p, buf[1024]; unsigned int len = 0, max = 0; @@ -289,8 +284,7 @@ Display *dpy; DC dc = {0}; int -main(int argc, char *argv[]) -{ +main(int argc, char *argv[]) { char *maxname; fd_set rd; struct timeval timeout; diff --git a/dmenubar/util.c b/dmenubar/util.c index 0e8828c..d0444c5 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -13,16 +13,14 @@ /* static */ static void -badmalloc(unsigned int size) -{ +badmalloc(unsigned int size) { eprint("fatal: could not malloc() %u bytes\n", size); } /* extern */ void * -emalloc(unsigned int size) -{ +emalloc(unsigned int size) { void *res = malloc(size); if(!res) badmalloc(size); @@ -30,8 +28,7 @@ emalloc(unsigned int size) } void -eprint(const char *errstr, ...) -{ +eprint(const char *errstr, ...) { va_list ap; va_start(ap, errstr); @@ -41,8 +38,7 @@ eprint(const char *errstr, ...) } char * -estrdup(const char *str) -{ +estrdup(const char *str) { void *res = strdup(str); if(!res) badmalloc(strlen(str)); From 420409647b4ef895c3c288167aa2c7817f0160a9 Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Sat, 16 Sep 2006 11:20:54 +0200 Subject: [PATCH 086/590] Added tag 1.0 for changeset 9e11140d4cc3eecac3b0ab752f91528fd5e04be8 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index a2534f7..26a7db1 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -7,3 +7,4 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7 409667a57221f7e50ba8b5248f638915cd61b366 0.8 d046c818ea467555cc338751c9bf3024609f1f12 0.9 +9e11140d4cc3eecac3b0ab752f91528fd5e04be8 1.0 From ec925f2bff8077f78c3affc42a74be6b885af14b Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Mon, 25 Sep 2006 08:29:20 +0200 Subject: [PATCH 087/590] applied something similiar to Jukkas patch --- dmenubar/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 60567b2..3203014 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -42,7 +42,7 @@ static Window root; static Window win; static void -calcoffsets() { +calcoffsets(void) { unsigned int tw, w; if(!curr) @@ -70,7 +70,7 @@ calcoffsets() { } static void -drawmenu() { +drawmenu(void) { Item *i; dc.x = 0; @@ -247,7 +247,7 @@ kpress(XKeyEvent * e) { } static char * -readstdin() { +readstdin(void) { static char *maxname = NULL; char *p, buf[1024]; unsigned int len = 0, max = 0; From 9152c74655f7696d4120d701bd67eda4d6a99b41 Mon Sep 17 00:00:00 2001 From: "arg@wmii.de" <unknown> Date: Tue, 26 Sep 2006 08:43:41 +0200 Subject: [PATCH 088/590] applied a change made by Uriel to dmenu (though I didn't applied everything) --- dmenubar/main.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 3203014..77a61b9 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -120,19 +120,8 @@ match(char *pattern) { nitem = 0; for(i = allitems; i; i=i->next) - if(!plen || !strncmp(pattern, i->text, plen)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } - for(i = allitems; i; i=i->next) - if(plen && strncmp(pattern, i->text, plen) - && strstr(i->text, pattern)) { + if(plen ? !strncmp(pattern, i->text, plen) : + strncmp(pattern, i->text, plen) && strstr(i->text, pattern)) { if(!j) item = i; else @@ -208,10 +197,8 @@ kpress(XKeyEvent * e) { } break; case XK_Return: - if(e->state & ShiftMask) { - if(text) - fprintf(stdout, "%s", text); - } + if((e->state & ShiftMask) && text) + fprintf(stdout, "%s", text); else if(sel) fprintf(stdout, "%s", sel->text); else if(text) From e1684b2aec2c29b8e4c9e7b6d9fb19f181de9b6c Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 08:47:10 +0200 Subject: [PATCH 089/590] uriel didn't understood dmenu code, he broke nearly everything --- dmenubar/main.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 77a61b9..170a3e0 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -120,8 +120,19 @@ match(char *pattern) { nitem = 0; for(i = allitems; i; i=i->next) - if(plen ? !strncmp(pattern, i->text, plen) : - strncmp(pattern, i->text, plen) && strstr(i->text, pattern)) { + if(!plen || !strncmp(pattern, i->text, plen)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + for(i = allitems; i; i=i->next) + if(plen && strncmp(pattern, i->text, plen) + && strstr(i->text, pattern)) { if(!j) item = i; else From 1e0d10fe28de394ad30986cc3a939387a5a1c8ad Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 13:20:47 +0200 Subject: [PATCH 090/590] removed config.h stuff, made dwm configurable due to command line options --- dmenubar/Makefile | 6 +---- dmenubar/config.arg.h | 11 --------- dmenubar/config.default.h | 11 --------- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 27 +++++++++++++++++--- dmenubar/dmenu.h | 6 ++++- dmenubar/main.c | 52 +++++++++++++++++++++++++++------------ 7 files changed, 67 insertions(+), 48 deletions(-) delete mode 100644 dmenubar/config.arg.h delete mode 100644 dmenubar/config.default.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 2fa60d4..5a8f21a 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -19,11 +19,7 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: dmenu.h config.h config.mk - -config.h: - @echo creating $@ from config.default.h - @cp config.default.h $@ +${OBJ}: dmenu.h config.mk dmenu: ${OBJ} @echo LD $@ diff --git a/dmenubar/config.arg.h b/dmenubar/config.arg.h deleted file mode 100644 index 5b99a2c..0000000 --- a/dmenubar/config.arg.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*" -#define SELBGCOLOR "#333366" -#define SELFGCOLOR "#eeeeee" -#define NORMBGCOLOR "#333333" -#define NORMFGCOLOR "#dddddd" -#define STDIN_TIMEOUT 3 /* seconds */ diff --git a/dmenubar/config.default.h b/dmenubar/config.default.h deleted file mode 100644 index 0bae3a1..0000000 --- a/dmenubar/config.default.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - -#define FONT "fixed" -#define SELBGCOLOR "#666699" -#define SELFGCOLOR "#eeeeee" -#define NORMBGCOLOR "#333366" -#define NORMFGCOLOR "#cccccc" -#define STDIN_TIMEOUT 3 /* seconds */ diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 3af05bd..8440322 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.0 +VERSION = 1.1 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 7495ef3..cfe16b4 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,6 +3,12 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu +.RB [ \-font <name> ] +.RB [ \-normbg <color> ] +.RB [ \-normfg <color> ] +.RB [ \-selbg <color> ] +.RB [ \-selfg <color> ] +.RB [ \-t <seconds> ] .RB [ \-v ] .SH DESCRIPTION .SS Overview @@ -12,6 +18,24 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP +.B \-font <name> +defines the font. +.TP +.B \-normbg <color> +defines the normal background color (#RGB, #RRGGBB, and color names are supported). +.TP +.B \-normfg <color> +defines the normal foreground color (#RGB, #RRGGBB, and color names are supported). +.TP +.B \-selbg <color> +defines the selected background color (#RGB, #RRGGBB, and color names are supported). +.TP +.B \-selfg <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 @@ -52,8 +76,5 @@ Remove enough characters from the input field to change its filtering effect. .TP .B Control-u Remove all characters from the input field. -.SH CUSTOMIZATION -dmenu is customized by creating a custom config.h and (re)compiling the source -code. This keeps it fast, secure and simple. .SH SEE ALSO .BR dwm (1) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index eed5689..d4065d2 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -3,10 +3,14 @@ * See LICENSE file for license details. */ -#include "config.h" #include <X11/Xlib.h> #include <X11/Xlocale.h> +#define FONT "fixed" +#define NORMBGCOLOR "#333366" +#define NORMFGCOLOR "#cccccc" +#define SELBGCOLOR "#666699" +#define SELFGCOLOR "#eeeeee" #define SPACE 30 /* px */ /* color */ diff --git a/dmenubar/main.c b/dmenubar/main.c index 170a3e0..27b28af 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -283,19 +283,41 @@ DC dc = {0}; int main(int argc, char *argv[]) { + char *font = FONT; char *maxname; + char *normbg = NORMBGCOLOR; + char *normfg = NORMFGCOLOR; + char *selbg = SELBGCOLOR; + char *selfg = SELFGCOLOR; fd_set rd; + int i; struct timeval timeout; - Item *i; + Item *itm; XEvent ev; XSetWindowAttributes wa; - if(argc == 2 && !strncmp("-v", argv[1], 3)) { - fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); - exit(EXIT_SUCCESS); - } - else if(argc != 1) - eprint("usage: dmenu [-v]\n"); + timeout.tv_usec = 0; + timeout.tv_sec = 3; + /* command line args */ + for(i = 1; i < argc; i++) + if(!strncmp(argv[i], "-font", 6)) + font = argv[++i]; + else if(!strncmp(argv[i], "-normbg", 8)) + normbg = argv[++i]; + else if(!strncmp(argv[i], "-normfg", 8)) + normfg = argv[++i]; + else if(!strncmp(argv[i], "-selbg", 7)) + selbg = argv[++i]; + else if(!strncmp(argv[i], "-selfg", 7)) + selfg = argv[++i]; + else if(!strncmp(argv[i], "-t", 3)) + timeout.tv_sec = atoi(argv[++i]); + else if(!strncmp(argv[i], "-v", 3)) { + fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); + exit(EXIT_SUCCESS); + } + else + eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-t <seconds>] [-v]\n", stdout); dpy = XOpenDisplay(0); if(!dpy) @@ -312,8 +334,6 @@ main(int argc, char *argv[]) { GrabModeAsync, CurrentTime) != GrabSuccess) 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) @@ -321,11 +341,11 @@ main(int argc, char *argv[]) { maxname = readstdin(); /* style */ - dc.sel[ColBG] = getcolor(SELBGCOLOR); - dc.sel[ColFG] = getcolor(SELFGCOLOR); - dc.norm[ColBG] = getcolor(NORMBGCOLOR); - dc.norm[ColFG] = getcolor(NORMFGCOLOR); - setfont(FONT); + dc.sel[ColBG] = getcolor(selbg); + dc.sel[ColFG] = getcolor(selfg); + dc.norm[ColBG] = getcolor(normbg); + dc.norm[ColFG] = getcolor(normfg); + setfont(font); wa.override_redirect = 1; wa.background_pixmap = ParentRelative; @@ -373,10 +393,10 @@ main(int argc, char *argv[]) { } while(allitems) { - i = allitems->next; + itm = allitems->next; free(allitems->text); free(allitems); - allitems = i; + allitems = itm; } if(dc.font.set) XFreeFontSet(dpy, dc.font.set); From e86ca83a637d8721ec1e8183c29d518988044257 Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 13:37:36 +0200 Subject: [PATCH 091/590] added fallback to color initialization --- dmenubar/dmenu.h | 3 ++- dmenubar/draw.c | 5 +++-- dmenubar/main.c | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index d4065d2..b58a32b 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -43,7 +43,8 @@ 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 unsigned long getcolor( + const char *colstr, const char *alternate); /* 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 */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 10a011d..dafc107 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -76,11 +76,12 @@ drawtext(const char *text, unsigned long col[ColLast]) { } unsigned long -getcolor(const char *colstr) { +getcolor(const char *colstr, const char *alternate) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; - XAllocNamedColor(dpy, cmap, colstr, &color, &color); + if(XAllocNamedColor(dpy, cmap, colstr, &color, &color) != Success) + XAllocNamedColor(dpy, cmap, alternate, &color, &color); return color.pixel; } diff --git a/dmenubar/main.c b/dmenubar/main.c index 27b28af..5a9b3b9 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -341,10 +341,10 @@ main(int argc, char *argv[]) { maxname = readstdin(); /* style */ - dc.sel[ColBG] = getcolor(selbg); - dc.sel[ColFG] = getcolor(selfg); - dc.norm[ColBG] = getcolor(normbg); - dc.norm[ColFG] = getcolor(normfg); + dc.norm[ColBG] = getcolor(normbg, NORMBGCOLOR); + dc.norm[ColFG] = getcolor(normfg, NORMFGCOLOR); + dc.sel[ColBG] = getcolor(selbg, SELBGCOLOR); + dc.sel[ColFG] = getcolor(selfg, SELFGCOLOR); setfont(font); wa.override_redirect = 1; From a46295bf8a555a559e3d5204f97d5683ff0d11a7 Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 13:39:00 +0200 Subject: [PATCH 092/590] reverting --- dmenubar/dmenu.h | 3 +-- dmenubar/draw.c | 5 ++--- dmenubar/main.c | 8 ++++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index b58a32b..d4065d2 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -43,8 +43,7 @@ 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, const char *alternate); /* returns color of colstr */ +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 */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c index dafc107..10a011d 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -76,12 +76,11 @@ drawtext(const char *text, unsigned long col[ColLast]) { } unsigned long -getcolor(const char *colstr, const char *alternate) { +getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; - if(XAllocNamedColor(dpy, cmap, colstr, &color, &color) != Success) - XAllocNamedColor(dpy, cmap, alternate, &color, &color); + XAllocNamedColor(dpy, cmap, colstr, &color, &color); return color.pixel; } diff --git a/dmenubar/main.c b/dmenubar/main.c index 5a9b3b9..f1bba6b 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -341,10 +341,10 @@ main(int argc, char *argv[]) { maxname = readstdin(); /* style */ - dc.norm[ColBG] = getcolor(normbg, NORMBGCOLOR); - dc.norm[ColFG] = getcolor(normfg, NORMFGCOLOR); - dc.sel[ColBG] = getcolor(selbg, SELBGCOLOR); - dc.sel[ColFG] = getcolor(selfg, SELFGCOLOR); + dc.norm[ColBG] = getcolor(normbg); + dc.norm[ColFG] = getcolor(normfg); + dc.sel[ColBG] = getcolor(selbg); + dc.sel[ColFG] = getcolor(selfg); setfont(font); wa.override_redirect = 1; From d398305f28459b703cead9a16822cd3ed22682aa Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 13:41:51 +0200 Subject: [PATCH 093/590] foo --- dmenubar/draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 10a011d..0459392 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -78,7 +78,7 @@ drawtext(const char *text, unsigned long col[ColLast]) { unsigned long getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); - XColor color; + XColor color = {0}; XAllocNamedColor(dpy, cmap, colstr, &color, &color); return color.pixel; From 2c12f3d68279c58abb7ddcd747f63fd438175186 Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 13:45:41 +0200 Subject: [PATCH 094/590] error handling --- dmenubar/draw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 0459392..68b8cb7 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -78,9 +78,10 @@ drawtext(const char *text, unsigned long col[ColLast]) { unsigned long getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); - XColor color = {0}; + XColor color; - XAllocNamedColor(dpy, cmap, colstr, &color, &color); + if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) + eprint("error, cannot allocate color '%s'\n", colstr); return color.pixel; } From d8558c3214a71de2e2f61c9bf384420765a5aee0 Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 14:30:48 +0200 Subject: [PATCH 095/590] removed crap from Makefile --- dmenubar/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 5a8f21a..d208dbb 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -33,8 +33,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.*.h config.mk \ - dmenu.1 dmenu.h ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.h ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} From 09f3d5a94f5f3f2ccad4fa5d0b2bfd4fbc5e4e2b Mon Sep 17 00:00:00 2001 From: "arg@mmvi" <unknown> Date: Tue, 26 Sep 2006 14:31:42 +0200 Subject: [PATCH 096/590] updated README --- dmenubar/README | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dmenubar/README b/dmenubar/README index d66a689..6e84135 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,5 +1,5 @@ dmenu - dynamic menu --------------------- +==================== dmenu is a generic and efficient menu for X. @@ -22,9 +22,3 @@ necessary as root): Running dmenu ------------- See the man page for details. - - -Configuration -------------- -The configuration of dmenu is done by creating a custom config.h -and (re)compiling the source code. From dcb249644ea99af7b62a8fa395debe8585a83d00 Mon Sep 17 00:00:00 2001 From: "arg@zarathustra" <unknown> Date: Tue, 26 Sep 2006 17:39:04 +0200 Subject: [PATCH 097/590] Added tag 1.1 for changeset e8c1e9733752db12f2dbd1fa93c46f5806242ba9 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 26a7db1..e7b12bc 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -8,3 +8,4 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 409667a57221f7e50ba8b5248f638915cd61b366 0.8 d046c818ea467555cc338751c9bf3024609f1f12 0.9 9e11140d4cc3eecac3b0ab752f91528fd5e04be8 1.0 +e8c1e9733752db12f2dbd1fa93c46f5806242ba9 1.1 From 6e82a76687045e522e285acfe5fb266651e4328a Mon Sep 17 00:00:00 2001 From: "arg@zarathustra" <unknown> Date: Tue, 26 Sep 2006 17:51:22 +0200 Subject: [PATCH 098/590] small update to man page (backported) --- dmenubar/dmenu.1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index cfe16b4..c47044a 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,12 +3,12 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-font <name> ] -.RB [ \-normbg <color> ] -.RB [ \-normfg <color> ] -.RB [ \-selbg <color> ] -.RB [ \-selfg <color> ] -.RB [ \-t <seconds> ] +.RB [ \-font " <name>"] +.RB [ \-normbg " <color>"] +.RB [ \-normfg " <color>"] +.RB [ \-selbg " <color>"] +.RB [ \-selfg " <color>"] +.RB [ \-t " <seconds>"] .RB [ \-v ] .SH DESCRIPTION .SS Overview From 190f46c81e114ef14ef1ecaf027b542db13c8b5d Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 6 Oct 2006 11:52:57 +0200 Subject: [PATCH 099/590] removed useless newlines --- dmenubar/dmenu.h | 3 +-- dmenubar/draw.c | 10 +--------- dmenubar/main.c | 27 +++------------------------ dmenubar/util.c | 5 +++-- 4 files changed, 8 insertions(+), 37 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index d4065d2..1eb57ba 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -1,5 +1,4 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 68b8cb7..14bb801 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -1,5 +1,4 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ #include "dmenu.h" @@ -32,21 +31,17 @@ drawtext(const char *text, unsigned long col[ColLast]) { XSetForeground(dpy, dc.gc, col[ColBG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) return; - w = 0; olen = len = strlen(text); if(len >= sizeof(buf)) len = sizeof(buf) - 1; memcpy(buf, text, len); buf[len] = 0; - h = dc.font.ascent + dc.font.descent; y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); - /* shorten text if necessary */ while(len && (w = textnw(buf, len)) > dc.w - h) buf[--len] = 0; @@ -58,10 +53,8 @@ drawtext(const char *text, unsigned long col[ColLast]) { if(len > 3) buf[len - 3] = '.'; } - if(w > dc.w) return; /* too long */ - gcv.foreground = col[ColFG]; if(dc.font.set) { XChangeGC(dpy, dc.gc, GCForeground, &gcv); @@ -106,7 +99,6 @@ setfont(const char *fontstr) { 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); diff --git a/dmenubar/main.c b/dmenubar/main.c index f1bba6b..7b4365e 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -1,5 +1,4 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * (C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> * See LICENSE file for license details. */ @@ -47,7 +46,6 @@ calcoffsets(void) { if(!curr) return; - w = cmdw + 2 * SPACE; for(next = curr; next; next=next->right) { tw = textw(next->text); @@ -57,7 +55,6 @@ calcoffsets(void) { if(w > mw) break; } - w = cmdw + 2 * SPACE; for(prev = curr; prev && prev->left; prev=prev->left) { tw = textw(prev->left->text); @@ -78,18 +75,15 @@ drawmenu(void) { dc.w = mw; dc.h = mh; drawtext(NULL, dc.norm); - /* print command */ if(cmdw && item) dc.w = cmdw; drawtext(text[0] ? text : NULL, dc.norm); dc.x += cmdw; - if(curr) { dc.w = SPACE; drawtext((curr && curr->left) ? "<" : NULL, dc.norm); dc.x += dc.w; - /* determine maximum items */ for(i = curr; i != next; i=i->right) { dc.w = textw(i->text); @@ -98,7 +92,6 @@ drawmenu(void) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } - dc.x = mw - SPACE; dc.w = SPACE; drawtext(next ? ">" : NULL, dc.norm); @@ -114,11 +107,9 @@ match(char *pattern) { if(!pattern) return; - plen = strlen(pattern); item = j = NULL; nitem = 0; - for(i = allitems; i; i=i->next) if(!plen || !strncmp(pattern, i->text, plen)) { if(!j) @@ -142,7 +133,6 @@ match(char *pattern) { j = i; nitem++; } - curr = prev = next = sel = item; calcoffsets(); } @@ -157,12 +147,10 @@ kpress(XKeyEvent * e) { len = strlen(text); buf[0] = 0; num = XLookupString(e, buf, sizeof(buf), &ksym, 0); - if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) return; - /* first check if a control mask is omitted */ if(e->state & ControlMask) { switch (ksym) { @@ -261,7 +249,6 @@ readstdin(void) { maxname = p; max = len; } - new = emalloc(sizeof(Item)); new->next = new->left = new->right = NULL; new->text = p; @@ -318,7 +305,6 @@ main(int argc, char *argv[]) { } else eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-t <seconds>] [-v]\n", stdout); - dpy = XOpenDisplay(0); if(!dpy) eprint("dmenu: cannot open display\n"); @@ -333,44 +319,37 @@ main(int argc, char *argv[]) { 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(); - /* style */ dc.norm[ColBG] = getcolor(normbg); dc.norm[ColFG] = getcolor(normfg); dc.sel[ColBG] = getcolor(selbg); dc.sel[ColFG] = getcolor(selfg); setfont(font); - + /* menu window */ wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; - mx = my = 0; mw = DisplayWidth(dpy, screen); mh = dc.font.height + 2; - win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); - /* pixmap */ dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, 0); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(maxname) cmdw = textw(maxname); if(cmdw > mw / 3) cmdw = mw / 3; - text[0] = 0; match(text); XMapRaised(dpy, win); @@ -392,6 +371,7 @@ main(int argc, char *argv[]) { } } + /* cleanup */ while(allitems) { itm = allitems->next; free(allitems->text); @@ -408,6 +388,5 @@ main(int argc, char *argv[]) { UninitializedEnd: XUngrabKeyboard(dpy, CurrentTime); XCloseDisplay(dpy); - return ret; } diff --git a/dmenubar/util.c b/dmenubar/util.c index d0444c5..b4b163a 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -1,5 +1,4 @@ -/* - * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ #include "dmenu.h" @@ -22,6 +21,7 @@ badmalloc(unsigned int size) { void * emalloc(unsigned int size) { void *res = malloc(size); + if(!res) badmalloc(size); return res; @@ -40,6 +40,7 @@ eprint(const char *errstr, ...) { char * estrdup(const char *str) { void *res = strdup(str); + if(!res) badmalloc(strlen(str)); return res; From 07ef2eeb2c031db22387f9f0bb5d09535e8d7c7f Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 6 Oct 2006 12:39:06 +0200 Subject: [PATCH 100/590] changing version info --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 8440322..c7d3cc7 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.1 +VERSION = 1.2 # Customize below to fit your system From feb8dabacfb042fa313b5788472d96509864f53c Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 6 Oct 2006 12:40:49 +0200 Subject: [PATCH 101/590] small change --- dmenubar/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 7b4365e..fcb9295 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -2,7 +2,6 @@ * (C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> * See LICENSE file for license details. */ - #include "dmenu.h" #include <ctype.h> From 6082d54f96d74f89928805d676fbd6f9806f873a Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 6 Oct 2006 13:44:22 +0200 Subject: [PATCH 102/590] Added tag 1.2 for changeset bee7fe6d1189174d0204ca3195b83cdc1bb4f82e --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index e7b12bc..921dd59 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -9,3 +9,4 @@ d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 d046c818ea467555cc338751c9bf3024609f1f12 0.9 9e11140d4cc3eecac3b0ab752f91528fd5e04be8 1.0 e8c1e9733752db12f2dbd1fa93c46f5806242ba9 1.1 +bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 From e916910ae9cf9148e1b598b71e1fb024ea3cf7d8 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Tue, 10 Oct 2006 19:15:06 +0200 Subject: [PATCH 103/590] simplified main event loop --- dmenubar/config.mk | 2 +- dmenubar/main.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index c7d3cc7..63fbad3 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.2 +VERSION = 1.3 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index fcb9295..3fa1e54 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -356,7 +356,7 @@ main(int argc, char *argv[]) { XSync(dpy, False); /* main event loop */ - while(running && !XNextEvent(dpy, &ev)) { + while(running && !XNextEvent(dpy, &ev)) switch (ev.type) { default: /* ignore all crap */ break; @@ -368,7 +368,6 @@ main(int argc, char *argv[]) { drawmenu(); break; } - } /* cleanup */ while(allitems) { From 022c61a779b4efd90d964086f59503f335e589ae Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 12 Oct 2006 12:58:34 +0200 Subject: [PATCH 104/590] simplified util.c --- dmenubar/util.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/dmenubar/util.c b/dmenubar/util.c index b4b163a..b7798d2 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -9,21 +9,21 @@ #include <sys/wait.h> #include <unistd.h> -/* static */ - -static void -badmalloc(unsigned int size) { - eprint("fatal: could not malloc() %u bytes\n", size); -} - -/* extern */ - void * emalloc(unsigned int size) { void *res = malloc(size); if(!res) - badmalloc(size); + eprint("fatal: could not malloc() %u bytes\n", size); + return res; +} + +char * +estrdup(const char *str) { + void *res = strdup(str); + + if(!res) + eprint("fatal: could not malloc() %u bytes\n", strlen(str)); return res; } @@ -36,12 +36,3 @@ eprint(const char *errstr, ...) { va_end(ap); exit(EXIT_FAILURE); } - -char * -estrdup(const char *str) { - void *res = strdup(str); - - if(!res) - badmalloc(strlen(str)); - return res; -} From 64db36790089909be88306e5a6b3d530b0e0ec31 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Thu, 12 Oct 2006 12:59:37 +0200 Subject: [PATCH 105/590] changing order --- dmenubar/util.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dmenubar/util.c b/dmenubar/util.c index b7798d2..0427ed5 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -18,15 +18,6 @@ emalloc(unsigned int size) { return res; } -char * -estrdup(const char *str) { - void *res = strdup(str); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", strlen(str)); - return res; -} - void eprint(const char *errstr, ...) { va_list ap; @@ -36,3 +27,12 @@ eprint(const char *errstr, ...) { va_end(ap); exit(EXIT_FAILURE); } + +char * +estrdup(const char *str) { + void *res = strdup(str); + + if(!res) + eprint("fatal: could not malloc() %u bytes\n", strlen(str)); + return res; +} From 7ffe09d8de2071faa5253bdf8e067fabc8ac555a Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@10kloc.org> Date: Fri, 13 Oct 2006 11:08:35 +0200 Subject: [PATCH 106/590] Added tag 1.3 for changeset 2eb9997be51cb1b11a8900728ccc0904f9371157 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 921dd59..a3a7af6 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -10,3 +10,4 @@ d046c818ea467555cc338751c9bf3024609f1f12 0.9 9e11140d4cc3eecac3b0ab752f91528fd5e04be8 1.0 e8c1e9733752db12f2dbd1fa93c46f5806242ba9 1.1 bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 +2eb9997be51cb1b11a8900728ccc0904f9371157 1.3 From 4a56486d7906926f999793af345c1ed99ca44977 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 23 Oct 2006 10:12:09 +0200 Subject: [PATCH 107/590] fixing arg handling in dmenu (thanks to Sander for his report) --- dmenubar/config.mk | 2 +- dmenubar/main.c | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 63fbad3..e0be79f 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.3 +VERSION = 1.4 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index 3fa1e54..1d37f70 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -286,18 +286,24 @@ main(int argc, char *argv[]) { timeout.tv_sec = 3; /* command line args */ for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-font", 6)) - font = argv[++i]; - else if(!strncmp(argv[i], "-normbg", 8)) - normbg = argv[++i]; - else if(!strncmp(argv[i], "-normfg", 8)) - normfg = argv[++i]; - else if(!strncmp(argv[i], "-selbg", 7)) - selbg = argv[++i]; - else if(!strncmp(argv[i], "-selfg", 7)) - selfg = argv[++i]; - else if(!strncmp(argv[i], "-t", 3)) - timeout.tv_sec = atoi(argv[++i]); + if(!strncmp(argv[i], "-font", 6)) { + if(++i < argc) font = argv[i]; + } + else if(!strncmp(argv[i], "-normbg", 8)) { + if(++i < argc) normbg = argv[i]; + } + else if(!strncmp(argv[i], "-normfg", 8)) { + if(++i < argc) normfg = argv[i]; + } + else if(!strncmp(argv[i], "-selbg", 7)) { + if(++i < argc) selbg = argv[i]; + } + else if(!strncmp(argv[i], "-selfg", 7)) { + 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 Anselm R. Garbe\n", stdout); exit(EXIT_SUCCESS); From 714e155474877bbe1a8007445db5978fe1d72e92 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 23 Oct 2006 12:53:35 +0200 Subject: [PATCH 108/590] removed misleading input cursor --- dmenubar/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 1d37f70..7228cb6 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -11,7 +11,6 @@ #include <unistd.h> #include <sys/select.h> #include <sys/time.h> -#include <X11/cursorfont.h> #include <X11/Xutil.h> #include <X11/keysym.h> @@ -346,7 +345,6 @@ main(int argc, char *argv[]) { DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); /* pixmap */ dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, 0); From 4548c07ef8858f21d781c33e0bef9ecefb882ead Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 26 Oct 2006 12:14:03 +0200 Subject: [PATCH 109/590] Added tag 1.4 for changeset df3fbb050004c544d14e43c36f6a94cca6ed4a69 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index a3a7af6..1b5999b 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -11,3 +11,4 @@ d046c818ea467555cc338751c9bf3024609f1f12 0.9 e8c1e9733752db12f2dbd1fa93c46f5806242ba9 1.1 bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 2eb9997be51cb1b11a8900728ccc0904f9371157 1.3 +df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 From 3a78327189c9f1a4d2e2cc20a52d0f6a3619fed9 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Sun, 26 Nov 2006 15:49:33 +0100 Subject: [PATCH 110/590] fixing sizeof stuff --- dmenubar/draw.c | 4 ++-- dmenubar/main.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 14bb801..74a47a6 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -35,8 +35,8 @@ drawtext(const char *text, unsigned long col[ColLast]) { return; w = 0; olen = len = strlen(text); - if(len >= sizeof(buf)) - len = sizeof(buf) - 1; + if(len >= sizeof buf) + len = sizeof buf - 1; memcpy(buf, text, len); buf[len] = 0; h = dc.font.ascent + dc.font.descent; diff --git a/dmenubar/main.c b/dmenubar/main.c index 7228cb6..ce13a80 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -144,7 +144,7 @@ kpress(XKeyEvent * e) { len = strlen(text); buf[0] = 0; - num = XLookupString(e, buf, sizeof(buf), &ksym, 0); + num = XLookupString(e, buf, sizeof buf, &ksym, 0); if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) @@ -181,7 +181,7 @@ kpress(XKeyEvent * e) { case XK_Tab: if(!sel) return; - strncpy(text, sel->text, sizeof(text)); + strncpy(text, sel->text, sizeof text); match(text); break; case XK_Right: @@ -221,9 +221,9 @@ kpress(XKeyEvent * e) { if(num && !iscntrl((int) buf[0])) { buf[num] = 0; if(len > 0) - strncat(text, buf, sizeof(text)); + strncat(text, buf, sizeof text); else - strncpy(text, buf, sizeof(text)); + strncpy(text, buf, sizeof text); match(text); } } @@ -238,7 +238,7 @@ readstdin(void) { Item *i, *new; i = 0; - while(fgets(buf, sizeof(buf), stdin)) { + while(fgets(buf, sizeof buf, stdin)) { len = strlen(buf); if (buf[len - 1] == '\n') buf[len - 1] = 0; From 1deed2fde18f9a086dc4dbaf6046bf508d713460 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Sun, 26 Nov 2006 15:49:47 +0100 Subject: [PATCH 111/590] next version will be 1.5 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index e0be79f..b211c07 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.4 +VERSION = 1.5 # Customize below to fit your system From 5a9790e24ad89efef09f770634aa99802627693c Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 30 Nov 2006 09:21:14 +0100 Subject: [PATCH 112/590] Added tag 1.5 for changeset e071fb045bd9e8574947acff7196360bc0270e68 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 1b5999b..a7e936f 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -12,3 +12,4 @@ e8c1e9733752db12f2dbd1fa93c46f5806242ba9 1.1 bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 2eb9997be51cb1b11a8900728ccc0904f9371157 1.3 df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 +e071fb045bd9e8574947acff7196360bc0270e68 1.5 From e34fbd2320676c20b4e27f1ff57564f945b1a3fa Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 5 Dec 2006 10:31:20 +0100 Subject: [PATCH 113/590] enforcing using imcomplete fonsets anyways --- dmenubar/config.mk | 2 +- dmenubar/draw.c | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index b211c07..280a034 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.5 +VERSION = 1.6 # Customize below to fit your system diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 74a47a6..56a1beb 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -88,13 +88,8 @@ setfont(const char *fontstr) { if(dc.font.set) XFreeFontSet(dpy, dc.font.set); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); - if(missing) { + if(missing) XFreeStringList(missing); - if(dc.font.set) { - XFreeFontSet(dpy, dc.font.set); - dc.font.set = NULL; - } - } if(dc.font.set) { XFontSetExtents *font_extents; XFontStruct **xfonts; From c3af8065ce329e795ceb0bde3d0393414e36b577 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 5 Dec 2006 13:30:37 +0100 Subject: [PATCH 114/590] only setting LC_CTYPE --- dmenubar/dmenu.h | 3 +-- dmenubar/draw.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 1eb57ba..08d7605 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -3,14 +3,13 @@ */ #include <X11/Xlib.h> -#include <X11/Xlocale.h> #define FONT "fixed" #define NORMBGCOLOR "#333366" #define NORMFGCOLOR "#cccccc" #define SELBGCOLOR "#666699" #define SELFGCOLOR "#eeeeee" -#define SPACE 30 /* px */ +#define SPACE 30 /* px */ /* color */ enum { ColFG, ColBG, ColLast }; diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 56a1beb..29289a4 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -84,7 +84,7 @@ setfont(const char *fontstr) { int i, n; missing = NULL; - setlocale(LC_ALL, ""); + setlocale(LC_CTYPE, ""); if(dc.font.set) XFreeFontSet(dpy, dc.font.set); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); From 74c3c4758469df042f8b0a04a7b5f43f3074f6ca Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 7 Dec 2006 10:06:06 +0100 Subject: [PATCH 115/590] also fixing dmenu accordingly --- dmenubar/draw.c | 2 -- dmenubar/main.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 29289a4..62f6e2c 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -4,7 +4,6 @@ #include "dmenu.h" #include <stdio.h> #include <string.h> -#include <X11/Xlocale.h> /* static */ @@ -84,7 +83,6 @@ setfont(const char *fontstr) { int i, n; missing = NULL; - setlocale(LC_CTYPE, ""); if(dc.font.set) XFreeFontSet(dpy, dc.font.set); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); diff --git a/dmenubar/main.c b/dmenubar/main.c index ce13a80..743967a 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -5,6 +5,7 @@ #include "dmenu.h" #include <ctype.h> +#include <locale.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -309,6 +310,7 @@ main(int argc, char *argv[]) { } else eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-t <seconds>] [-v]\n", stdout); + setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) eprint("dmenu: cannot open display\n"); From 563fd4424d755543df6e8de226ef37dca3726a3f Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 7 Dec 2006 11:55:46 +0100 Subject: [PATCH 116/590] using -*-fixed-*-*-*-*-*-*-*-*-*-*-iso10646-* fixed by default --- dmenubar/dmenu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 08d7605..465273c 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -4,7 +4,7 @@ #include <X11/Xlib.h> -#define FONT "fixed" +#define FONT "-*-fixed-*-*-*-*-*-*-*-*-*-*-iso10646-*" #define NORMBGCOLOR "#333366" #define NORMFGCOLOR "#cccccc" #define SELBGCOLOR "#666699" From 0113211338d27bbb9b7fc7b462fb7525a806551a Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 7 Dec 2006 12:03:47 +0100 Subject: [PATCH 117/590] people should define fixed being compatible with their locale --- dmenubar/dmenu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 465273c..08d7605 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -4,7 +4,7 @@ #include <X11/Xlib.h> -#define FONT "-*-fixed-*-*-*-*-*-*-*-*-*-*-iso10646-*" +#define FONT "fixed" #define NORMBGCOLOR "#333366" #define NORMFGCOLOR "#cccccc" #define SELBGCOLOR "#666699" From e3a3de76bb11e681c2456e0d6eab63467b9f6585 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 7 Dec 2006 14:38:31 +0100 Subject: [PATCH 118/590] found compromise --- dmenubar/dmenu.h | 2 +- dmenubar/draw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 08d7605..ff9790d 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -4,7 +4,7 @@ #include <X11/Xlib.h> -#define FONT "fixed" +#define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*" #define NORMBGCOLOR "#333366" #define NORMFGCOLOR "#cccccc" #define SELBGCOLOR "#666699" diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 62f6e2c..bd11091 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -79,7 +79,7 @@ getcolor(const char *colstr) { void setfont(const char *fontstr) { - char **missing, *def; + char *def, **missing; int i, n; missing = NULL; From be78345ff9bfa341f4d907ea77c2e39b37c36c33 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 7 Dec 2006 14:54:47 +0100 Subject: [PATCH 119/590] Added tag 1.6 for changeset dcc5427f99f51a978386a0dd770467cd911ac84b --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index a7e936f..78f0f3c 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -13,3 +13,4 @@ bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 2eb9997be51cb1b11a8900728ccc0904f9371157 1.3 df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 e071fb045bd9e8574947acff7196360bc0270e68 1.5 +dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 From 771bb341ae439a689ba83804e3adad6229a36eee Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Fri, 8 Dec 2006 10:41:16 +0100 Subject: [PATCH 120/590] removed hardcoded 'fixed' fallback, useless and misleading --- dmenubar/config.mk | 2 +- dmenubar/draw.c | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 280a034..bc89b16 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.6 +VERSION = 1.7 # Customize below to fit your system diff --git a/dmenubar/draw.c b/dmenubar/draw.c index bd11091..ea02c4d 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -107,10 +107,7 @@ setfont(const char *fontstr) { if(dc.font.xfont) XFreeFont(dpy, dc.font.xfont); dc.font.xfont = NULL; - dc.font.xfont = XLoadQueryFont(dpy, fontstr); - if (!dc.font.xfont) - dc.font.xfont = XLoadQueryFont(dpy, "fixed"); - if (!dc.font.xfont) + if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))) eprint("error, cannot init 'fixed' font\n"); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; From 70d78b09522cfff541f38dc9bdb74eaa4480badb Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Fri, 8 Dec 2006 11:12:11 +0100 Subject: [PATCH 121/590] fixed diagnostic error message --- dmenubar/draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index ea02c4d..710af8e 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -108,7 +108,7 @@ setfont(const char *fontstr) { XFreeFont(dpy, dc.font.xfont); dc.font.xfont = NULL; if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))) - eprint("error, cannot init 'fixed' font\n"); + eprint("error, cannot load font: '%s'\n", fontstr); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; } From eb43ec3adec43b73c5719b97c9ce38c4a41e3192 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 12 Dec 2006 09:57:42 +0100 Subject: [PATCH 122/590] ordered switch branches in kpress alphabetically, applied Sanders patch for PgUp/Dn and Home/End scrolling --- dmenubar/dmenu.1 | 8 ++++- dmenubar/main.c | 89 +++++++++++++++++++++++++++++++----------------- 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index c47044a..ff0c000 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -40,7 +40,7 @@ defines the seconds to wait for standard input, before exiting (default is 3). prints version information to standard output, then exits. .SH USAGE dmenu reads a list of newline-separated items from standard input and creates a -menu. When the user selects an item or enters any text and presses Return, his +menu. When the user selects an item or enters any text and presses Return, his/her choice is printed to standard output and dmenu terminates. .P dmenu is completely controlled by the keyboard. The following keys are recognized: @@ -52,6 +52,12 @@ only items containing this text will be displayed. .B Left/Right Select the previous/next item. .TP +.B PageUp/PageDown +Select the first item of the previous/next 'page' of items. +.TP +.B Home/End +Select the first/last item. +.TP .B Tab Copy the selected item to the input field. .TP diff --git a/dmenubar/main.c b/dmenubar/main.c index 743967a..0263948 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -170,6 +170,42 @@ kpress(XKeyEvent * e) { } } switch(ksym) { + default: + if(num && !iscntrl((int) buf[0])) { + buf[num] = 0; + if(len > 0) + strncat(text, buf, sizeof text); + else + strncpy(text, buf, sizeof text); + match(text); + } + break; + case XK_BackSpace: + if((i = len)) { + prev_nitem = nitem; + do { + text[--i] = 0; + match(text); + } while(i && nitem && prev_nitem == nitem); + match(text); + } + break; + case XK_End: + while(next) { + sel = curr = next; + calcoffsets(); + } + while(sel->right) + sel = sel->right; + break; + case XK_Escape: + ret = 1; + running = False; + break; + case XK_Home: + sel = curr = item; + calcoffsets(); + break; case XK_Left: if(!(sel && sel->left)) return; @@ -179,18 +215,15 @@ kpress(XKeyEvent * e) { calcoffsets(); } break; - case XK_Tab: - if(!sel) - return; - strncpy(text, sel->text, sizeof text); - match(text); + case XK_Next: + if(next) { + sel = curr = next; + calcoffsets(); + } break; - case XK_Right: - if(!(sel && sel->right)) - return; - sel=sel->right; - if(sel == next) { - curr = next; + case XK_Prior: + if(prev) { + sel = curr = prev; calcoffsets(); } break; @@ -204,29 +237,21 @@ kpress(XKeyEvent * e) { fflush(stdout); running = False; break; - case XK_Escape: - ret = 1; - running = False; - break; - case XK_BackSpace: - if((i = len)) { - prev_nitem = nitem; - do { - text[--i] = 0; - match(text); - } while(i && nitem && prev_nitem == nitem); - match(text); + case XK_Right: + if(!(sel && sel->right)) + return; + sel=sel->right; + if(sel == next) { + curr = next; + calcoffsets(); } break; - default: - if(num && !iscntrl((int) buf[0])) { - buf[num] = 0; - if(len > 0) - strncat(text, buf, sizeof text); - else - strncpy(text, buf, sizeof text); - match(text); - } + case XK_Tab: + if(!sel) + return; + strncpy(text, sel->text, sizeof text); + match(text); + break; } drawmenu(); } From 56b0de9b85494f11b1842c5df99c3aa3acba9270 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Wed, 13 Dec 2006 14:14:41 +0100 Subject: [PATCH 123/590] added prompt option (-p 'prompt text'), documented in man page as well --- dmenubar/dmenu.1 | 4 ++++ dmenubar/main.c | 22 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index ff0c000..38e485d 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -8,6 +8,7 @@ dmenu \- dynamic menu .RB [ \-normfg " <color>"] .RB [ \-selbg " <color>"] .RB [ \-selfg " <color>"] +.RB [ \-p " <prompt>"] .RB [ \-t " <seconds>"] .RB [ \-v ] .SH DESCRIPTION @@ -33,6 +34,9 @@ defines the selected background color (#RGB, #RRGGBB, and color names are suppor .B \-selfg <color> defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). .TP +.B \-p <prompt> +defines a prompt being displayed before input area. +.TP .B \-t <seconds> defines the seconds to wait for standard input, before exiting (default is 3). .TP diff --git a/dmenubar/main.c b/dmenubar/main.c index 0263948..964fad6 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -25,10 +25,12 @@ struct Item { /* static */ static char text[4096]; +static char *prompt = NULL; static int mx, my, mw, mh; static int ret = 0; static int nitem = 0; static unsigned int cmdw = 0; +static unsigned int promptw = 0; static Bool running = True; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ @@ -45,7 +47,7 @@ calcoffsets(void) { if(!curr) return; - w = cmdw + 2 * SPACE; + w = promptw + cmdw + 2 * SPACE; for(next = curr; next; next=next->right) { tw = textw(next->text); if(tw > mw / 3) @@ -54,7 +56,7 @@ calcoffsets(void) { if(w > mw) break; } - w = cmdw + 2 * SPACE; + w = promptw + cmdw + 2 * SPACE; for(prev = curr; prev && prev->left; prev=prev->left) { tw = textw(prev->left->text); if(tw > mw / 3) @@ -74,6 +76,13 @@ drawmenu(void) { dc.w = mw; dc.h = mh; drawtext(NULL, dc.norm); + /* print prompt? */ + if(promptw) { + dc.w = promptw; + drawtext(prompt, dc.sel); + } + dc.x += promptw; + dc.w = mw - promptw; /* print command */ if(cmdw && item) dc.w = cmdw; @@ -326,6 +335,9 @@ main(int argc, char *argv[]) { else if(!strncmp(argv[i], "-selfg", 7)) { if(++i < argc) selfg = argv[i]; } + else if(!strncmp(argv[i], "-p", 3)) { + if(++i < argc) prompt = argv[i]; + } else if(!strncmp(argv[i], "-t", 3)) { if(++i < argc) timeout.tv_sec = atoi(argv[i]); } @@ -334,7 +346,7 @@ main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } else - eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-t <seconds>] [-v]\n", stdout); + eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-p <prompt>] [-t <seconds>] [-v]\n", stdout); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) @@ -380,6 +392,10 @@ main(int argc, char *argv[]) { cmdw = textw(maxname); if(cmdw > mw / 3) cmdw = mw / 3; + if(prompt) + promptw = textw(prompt); + if(promptw > mw / 5) + promptw = mw / 5; text[0] = 0; match(text); XMapRaised(dpy, win); From 69ff8f2de51284532177099579a25b3d31be14bc Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Wed, 13 Dec 2006 14:36:09 +0100 Subject: [PATCH 124/590] changed text in dmenu manpage --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 38e485d..694debd 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -35,7 +35,7 @@ defines the selected background color (#RGB, #RRGGBB, and color names are suppor defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). .TP .B \-p <prompt> -defines a prompt being displayed before input area. +defines a prompt to be displayed before the input area. .TP .B \-t <seconds> defines the seconds to wait for standard input, before exiting (default is 3). From fadcdef6745ad6b1ef067377e524e717d3951c4f Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 08:51:21 +0100 Subject: [PATCH 125/590] Added tag 1.7 for changeset 58dbef4aef3d45c7a3da6945e53c9667c0f02d5b --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 78f0f3c..bf8c770 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -14,3 +14,4 @@ bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 e071fb045bd9e8574947acff7196360bc0270e68 1.5 dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 +58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 From ce243552411b1327cf3a4c5bf07933de5cdc76c1 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 09:30:23 +0100 Subject: [PATCH 126/590] applied hotfix of sander --- dmenubar/config.mk | 2 +- dmenubar/main.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index bc89b16..7beebff 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.7 +VERSION = 1.7.1 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index 964fad6..3ea9d89 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -200,11 +200,13 @@ kpress(XKeyEvent * e) { } break; case XK_End: + if(!sel) + return; while(next) { sel = curr = next; calcoffsets(); } - while(sel->right) + while(sel && sel->right) sel = sel->right; break; case XK_Escape: @@ -212,6 +214,8 @@ kpress(XKeyEvent * e) { running = False; break; case XK_Home: + if(!item) + return; sel = curr = item; calcoffsets(); break; @@ -225,16 +229,16 @@ kpress(XKeyEvent * e) { } break; case XK_Next: - if(next) { - sel = curr = next; - calcoffsets(); - } + if(!next) + return; + sel = curr = next; + calcoffsets(); break; case XK_Prior: - if(prev) { - sel = curr = prev; - calcoffsets(); - } + if(!prev) + return; + sel = curr = prev; + calcoffsets(); break; case XK_Return: if((e->state & ShiftMask) && text) From 60852051c90cec3cedd277622a77c7a152c2f3c9 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 09:30:31 +0100 Subject: [PATCH 127/590] Added tag 1.7.1 for changeset 8e0b9b09bf83c429c73e60a23997f32877a645bf --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index bf8c770..ad90308 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -15,3 +15,4 @@ df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 e071fb045bd9e8574947acff7196360bc0270e68 1.5 dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 +8e0b9b09bf83c429c73e60a23997f32877a645bf 1.7.1 From b7dc7ed52ee21b0fb1e31420d97a1703c794d477 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 09:34:24 +0100 Subject: [PATCH 128/590] silent hotfix --- dmenubar/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 3ea9d89..c10dfaa 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -200,7 +200,7 @@ kpress(XKeyEvent * e) { } break; case XK_End: - if(!sel) + if(!item) return; while(next) { sel = curr = next; From ffd5dea305e57e4fbff622a95dbc50426305a4be Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 09:45:06 +0100 Subject: [PATCH 129/590] foo --- dmenubar/.hgtags | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index ad90308..bf8c770 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -15,4 +15,3 @@ df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 e071fb045bd9e8574947acff7196360bc0270e68 1.5 dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 -8e0b9b09bf83c429c73e60a23997f32877a645bf 1.7.1 From 66e0f28dfc2bfeee22d536bea52157af47bb83e5 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 09:45:11 +0100 Subject: [PATCH 130/590] Added tag 1.7.1 for changeset 3696d77aaf02f5d15728dde3b9e35abcaf291496 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index bf8c770..4c657a4 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -15,3 +15,4 @@ df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 e071fb045bd9e8574947acff7196360bc0270e68 1.5 dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 +3696d77aaf02f5d15728dde3b9e35abcaf291496 1.7.1 From faa7fbad82bc0c0b333d14922147ad783da1d52e Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 14:40:58 +0100 Subject: [PATCH 131/590] added vi-like key-bindings for keyboards without cursor keys (they are undocumented features) --- dmenubar/config.mk | 2 +- dmenubar/main.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 7beebff..00fe5a9 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.7.1 +VERSION = 1.8 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index c10dfaa..06b2ca9 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -178,6 +178,29 @@ kpress(XKeyEvent * e) { break; } } + if(e->state & Mod1Mask) { + switch(ksym) { + default: return; + case XK_h: + ksym = XK_Left; + break; + case XK_l: + ksym = XK_Right; + break; + case XK_j: + ksym = XK_Next; + break; + case XK_l: + ksym = XK_Prior; + break; + case XK_g: + ksym = XK_Home; + break; + case XK_G: + ksym = XK_End; + break; + } + } switch(ksym) { default: if(num && !iscntrl((int) buf[0])) { From 7c0ff994c851c7ea492c334c92bd89563fa713a3 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Thu, 14 Dec 2006 14:41:53 +0100 Subject: [PATCH 132/590] hotfix --- dmenubar/main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 06b2ca9..1c6e57f 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -182,23 +182,23 @@ kpress(XKeyEvent * e) { switch(ksym) { default: return; case XK_h: - ksym = XK_Left; - break; + ksym = XK_Left; + break; case XK_l: - ksym = XK_Right; - break; + ksym = XK_Right; + break; case XK_j: - ksym = XK_Next; - break; - case XK_l: - ksym = XK_Prior; - break; + ksym = XK_Next; + break; + case XK_k: + ksym = XK_Prior; + break; case XK_g: - ksym = XK_Home; - break; + ksym = XK_Home; + break; case XK_G: - ksym = XK_End; - break; + ksym = XK_End; + break; } } switch(ksym) { From de7ab0f95daf1e8171355e1ce0c3d8a1e24c1deb Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Mon, 18 Dec 2006 12:52:58 +0100 Subject: [PATCH 133/590] applied Stefan Tibus' sun patch, added -bottom option to dmenu which makes it appear in the bottom (for wmii compliance), slightly modified version than the patch proposed by Stefan Tibus --- dmenubar/config.mk | 5 +++++ dmenubar/dmenu.1 | 4 ++++ dmenubar/main.c | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 00fe5a9..1670243 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -20,6 +20,11 @@ LDFLAGS = ${LIBS} #CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = -g ${LIBS} +# Solaris +#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = ${LIBS} +#CFLAGS += -xtarget=ultra + # compiler and linker CC = cc LD = ${CC} diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 694debd..76bb71c 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,6 +3,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu +.RB [ \-bottom ] .RB [ \-font " <name>"] .RB [ \-normbg " <color>"] .RB [ \-normfg " <color>"] @@ -19,6 +20,9 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP +.B \-bottom +makes dmenu appear at the screen bottom (by default it appears at the screen top). +.TP .B \-font <name> defines the font. .TP diff --git a/dmenubar/main.c b/dmenubar/main.c index 1c6e57f..7fca45e 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -330,6 +330,7 @@ DC dc = {0}; int main(int argc, char *argv[]) { + Bool bottom = False; char *font = FONT; char *maxname; char *normbg = NORMBGCOLOR; @@ -347,7 +348,10 @@ main(int argc, char *argv[]) { timeout.tv_sec = 3; /* command line args */ for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-font", 6)) { + if(!strncmp(argv[i], "-bottom", 8)) { + bottom = True; + } + else if(!strncmp(argv[i], "-font", 6)) { if(++i < argc) font = argv[i]; } else if(!strncmp(argv[i], "-normbg", 8)) { @@ -373,7 +377,8 @@ main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } else - eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-p <prompt>] [-t <seconds>] [-v]\n", stdout); + eprint("usage: dmenu [-bottom] [-font <name>] [-{norm,sel}{bg,fg} <color>]\n" + " [-p <prompt>] [-t <seconds>] [-v]\n", stdout); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) @@ -406,7 +411,12 @@ main(int argc, char *argv[]) { wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; mx = my = 0; mw = DisplayWidth(dpy, screen); - mh = dc.font.height + 2; + if(bottom) { + mh = dc.font.ascent + dc.font.descent + 3; // match wmii + my = DisplayHeight(dpy, screen) - mh; + } + else + mh = dc.font.height + 2; win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), From fa2ee99182d4997b8ee90f4f671b23d7ec7e52ae Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Mon, 18 Dec 2006 13:25:11 +0100 Subject: [PATCH 134/590] agreed with Sander --- dmenubar/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 7fca45e..9ef0bae 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -411,12 +411,9 @@ main(int argc, char *argv[]) { wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; mx = my = 0; mw = DisplayWidth(dpy, screen); - if(bottom) { - mh = dc.font.ascent + dc.font.descent + 3; // match wmii - my = DisplayHeight(dpy, screen) - mh; - } - else - mh = dc.font.height + 2; + mh = dc.font.height + 2; + if(bottom) + my += DisplayHeight(dpy, screen) - mh; win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), From eac2a60e9b6a12363f3aa8648949be4a9f29593d Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Mon, 18 Dec 2006 13:46:44 +0100 Subject: [PATCH 135/590] added wmii reference to dmenu(1) --- dmenubar/dmenu.1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 76bb71c..5a3956d 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -91,4 +91,5 @@ Remove enough characters from the input field to change its filtering effect. .B Control-u Remove all characters from the input field. .SH SEE ALSO -.BR dwm (1) +.BR dwm (1), +.BR wmii (1) . From 6509cc9f73a58edc77bac0541d883ef34918a820 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 19 Dec 2006 11:39:07 +0100 Subject: [PATCH 136/590] prepared dmenu-1.8, shortened command line options (-font is -fn, -selbg is -sb, -selfg is -sf, -normbg is -nb, -normfg is -nf now) --- dmenubar/dmenu.1 | 32 ++++++++++++++++---------------- dmenubar/main.c | 24 ++++++++++++------------ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 5a3956d..9cc80a5 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,13 +3,13 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-bottom ] -.RB [ \-font " <name>"] -.RB [ \-normbg " <color>"] -.RB [ \-normfg " <color>"] -.RB [ \-selbg " <color>"] -.RB [ \-selfg " <color>"] +.RB [ \-b ] +.RB [ \-fn " <font>"] +.RB [ \-nb " <color>"] +.RB [ \-nf " <color>"] .RB [ \-p " <prompt>"] +.RB [ \-sb " <color>"] +.RB [ \-sf " <color>"] .RB [ \-t " <seconds>"] .RB [ \-v ] .SH DESCRIPTION @@ -20,27 +20,27 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP -.B \-bottom +.B \-b makes dmenu appear at the screen bottom (by default it appears at the screen top). .TP -.B \-font <name> +.B \-font <font> defines the font. .TP -.B \-normbg <color> +.B \-nb <color> defines the normal background color (#RGB, #RRGGBB, and color names are supported). .TP -.B \-normfg <color> +.B \-nf <color> defines the normal foreground color (#RGB, #RRGGBB, and color names are supported). .TP -.B \-selbg <color> -defines the selected background color (#RGB, #RRGGBB, and color names are supported). -.TP -.B \-selfg <color> -defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). -.TP .B \-p <prompt> defines a prompt to be displayed before the input area. .TP +.B \-sb <color> +defines the selected background color (#RGB, #RRGGBB, and color names are supported). +.TP +.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 diff --git a/dmenubar/main.c b/dmenubar/main.c index 9ef0bae..69214dd 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -348,27 +348,27 @@ main(int argc, char *argv[]) { timeout.tv_sec = 3; /* command line args */ for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-bottom", 8)) { + if(!strncmp(argv[i], "-b", 3)) { bottom = True; } - else if(!strncmp(argv[i], "-font", 6)) { + else if(!strncmp(argv[i], "-fn", 4)) { if(++i < argc) font = argv[i]; } - else if(!strncmp(argv[i], "-normbg", 8)) { + else if(!strncmp(argv[i], "-nb", 4)) { if(++i < argc) normbg = argv[i]; } - else if(!strncmp(argv[i], "-normfg", 8)) { + else if(!strncmp(argv[i], "-nf", 4)) { if(++i < argc) normfg = argv[i]; } - else if(!strncmp(argv[i], "-selbg", 7)) { - if(++i < argc) selbg = argv[i]; - } - else if(!strncmp(argv[i], "-selfg", 7)) { - if(++i < argc) selfg = argv[i]; - } else if(!strncmp(argv[i], "-p", 3)) { if(++i < argc) prompt = argv[i]; } + else if(!strncmp(argv[i], "-sb", 4)) { + if(++i < argc) selbg = argv[i]; + } + 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]); } @@ -377,8 +377,8 @@ main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } else - eprint("usage: dmenu [-bottom] [-font <name>] [-{norm,sel}{bg,fg} <color>]\n" - " [-p <prompt>] [-t <seconds>] [-v]\n", stdout); + eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n" + " [-sb <color>] [-sf <color>] [-t <seconds>] [-v]\n", stdout); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) From caeee5543e653a9d5f308ec9448703e3efe91b29 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 19 Dec 2006 11:49:28 +0100 Subject: [PATCH 137/590] fixed a typo in dmenu.1 --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 9cc80a5..f0bf50c 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -23,7 +23,7 @@ efficiently. .B \-b makes dmenu appear at the screen bottom (by default it appears at the screen top). .TP -.B \-font <font> +.B \-fn <font> defines the font. .TP .B \-nb <color> From 853a1f9c3fb85bc3451fd6b27f4ea3df71f2310b Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 19 Dec 2006 11:49:38 +0100 Subject: [PATCH 138/590] Added tag 1.8 for changeset d3e6fa22ae45b38b1bdb0d813390365e5930360b --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 4c657a4..72eecf6 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -16,3 +16,4 @@ e071fb045bd9e8574947acff7196360bc0270e68 1.5 dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 3696d77aaf02f5d15728dde3b9e35abcaf291496 1.7.1 +d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 From 8b1697c4806541ff6143efe4aba124cf42f7b83a Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 2 Jan 2007 15:38:44 +0100 Subject: [PATCH 139/590] next version will contain updated copyright notice --- dmenubar/LICENSE | 4 ++-- dmenubar/Makefile | 2 +- dmenubar/config.mk | 2 +- dmenubar/dmenu.h | 2 +- dmenubar/draw.c | 2 +- dmenubar/main.c | 6 +++--- dmenubar/util.c | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 67e22c3..d3a309d 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License -(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> -(C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> +(C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> +(C)opyright MMVII Sander van Dijk <a dot h dot vandijk at gmail dot com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/Makefile b/dmenubar/Makefile index d208dbb..fec5da4 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -1,5 +1,5 @@ # dmenu - dynamic menu -# (C)opyright MMVI Anselm R. Garbe +# (C)opyright MMVII Anselm R. Garbe include config.mk diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 1670243..7b2808d 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.8 +VERSION = 1.9 # Customize below to fit your system diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index ff9790d..0afdf0e 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -1,4 +1,4 @@ -/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 710af8e..92f07ca 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -1,4 +1,4 @@ -/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMIV-MMVII Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ #include "dmenu.h" diff --git a/dmenubar/main.c b/dmenubar/main.c index 69214dd..71ad867 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -1,5 +1,5 @@ -/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * (C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> +/* (C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> + * (C)opyright MMVII Sander van Dijk <a dot h dot vandijk at gmail dot com> * See LICENSE file for license details. */ #include "dmenu.h" @@ -373,7 +373,7 @@ main(int argc, char *argv[]) { if(++i < argc) timeout.tv_sec = atoi(argv[i]); } else if(!strncmp(argv[i], "-v", 3)) { - fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); + fputs("dmenu-"VERSION", (C)opyright MMVII Anselm R. Garbe\n", stdout); exit(EXIT_SUCCESS); } else diff --git a/dmenubar/util.c b/dmenubar/util.c index 0427ed5..62b816b 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -1,4 +1,4 @@ -/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ #include "dmenu.h" From ade64e08c667a9c69eb90aef0d31c8e2077162a2 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 2 Jan 2007 15:41:13 +0100 Subject: [PATCH 140/590] corrected --- dmenubar/dmenu.h | 2 +- dmenubar/main.c | 4 ++-- dmenubar/util.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 0afdf0e..9e184fd 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -1,4 +1,4 @@ -/* (C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ diff --git a/dmenubar/main.c b/dmenubar/main.c index 71ad867..cb52c9c 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -1,5 +1,5 @@ -/* (C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> - * (C)opyright MMVII Sander van Dijk <a dot h dot vandijk 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" diff --git a/dmenubar/util.c b/dmenubar/util.c index 62b816b..01b38bb 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -1,4 +1,4 @@ -/* (C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> +/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ #include "dmenu.h" From c8865e6a8849e7717b2678b548072e8792436212 Mon Sep 17 00:00:00 2001 From: "arg@mig29" <unknown> Date: Tue, 2 Jan 2007 15:44:32 +0100 Subject: [PATCH 141/590] corrections --- dmenubar/LICENSE | 4 ++-- dmenubar/main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index d3a309d..2d25a17 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License -(C)opyright MMVII Anselm R. Garbe <garbeam at gmail dot com> -(C)opyright MMVII Sander van Dijk <a dot h dot vandijk 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> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/main.c b/dmenubar/main.c index cb52c9c..573d7c3 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -373,7 +373,7 @@ main(int argc, char *argv[]) { if(++i < argc) timeout.tv_sec = atoi(argv[i]); } else if(!strncmp(argv[i], "-v", 3)) { - fputs("dmenu-"VERSION", (C)opyright MMVII Anselm R. Garbe\n", stdout); + fputs("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout); exit(EXIT_SUCCESS); } else From a839d28b055611baabfe0c11e00361ca8201a8ad Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 10 Jan 2007 18:06:16 +0100 Subject: [PATCH 142/590] applied Alexis Hildebrandts patches --- dmenubar/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 573d7c3..115fbde 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -164,6 +164,8 @@ kpress(XKeyEvent * e) { switch (ksym) { default: /* ignore other control sequences */ return; + case XK_bracketleft: + ksym = XK_Escape; break; case XK_h: case XK_H: @@ -175,7 +177,6 @@ kpress(XKeyEvent * e) { match(text); drawmenu(); return; - break; } } if(e->state & Mod1Mask) { From 0394c5e258bb627c8d29655327094dad02bb9f21 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 10 Jan 2007 23:07:03 +0100 Subject: [PATCH 143/590] applied Sanders dmenu_ctrlchars.patch (thanks!) --- dmenubar/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dmenubar/main.c b/dmenubar/main.c index 115fbde..46e0b44 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -171,6 +171,14 @@ kpress(XKeyEvent * e) { case XK_H: ksym = XK_BackSpace; break; + case XK_i: + case XK_I: + ksym = XK_Tab; + break; + case XK_j: + case XK_J: + ksym = XK_Return; + break; case XK_u: case XK_U: text[0] = 0; From 37d379535a8aa5caf7adb416108fe11a395bb950 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 11 Jan 2007 10:17:01 +0100 Subject: [PATCH 144/590] commented recent Control-shortcut additions --- dmenubar/dmenu.1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index f0bf50c..2d61845 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -66,7 +66,7 @@ Select the first item of the previous/next 'page' of items. .B Home/End Select the first/last item. .TP -.B Tab +.B Tab (Control-i) Copy the selected item to the input field. .TP .B Return @@ -74,13 +74,13 @@ Confirm selection and quit (print the selected item to standard output). Returns .B 0 on termination. .TP -.B Shift-Return +.B Shift-Return (Control-j) Confirm selection and quit (print the text in the input field to standard output). Returns .B 0 on termination. .TP -.B Escape +.B Escape (Control-bracketleft) Quit without selecting an item. Returns .B 1 on termination. From 9d2e13d2d38bbe4d8d9ffc4e501743f311fa7b69 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 11 Jan 2007 11:41:16 +0100 Subject: [PATCH 145/590] documenting undocumented vi-alike shortcuts of dmenu --- dmenubar/dmenu.1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 2d61845..4bc5b03 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -57,13 +57,13 @@ 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: only items containing this text will be displayed. .TP -.B Left/Right +.B Left/Right (Mod1-h/Mod1-l) Select the previous/next item. .TP -.B PageUp/PageDown +.B PageUp/PageDown (Mod1-k/Mod1-j) Select the first item of the previous/next 'page' of items. .TP -.B Home/End +.B Home/End (Mod1-g/Mod1-Shift-g) Select the first/last item. .TP .B Tab (Control-i) From 6ceff97643104bf6f54fc20ea522ecae5b3ccc20 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 11 Jan 2007 13:51:15 +0100 Subject: [PATCH 146/590] s/Mod1-Shift-g/Mod1-G/ in fact Sander is right --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 4bc5b03..2d2d670 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -63,7 +63,7 @@ Select the previous/next item. .B PageUp/PageDown (Mod1-k/Mod1-j) Select the first item of the previous/next 'page' of items. .TP -.B Home/End (Mod1-g/Mod1-Shift-g) +.B Home/End (Mod1-g/Mod1-G) Select the first/last item. .TP .B Tab (Control-i) From 46cce31caad2a45156ccf8f5eb8ab38abc387afb Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 11 Jan 2007 15:52:37 +0100 Subject: [PATCH 147/590] added evil key support to dmenu --- dmenubar/main.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 46e0b44..59b3a72 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -15,6 +15,8 @@ #include <X11/Xutil.h> #include <X11/keysym.h> +#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) + typedef struct Item Item; struct Item { Item *next; /* traverses all items */ @@ -31,6 +33,7 @@ static int ret = 0; static int nitem = 0; static unsigned int cmdw = 0; static unsigned int promptw = 0; +static unsigned int numlockmask = 0; static Bool running = True; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ @@ -187,7 +190,7 @@ kpress(XKeyEvent * e) { return; } } - if(e->state & Mod1Mask) { + if(CLEANMASK(e->state) & Mod1Mask) { switch(ksym) { default: return; case XK_h: @@ -347,10 +350,11 @@ main(int argc, char *argv[]) { char *selbg = SELBGCOLOR; char *selfg = SELFGCOLOR; fd_set rd; - int i; + int i, j; struct timeval timeout; Item *itm; XEvent ev; + XModifierKeymap *modmap; XSetWindowAttributes wa; timeout.tv_usec = 0; @@ -408,6 +412,15 @@ main(int argc, char *argv[]) { 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)) + numlockmask = (1 << i); + } + } + XFreeModifiermap(modmap); /* style */ dc.norm[ColBG] = getcolor(normbg); dc.norm[ColFG] = getcolor(normfg); From a0588b64b674c939344f69e1578fa23db4de0650 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 12 Jan 2007 12:43:44 +0100 Subject: [PATCH 148/590] Added tag 1.9 for changeset c7f5f4d54317 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 72eecf6..a470330 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -17,3 +17,4 @@ dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 3696d77aaf02f5d15728dde3b9e35abcaf291496 1.7.1 d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 +c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 From 55a9d6efd6e253959063c768b88cc04b5269759d Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 16 Jan 2007 11:07:30 +0100 Subject: [PATCH 149/590] small fix of Control-j in dmenu.1 --- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 7b2808d..771082a 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 1.9 +VERSION = 2.0 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 2d2d670..c682711 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -69,12 +69,12 @@ Select the first/last item. .B Tab (Control-i) Copy the selected item to the input field. .TP -.B Return +.B Return (Control-j) Confirm selection and quit (print the selected item to standard output). Returns .B 0 on termination. .TP -.B Shift-Return (Control-j) +.B Shift-Return (Control-Shift-j) Confirm selection and quit (print the text in the input field to standard output). Returns .B 0 From a76b884624c8431c317f0a27a95569ba93c6f162 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 16 Jan 2007 11:24:51 +0100 Subject: [PATCH 150/590] applied new default colors --- dmenubar/dmenu.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 9e184fd..b6c6aba 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -5,10 +5,10 @@ #include <X11/Xlib.h> #define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*" -#define NORMBGCOLOR "#333366" -#define NORMFGCOLOR "#cccccc" -#define SELBGCOLOR "#666699" -#define SELFGCOLOR "#eeeeee" +#define NORMBGCOLOR "#eeeeee" +#define NORMFGCOLOR "#222222" +#define SELBGCOLOR "#006699" +#define SELFGCOLOR "#ffffff" #define SPACE 30 /* px */ /* color */ From 4e4a1a82e5d4bf4f4fb7388b9a19bc3c56e79507 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 16 Jan 2007 11:38:31 +0100 Subject: [PATCH 151/590] removed useless mx, my --- dmenubar/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 59b3a72..b5c29c3 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -28,7 +28,7 @@ struct Item { static char text[4096]; static char *prompt = NULL; -static int mx, my, mw, mh; +static int mw, mh; static int ret = 0; static int nitem = 0; static unsigned int cmdw = 0; @@ -431,12 +431,11 @@ main(int argc, char *argv[]) { wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; - mx = my = 0; mw = DisplayWidth(dpy, screen); mh = dc.font.height + 2; if(bottom) my += DisplayHeight(dpy, screen) - mh; - win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, + win = XCreateWindow(dpy, root, 0, 0, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); From 6d36e3fb3a5fa59681e7c9e97731e68793b9efce Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 16 Jan 2007 11:39:26 +0100 Subject: [PATCH 152/590] small fix --- dmenubar/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index b5c29c3..4dff207 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -350,7 +350,7 @@ main(int argc, char *argv[]) { char *selbg = SELBGCOLOR; char *selfg = SELFGCOLOR; fd_set rd; - int i, j; + int i, j, my; struct timeval timeout; Item *itm; XEvent ev; @@ -431,6 +431,7 @@ main(int argc, char *argv[]) { 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) From b9e70ae616f0908402e2a286eeab964be1bd3c88 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 16 Jan 2007 11:42:09 +0100 Subject: [PATCH 153/590] Added tag 2.0 for changeset 1fce5c464fcd --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index a470330..cade777 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -18,3 +18,4 @@ dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 3696d77aaf02f5d15728dde3b9e35abcaf291496 1.7.1 d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 +1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0 From 3e21743a6c98362f367e40284cde51f722848b33 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 17 Jan 2007 11:10:09 +0100 Subject: [PATCH 154/590] Added tag 2.1 for changeset d91c79020430 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index cade777..98ac4a1 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -19,3 +19,4 @@ dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0 +d91c79020430b9707f7c572563021a62468a34b3 2.1 From bf6ee88eef686155082024fb56e018bdb1fc2a4a Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 17 Jan 2007 11:10:26 +0100 Subject: [PATCH 155/590] hotfix changes --- dmenubar/.hgtags | 1 - dmenubar/config.mk | 2 +- dmenubar/main.c | 8 +++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 98ac4a1..cade777 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -19,4 +19,3 @@ dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0 -d91c79020430b9707f7c572563021a62468a34b3 2.1 diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 771082a..7860a39 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.0 +VERSION = 2.1 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index 4dff207..f1f71fd 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -350,7 +350,7 @@ main(int argc, char *argv[]) { char *selbg = SELBGCOLOR; char *selfg = SELFGCOLOR; fd_set rd; - int i, j, my; + int i, j; struct timeval timeout; Item *itm; XEvent ev; @@ -431,12 +431,10 @@ main(int argc, char *argv[]) { 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); From 226d8e56b1c7ef480e3e5cf1f6f3c2d9b19352ac Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 17 Jan 2007 11:10:31 +0100 Subject: [PATCH 156/590] Added tag 2.1 for changeset 7656557298c9 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index cade777..e204fe7 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -19,3 +19,4 @@ dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0 +7656557298c954469a6a9564e6649b1fb5db663e 2.1 From a852cb33c1ba17b092453536230f98e9cb2f5e79 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 5 Feb 2007 11:10:41 +0100 Subject: [PATCH 157/590] got rid of LD, inspired by JGs patch to wmii --- dmenubar/Makefile | 5 ++--- dmenubar/config.mk | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index fec5da4..d86c111 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -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: diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 7860a39..cc328ea 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.1 +VERSION = 2.2 # Customize below to fit your system @@ -27,4 +27,3 @@ LDFLAGS = ${LIBS} # compiler and linker CC = cc -LD = ${CC} From 24ad9306c7893a2d2e4968c595838b1ee1bb66f1 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 8 Feb 2007 11:10:29 +0100 Subject: [PATCH 158/590] letting dmenu appear at the bottom by default --- dmenubar/dmenu.1 | 4 ---- dmenubar/main.c | 10 +++------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index c682711..88dd9ef 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,7 +3,6 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-b ] .RB [ \-fn " <font>"] .RB [ \-nb " <color>"] .RB [ \-nf " <color>"] @@ -20,9 +19,6 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP -.B \-b -makes dmenu appear at the screen bottom (by default it appears at the screen top). -.TP .B \-fn <font> defines the font. .TP diff --git a/dmenubar/main.c b/dmenubar/main.c index f1f71fd..224d298 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -342,7 +342,6 @@ DC dc = {0}; int main(int argc, char *argv[]) { - Bool bottom = False; char *font = FONT; char *maxname; char *normbg = NORMBGCOLOR; @@ -361,10 +360,7 @@ main(int argc, char *argv[]) { timeout.tv_sec = 3; /* command line args */ for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-b", 3)) { - bottom = True; - } - else if(!strncmp(argv[i], "-fn", 4)) { + if(!strncmp(argv[i], "-fn", 4)) { if(++i < argc) font = argv[i]; } else if(!strncmp(argv[i], "-nb", 4)) { @@ -390,7 +386,7 @@ main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } else - eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n" + eprint("usage: dmenu [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n" " [-sb <color>] [-sf <color>] [-t <seconds>] [-v]\n", stdout); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); @@ -434,7 +430,7 @@ main(int argc, char *argv[]) { mw = DisplayWidth(dpy, screen); mh = dc.font.height + 2; win = XCreateWindow(dpy, root, 0, - bottom ? DisplayHeight(dpy, screen) - mh : 0, mw, mh, 0, + DisplayHeight(dpy, screen) - mh, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); From de82e827bf02641ba7f98c611cd8d8632a8aff63 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 8 Feb 2007 11:17:11 +0100 Subject: [PATCH 159/590] nah nah nah, I can't get used to the bottom bar, pushing the conditional dmenu again --- dmenubar/dmenu.1 | 4 ++++ dmenubar/main.c | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 88dd9ef..c682711 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,6 +3,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu +.RB [ \-b ] .RB [ \-fn " <font>"] .RB [ \-nb " <color>"] .RB [ \-nf " <color>"] @@ -19,6 +20,9 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP +.B \-b +makes dmenu appear at the screen bottom (by default it appears at the screen top). +.TP .B \-fn <font> defines the font. .TP diff --git a/dmenubar/main.c b/dmenubar/main.c index 224d298..f1f71fd 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -342,6 +342,7 @@ DC dc = {0}; int main(int argc, char *argv[]) { + Bool bottom = False; char *font = FONT; char *maxname; char *normbg = NORMBGCOLOR; @@ -360,7 +361,10 @@ main(int argc, char *argv[]) { timeout.tv_sec = 3; /* command line args */ for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-fn", 4)) { + if(!strncmp(argv[i], "-b", 3)) { + bottom = True; + } + else if(!strncmp(argv[i], "-fn", 4)) { if(++i < argc) font = argv[i]; } else if(!strncmp(argv[i], "-nb", 4)) { @@ -386,7 +390,7 @@ main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } else - eprint("usage: dmenu [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n" + eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>] [-p <prompt>]\n" " [-sb <color>] [-sf <color>] [-t <seconds>] [-v]\n", stdout); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); @@ -430,7 +434,7 @@ main(int argc, char *argv[]) { mw = DisplayWidth(dpy, screen); mh = dc.font.height + 2; win = XCreateWindow(dpy, root, 0, - DisplayHeight(dpy, screen) - mh, mw, mh, 0, + bottom ? DisplayHeight(dpy, screen) - mh : 0, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); From 9bacebf33b8d2da36d19c56f1374e9bcdd2d8601 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 8 Feb 2007 14:10:17 +0100 Subject: [PATCH 160/590] fixed Copyright notice in Makefile --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index d86c111..18279f6 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -1,5 +1,5 @@ # dmenu - dynamic menu -# (C)opyright MMVII Anselm R. Garbe +# (C)opyright MMVI-MMVII Anselm R. Garbe include config.mk From cffb2ca9124a41ebcdbbdc56287d540ef0a718b5 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 14 Feb 2007 09:42:02 +0100 Subject: [PATCH 161/590] Added tag 2.2 for changeset 90f0e34e7f11 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index e204fe7..691508a 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -20,3 +20,4 @@ d3e6fa22ae45b38b1bdb0d813390365e5930360b 1.8 c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0 7656557298c954469a6a9564e6649b1fb5db663e 2.1 +90f0e34e7f118c9ad3227a1606211ee825942b1c 2.2 From e63ff024199aab6293fc5334558a66f7a92fea33 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 19 Feb 2007 15:49:50 +0100 Subject: [PATCH 162/590] removed draw.c, implemented C-w handling (backward word deletion) --- dmenubar/Makefile | 2 +- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 3 ++ dmenubar/dmenu.h | 7 --- dmenubar/draw.c | 121 ------------------------------------------ dmenubar/main.c | 127 ++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 130 insertions(+), 132 deletions(-) delete mode 100644 dmenubar/draw.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 18279f6..66040d9 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = draw.c main.c util.c +SRC = main.c util.c OBJ = ${SRC:.c=.o} all: options dmenu diff --git a/dmenubar/config.mk b/dmenubar/config.mk index cc328ea..195fd4c 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.2 +VERSION = 2.3 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index c682711..2afa17c 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -90,6 +90,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) . diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index b6c6aba..5c047ff 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -38,13 +38,6 @@ 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 */ - /* util.c */ extern void *emalloc(unsigned int size); /* allocates memory, exits on error */ extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c deleted file mode 100644 index 92f07ca..0000000 --- a/dmenubar/draw.c +++ /dev/null @@ -1,121 +0,0 @@ -/* (C)opyright MMIV-MMVII Anselm R. Garbe <garbeam 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 -drawtext(const char *text, unsigned long col[ColLast]) { - int x, y, w, h; - static char buf[256]; - unsigned int len, olen; - XGCValues gcv; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - - XSetForeground(dpy, dc.gc, col[ColBG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; - h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ - gcv.foreground = col[ColFG]; - if(dc.font.set) { - XChangeGC(dpy, dc.gc, GCForeground, &gcv); - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, - 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); - } -} - -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; -} diff --git a/dmenubar/main.c b/dmenubar/main.c index f1f71fd..0840643 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -44,6 +44,22 @@ static Item *curr = NULL; static Window root; static Window win; +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); +} + +static unsigned int +textw(const char *text) { + return textnw(text, strlen(text)) + dc.font.height; +} + static void calcoffsets(void) { unsigned int tw, w; @@ -70,6 +86,53 @@ calcoffsets(void) { } } +static void +drawtext(const char *text, unsigned long col[ColLast]) { + int x, y, w, h; + static char buf[256]; + unsigned int len, olen; + XGCValues gcv; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, col[ColBG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + w = 0; + olen = len = strlen(text); + if(len >= sizeof buf) + len = sizeof buf - 1; + memcpy(buf, text, len); + buf[len] = 0; + h = dc.font.ascent + dc.font.descent; + y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; + x = dc.x + (h / 2); + /* shorten text if necessary */ + while(len && (w = textnw(buf, len)) > dc.w - h) + buf[--len] = 0; + if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; + if(len > 3) + buf[len - 3] = '.'; + } + if(w > dc.w) + return; /* too long */ + gcv.foreground = col[ColFG]; + if(dc.font.set) { + XChangeGC(dpy, dc.gc, GCForeground, &gcv); + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, + 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); + } +} + static void drawmenu(void) { Item *i; @@ -111,6 +174,54 @@ drawmenu(void) { XFlush(dpy); } +static 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; +} + +static 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; +} + static void match(char *pattern) { unsigned int plen; @@ -151,8 +262,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 +299,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) { From 833885d2a6e8015bd41ecc514978ab71dc7c19e2 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 19 Feb 2007 21:18:36 +0100 Subject: [PATCH 163/590] removed -t, now using isatty() instead of select() to prevent execution from an interactive shell --- dmenubar/dmenu.1 | 4 ---- dmenubar/main.c | 42 +++++++++++++++--------------------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 2afa17c..477219a 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -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 diff --git a/dmenubar/main.c b/dmenubar/main.c index 0840643..54a3a12 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -10,8 +10,6 @@ #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> @@ -457,6 +455,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; @@ -472,16 +476,16 @@ main(int argc, char *argv[]) { char *normfg = NORMFGCOLOR; char *selbg = SELBGCOLOR; char *selfg = SELFGCOLOR; - fd_set rd; int i, j; - struct timeval timeout; 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)) { @@ -505,41 +509,26 @@ 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); } } @@ -607,7 +596,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; From 4e5645b281ce374f3ea3d5ef3d72b7c06a14bc67 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 20 Feb 2007 13:54:00 +0100 Subject: [PATCH 164/590] readded draw.c again (except getcolor and setfont) --- dmenubar/Makefile | 2 +- dmenubar/dmenu.h | 5 ++++ dmenubar/draw.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ dmenubar/main.c | 64 ------------------------------------------ dmenubar/util.c | 2 -- 5 files changed, 77 insertions(+), 67 deletions(-) create mode 100644 dmenubar/draw.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 66040d9..18279f6 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = main.c util.c +SRC = draw.c main.c util.c OBJ = ${SRC:.c=.o} all: options dmenu diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 5c047ff..bb3b144 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -38,6 +38,11 @@ extern int screen; extern Display *dpy; extern DC dc; /* global drawing context */ +/* draw.c */ +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 */ extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c new file mode 100644 index 0000000..145df16 --- /dev/null +++ b/dmenubar/draw.c @@ -0,0 +1,71 @@ +/* (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 <string.h> + +/* extern */ + +void +drawtext(const char *text, unsigned long col[ColLast]) { + int x, y, w, h; + static char buf[256]; + unsigned int len, olen; + XGCValues gcv; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, col[ColBG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + w = 0; + olen = len = strlen(text); + if(len >= sizeof buf) + len = sizeof buf - 1; + memcpy(buf, text, len); + buf[len] = 0; + h = dc.font.ascent + dc.font.descent; + y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; + x = dc.x + (h / 2); + /* shorten text if necessary */ + while(len && (w = textnw(buf, len)) > dc.w - h) + buf[--len] = 0; + if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; + if(len > 3) + buf[len - 3] = '.'; + } + if(w > dc.w) + return; /* too long */ + gcv.foreground = col[ColFG]; + if(dc.font.set) { + XChangeGC(dpy, dc.gc, GCForeground, &gcv); + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, + 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); + } +} + +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); +} diff --git a/dmenubar/main.c b/dmenubar/main.c index 54a3a12..8b24bb0 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -3,7 +3,6 @@ * See LICENSE file for license details. */ #include "dmenu.h" - #include <ctype.h> #include <locale.h> #include <stdlib.h> @@ -42,22 +41,6 @@ static Item *curr = NULL; static Window root; static Window win; -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); -} - -static unsigned int -textw(const char *text) { - return textnw(text, strlen(text)) + dc.font.height; -} - static void calcoffsets(void) { unsigned int tw, w; @@ -84,53 +67,6 @@ calcoffsets(void) { } } -static void -drawtext(const char *text, unsigned long col[ColLast]) { - int x, y, w, h; - static char buf[256]; - unsigned int len, olen; - XGCValues gcv; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - - XSetForeground(dpy, dc.gc, col[ColBG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; - h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ - gcv.foreground = col[ColFG]; - if(dc.font.set) { - XChangeGC(dpy, dc.gc, GCForeground, &gcv); - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, - 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); - } -} - static void drawmenu(void) { Item *i; diff --git a/dmenubar/util.c b/dmenubar/util.c index 01b38bb..124bcd5 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -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) { From d682af2ab3443e011daee3beec0476dd974a1af3 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 20 Feb 2007 13:54:37 +0100 Subject: [PATCH 165/590] s/setfont/initfont/ --- dmenubar/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 8b24bb0..3ac1c91 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -119,7 +119,7 @@ getcolor(const char *colstr) { } static void -setfont(const char *fontstr) { +initfont(const char *fontstr) { char *def, **missing; int i, n; @@ -474,7 +474,7 @@ main(int argc, char *argv[]) { dc.norm[ColFG] = getcolor(normfg); dc.sel[ColBG] = getcolor(selbg); dc.sel[ColFG] = getcolor(selfg); - setfont(font); + initfont(font); /* menu window */ wa.override_redirect = 1; wa.background_pixmap = ParentRelative; From 4ac0d96230b4a3425105a4a06fd60af454db4778 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 20 Feb 2007 13:57:05 +0100 Subject: [PATCH 166/590] renamed getcolor to initcolor --- dmenubar/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 3ac1c91..c1d48dd 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -109,7 +109,7 @@ drawmenu(void) { } static unsigned long -getcolor(const char *colstr) { +initcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -470,10 +470,10 @@ main(int argc, char *argv[]) { } XFreeModifiermap(modmap); /* style */ - dc.norm[ColBG] = getcolor(normbg); - dc.norm[ColFG] = getcolor(normfg); - dc.sel[ColBG] = getcolor(selbg); - dc.sel[ColFG] = getcolor(selfg); + 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; From 05811e8be030c87852f22176f547f98d9c751b30 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 21 Feb 2007 10:59:36 +0100 Subject: [PATCH 167/590] applied the fix inspired by a recent wmii commit --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 18279f6..3910080 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -44,7 +44,7 @@ install: all @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @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: From db58d530ed8e560e40dab2ae23612302f14155c9 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 21 Feb 2007 11:05:19 +0100 Subject: [PATCH 168/590] Added tag 2.3 for changeset b6e09682c8adcb6569656bee73c311f9ab457715 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 691508a..0b46cf7 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -21,3 +21,4 @@ c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 1fce5c464fcd870b9f024aa1853d5cf3a3eb371b 2.0 7656557298c954469a6a9564e6649b1fb5db663e 2.1 90f0e34e7f118c9ad3227a1606211ee825942b1c 2.2 +b6e09682c8adcb6569656bee73c311f9ab457715 2.3 From db151423f8e36019fb1042b11f01af857bb21805 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 22 Feb 2007 18:16:35 +0100 Subject: [PATCH 169/590] made Fnt an anonymous struct --- dmenubar/config.mk | 2 +- dmenubar/dmenu.h | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 195fd4c..525ef17 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.3 +VERSION = 2.4 # Customize below to fit your system diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index bb3b144..2174688 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -14,25 +14,20 @@ /* color */ enum { ColFG, ColBG, ColLast }; -typedef struct DC DC; -typedef struct Fnt Fnt; - -struct Fnt { - XFontStruct *xfont; - XFontSet set; - int ascent; - int descent; - int height; -}; - -struct DC { +typedef struct { int x, y, w, h; unsigned long norm[ColLast]; unsigned long sel[ColLast]; Drawable drawable; - Fnt font; GC gc; -}; /* draw context */ + struct { + XFontStruct *xfont; + XFontSet set; + int ascent; + int descent; + int height; + } font; +} DC; /* draw context */ extern int screen; extern Display *dpy; From af2ed87fd844cd13427d63e259161601a5927eb4 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 10:16:43 +0100 Subject: [PATCH 170/590] added dmenu_path convenience script --- dmenubar/Makefile | 7 ++++--- dmenubar/dmenu_path | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100755 dmenubar/dmenu_path diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 3910080..3869f4d 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -32,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} @@ -40,8 +40,9 @@ 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 @@ -49,7 +50,7 @@ install: all 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 diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path new file mode 100755 index 0000000..3070eb7 --- /dev/null +++ b/dmenubar/dmenu_path @@ -0,0 +1,2 @@ +#!/bin/sh +/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | /usr/bin/sort -u From dc46ba06332a66c385db90f9798c0cbf7f8e598d Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 10:42:00 +0100 Subject: [PATCH 171/590] Added tag 2.4 for changeset 9e9036cbfb4b --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 0b46cf7..de1fdb8 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -22,3 +22,4 @@ c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 7656557298c954469a6a9564e6649b1fb5db663e 2.1 90f0e34e7f118c9ad3227a1606211ee825942b1c 2.2 b6e09682c8adcb6569656bee73c311f9ab457715 2.3 +9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4 From 158acd3d686f5bb708fe96445d2960181440e6e1 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 13:28:38 +0100 Subject: [PATCH 172/590] hotfix --- dmenubar/config.mk | 2 +- dmenubar/dmenu_path | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 525ef17..1eaf66e 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.4 +VERSION = 2.4.1 # Customize below to fit your system diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 3070eb7..72ff3ed 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,2 +1,2 @@ #!/bin/sh -/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | /usr/bin/sort -u +/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | sort | uniq From fc00f4a3c5a9ce8beffdc89a61f5169532c6c2dd Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 13:28:43 +0100 Subject: [PATCH 173/590] Added tag 2.4.1 for changeset 03e83e2788c8 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index de1fdb8..35a537d 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -23,3 +23,4 @@ c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 90f0e34e7f118c9ad3227a1606211ee825942b1c 2.2 b6e09682c8adcb6569656bee73c311f9ab457715 2.3 9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4 +03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1 From c01719056435bfabb5496643034908070fc0a62b Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 13:51:06 +0100 Subject: [PATCH 174/590] ok 2.4.2 --- dmenubar/config.mk | 2 +- dmenubar/dmenu_path | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 1eaf66e..a0ef56a 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.4.1 +VERSION = 2.4.2 # Customize below to fit your system diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 72ff3ed..4008f4c 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,2 +1,2 @@ #!/bin/sh -/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | sort | uniq +/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | sort -u From 92f6ceb82d003b1f975d88a331cb39b00a919833 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 13:51:23 +0100 Subject: [PATCH 175/590] Added tag 2.4.2 for changeset 1ca5d430524e --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 35a537d..b4e087a 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -24,3 +24,4 @@ c7f5f4d543170f03d70468e98a3a0ec8d2c4161b 1.9 b6e09682c8adcb6569656bee73c311f9ab457715 2.3 9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4 03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1 +1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2 From 54bc217bd921560321f4b805bdbc18b72fb811f9 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 14:39:54 +0100 Subject: [PATCH 176/590] fixed a bug when dmenu is run with -v --- dmenubar/config.mk | 2 +- dmenubar/main.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index a0ef56a..7ae7dde 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.4.2 +VERSION = 2.5 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index c1d48dd..cd0e2b5 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -418,7 +418,9 @@ main(int argc, char *argv[]) { XModifierKeymap *modmap; XSetWindowAttributes wa; - if(isatty(STDIN_FILENO)) { + 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(); } @@ -445,8 +447,6 @@ main(int argc, char *argv[]) { else if(!strncmp(argv[i], "-sf", 4)) { 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 usage(); setlocale(LC_CTYPE, ""); From f50ed00128f0b93548c834ab9f0f8283ddc2b4f0 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 23 Feb 2007 15:28:25 +0100 Subject: [PATCH 177/590] using the old-style fashion we uses earlier --- dmenubar/dmenu_path | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 4008f4c..4ecf4fa 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,2 +1,9 @@ #!/bin/sh -/bin/ls -lL `echo $PATH | tr : ' '` 2> /dev/null | awk '$1 ~ /^[^d].*x/ { print $NF }' | sort -u +IFS=: +for dir in $PATH +do + for file in "$dir"/* + do + test -x "$file" && echo "${file##*/}" + done +done | sort -u From 2834e686901cef275a65751a518f1cd191096c1a Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Sat, 24 Feb 2007 14:07:40 +0100 Subject: [PATCH 178/590] removed superfluous externs as well --- dmenubar/dmenu.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 2174688..84e19e6 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -29,16 +29,16 @@ typedef struct { } font; } DC; /* draw context */ -extern int screen; -extern Display *dpy; -extern DC dc; /* global drawing context */ +int screen; +Display *dpy; +DC dc; /* global drawing context */ /* draw.c */ -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); +void drawtext(const char *text, unsigned long col[ColLast]); +unsigned int textw(const char *text); +unsigned int textnw(const char *text, unsigned int len); /* util.c */ -extern void *emalloc(unsigned int size); /* allocates memory, exits on error */ -extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ -extern char *estrdup(const char *str); /* duplicates str, exits on allocation error */ +void *emalloc(unsigned int size); /* allocates memory, exits on error */ +void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ +char *estrdup(const char *str); /* duplicates str, exits on allocation error */ From 1509f6827a70e193a4b6863031886c2c214e6736 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Sat, 24 Feb 2007 15:38:10 +0100 Subject: [PATCH 179/590] I also dislike sort -u, I support that each Unix tool does one job and does it right ;) --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 4ecf4fa..f64c82e 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -6,4 +6,4 @@ do do test -x "$file" && echo "${file##*/}" done -done | sort -u +done | sort | uniq From f79b5faa65e9d73e185d3b805384b1a9667f2a63 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Sat, 24 Feb 2007 15:38:26 +0100 Subject: [PATCH 180/590] Added tag 2.5 for changeset 041143e9fc54 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index b4e087a..b8053c0 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -25,3 +25,4 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3 9e9036cbfb4b7306c6fb366249e81dc0e65bdfde 2.4 03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1 1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2 +041143e9fc544c62edc58af52cae9ac5237e5945 2.5 From 3a73e96db8f75d8143c539bd0a605604ab71ec04 Mon Sep 17 00:00:00 2001 From: Kris Maglione <jg@suckless.org> Date: Sun, 25 Feb 2007 16:41:05 -0500 Subject: [PATCH 181/590] Escape -s in dmenu.1 --- dmenubar/dmenu.1 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 477219a..4e44e27 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -1,4 +1,4 @@ -.TH DMENU 1 dmenu-VERSION +.TH DMENU 1 dmenu\-VERSION .SH NAME dmenu \- dynamic menu .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: only items containing this text will be displayed. .TP -.B Left/Right (Mod1-h/Mod1-l) +.B Left/Right (Mod1\-h/Mod1\-l) Select the previous/next item. .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. .TP -.B Home/End (Mod1-g/Mod1-G) +.B Home/End (Mod1\-g/Mod1\-G) Select the first/last item. .TP -.B Tab (Control-i) +.B Tab (Control\-i) Copy the selected item to the input field. .TP -.B Return (Control-j) +.B Return (Control\-j) Confirm selection and quit (print the selected item to standard output). Returns .B 0 on termination. .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). Returns .B 0 on termination. .TP -.B Escape (Control-bracketleft) +.B Escape (Control\-bracketleft) Quit without selecting an item. Returns .B 1 on termination. .TP -.B Backspace (Control-h) +.B Backspace (Control\-h) Remove enough characters from the input field to change its filtering effect. .TP -.B Control-u +.B Control\-u Remove all characters from the input field. .TP -.B Control-w +.B Control\-w Remove all characters of current word from the input field. .SH SEE ALSO .BR dwm (1), From 40b8f059225845fda30b8ae6ea1fbd5094ae083b Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 26 Feb 2007 10:47:52 +0100 Subject: [PATCH 182/590] next is 2.6, but not yet ;) --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 7ae7dde..b261284 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.5 +VERSION = 2.6 # Customize below to fit your system From 29ca954fad4736cc67a70652cadf5dde5a25e55e Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 26 Feb 2007 11:44:41 +0100 Subject: [PATCH 183/590] if isatty() first read from stdin and then grab the keyboard, otherwise first grab the keyboard and then read from stdin --- dmenubar/main.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index cd0e2b5..210792a 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -108,6 +108,13 @@ drawmenu(void) { XFlush(dpy); } +static void +grabkeyboard(void) { + while(XGrabKeyboard(dpy, root, True, GrabModeAsync, + GrabModeAsync, CurrentTime) != GrabSuccess) + usleep(1000); +} + static unsigned long initcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); @@ -418,12 +425,6 @@ main(int argc, char *argv[]) { XModifierKeymap *modmap; 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 */ for(i = 1; i < argc; i++) if(!strncmp(argv[i], "-b", 3)) { @@ -447,6 +448,8 @@ main(int argc, char *argv[]) { else if(!strncmp(argv[i], "-sf", 4)) { 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 usage(); setlocale(LC_CTYPE, ""); @@ -455,10 +458,14 @@ main(int argc, char *argv[]) { eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - while(XGrabKeyboard(dpy, root, True, GrabModeAsync, - GrabModeAsync, CurrentTime) != GrabSuccess) - usleep(1000); - maxname = readstdin(); + 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++) { From 60c704612633483fae11a014d613d9e400fa358d Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 26 Feb 2007 14:07:19 +0100 Subject: [PATCH 184/590] changed Backspace/C-w behavior (now it only removes a single character) --- dmenubar/dmenu.1 | 2 +- dmenubar/main.c | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 4e44e27..56c3bdd 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -82,7 +82,7 @@ Quit without selecting an item. Returns on termination. .TP .B Backspace (Control\-h) -Remove enough characters from the input field to change its filtering effect. +Remove a character from the input field. .TP .B Control\-u Remove all characters from the input field. diff --git a/dmenubar/main.c b/dmenubar/main.c index 210792a..b733feb 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -289,12 +289,8 @@ kpress(XKeyEvent * e) { } break; case XK_BackSpace: - if((i = len)) { - prev_nitem = nitem; - do { - text[--i] = 0; - match(text); - } while(i && nitem && prev_nitem == nitem); + if(len) { + text[--len] = 0; match(text); } break; From 31bf2d9a6dfa4988a695fae1fdfd49580218c92d Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 27 Feb 2007 14:44:21 +0100 Subject: [PATCH 185/590] useless var declaration prev_nitem --- dmenubar/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index b733feb..d87e5dc 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -203,7 +203,7 @@ match(char *pattern) { static void kpress(XKeyEvent * e) { char buf[32]; - int i, num, prev_nitem; + int i, num; unsigned int len; KeySym ksym; From fc1b666f81abc0fd21f7fcd21fd2fd99adf50582 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 1 Mar 2007 15:47:54 +0100 Subject: [PATCH 186/590] Added tag 2.6 for changeset 775f761a5647 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index b8053c0..51ad766 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -26,3 +26,4 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3 03e83e2788c83ddd63b45a667939d7ec783c98cb 2.4.1 1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2 041143e9fc544c62edc58af52cae9ac5237e5945 2.5 +775f761a5647a05038e091d1c99fc35d3034cd68 2.6 From 422592173328268c6187c9b937dc00a9c7ab34ef Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 2 Mar 2007 15:16:36 +0100 Subject: [PATCH 187/590] also, don't set the font all the time --- dmenubar/config.mk | 2 +- dmenubar/draw.c | 15 ++++----------- dmenubar/main.c | 2 ++ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index b261284..07b323b 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.6 +VERSION = 2.7 # Customize below to fit your system diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 145df16..d36df30 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -12,7 +12,6 @@ drawtext(const char *text, unsigned long col[ColLast]) { int x, y, w, h; static char buf[256]; unsigned int len, olen; - XGCValues gcv; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); @@ -41,17 +40,11 @@ drawtext(const char *text, unsigned long col[ColLast]) { } if(w > dc.w) return; /* too long */ - gcv.foreground = col[ColFG]; - if(dc.font.set) { - XChangeGC(dpy, dc.gc, GCForeground, &gcv); - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, - x, y, buf, len); - } - else { - gcv.font = dc.font.xfont->fid; - XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv); + XSetForeground(dpy, dc.gc, col[ColFG]); + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + else XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); - } } unsigned int diff --git a/dmenubar/main.c b/dmenubar/main.c index d87e5dc..0f07773 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -493,6 +493,8 @@ main(int argc, char *argv[]) { dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, 0); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); if(maxname) cmdw = textw(maxname); if(cmdw > mw / 3) From 4f2eda6ce35bf03c4db3cfaa279760f4a66934ab Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 2 Mar 2007 21:48:48 +0100 Subject: [PATCH 188/590] keyboard grab works on the dmenu window now (not on the root window) - thx for Kris for this hint --- dmenubar/main.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 0f07773..beb8411 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -110,7 +110,7 @@ drawmenu(void) { static void grabkeyboard(void) { - while(XGrabKeyboard(dpy, root, True, GrabModeAsync, + while(XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) usleep(1000); } @@ -454,24 +454,6 @@ main(int argc, char *argv[]) { eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - 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); /* style */ dc.norm[ColBG] = initcolor(normbg); dc.norm[ColFG] = initcolor(normfg); @@ -495,6 +477,25 @@ main(int argc, char *argv[]) { 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) cmdw = textw(maxname); if(cmdw > mw / 3) @@ -505,8 +506,6 @@ main(int argc, char *argv[]) { promptw = mw / 5; text[0] = 0; match(text); - XMapRaised(dpy, win); - drawmenu(); XSync(dpy, False); /* main event loop */ From d9804ca73b40dcd99ca6b2a8741d1b4038652a71 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 5 Mar 2007 11:25:18 +0100 Subject: [PATCH 189/590] Added tag 2.7 for changeset fbd9e9d63f20 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 51ad766..0c95111 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -27,3 +27,4 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3 1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2 041143e9fc544c62edc58af52cae9ac5237e5945 2.5 775f761a5647a05038e091d1c99fc35d3034cd68 2.6 +fbd9e9d63f202afe6834ccfdf890904f1897ec0b 2.7 From 8f1c31bf98d16264c2c9c733aa52d58d793f6c64 Mon Sep 17 00:00:00 2001 From: Kris Maglione <jg@suckless.org> Date: Tue, 6 Mar 2007 03:24:40 -0500 Subject: [PATCH 190/590] Wait for an Expose and draw the menu immediately after mapping the window. --- dmenubar/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index beb8411..29b313b 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -479,6 +479,8 @@ main(int argc, char *argv[]) { XSetFont(dpy, dc.gc, dc.font.xfont->fid); drawmenu(); XMapRaised(dpy, win); + XMaskEvent(dpy, ExposureMask, &ev); + drawmenu(); if(isatty(STDIN_FILENO)) { maxname = readstdin(); grabkeyboard(); @@ -506,6 +508,7 @@ main(int argc, char *argv[]) { promptw = mw / 5; text[0] = 0; match(text); + drawmenu(); XSync(dpy, False); /* main event loop */ @@ -516,10 +519,6 @@ main(int argc, char *argv[]) { case KeyPress: kpress(&ev.xkey); break; - case Expose: - if(ev.xexpose.count == 0) - drawmenu(); - break; } /* cleanup */ From d9298c3762d76ceac41987ef0c2499b981dd0545 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 7 Mar 2007 10:54:21 +0100 Subject: [PATCH 191/590] reverting keyboard grab to root window - invoking several dmenu's now works again... --- dmenubar/main.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index 29b313b..0f07773 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -110,7 +110,7 @@ drawmenu(void) { static void grabkeyboard(void) { - while(XGrabKeyboard(dpy, win, True, GrabModeAsync, + while(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) usleep(1000); } @@ -454,6 +454,24 @@ main(int argc, char *argv[]) { eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); + 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); /* style */ dc.norm[ColBG] = initcolor(normbg); dc.norm[ColFG] = initcolor(normfg); @@ -477,27 +495,6 @@ main(int argc, char *argv[]) { XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); - drawmenu(); - XMapRaised(dpy, win); - XMaskEvent(dpy, ExposureMask, &ev); - drawmenu(); - 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) cmdw = textw(maxname); if(cmdw > mw / 3) @@ -508,6 +505,7 @@ main(int argc, char *argv[]) { promptw = mw / 5; text[0] = 0; match(text); + XMapRaised(dpy, win); drawmenu(); XSync(dpy, False); @@ -519,6 +517,10 @@ main(int argc, char *argv[]) { case KeyPress: kpress(&ev.xkey); break; + case Expose: + if(ev.xexpose.count == 0) + drawmenu(); + break; } /* cleanup */ From 01f4392ccf541cf3bf2a266ca177c637fccfd8e0 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 7 Mar 2007 11:01:14 +0100 Subject: [PATCH 192/590] attempt to grab the keyboard only 1000 times, not forever. --- dmenubar/config.mk | 2 +- dmenubar/main.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 07b323b..75cc46d 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.7 +VERSION = 2.8 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index 0f07773..fa03ec8 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -108,11 +108,17 @@ drawmenu(void) { XFlush(dpy); } -static void +static Bool grabkeyboard(void) { - while(XGrabKeyboard(dpy, root, True, GrabModeAsync, - GrabModeAsync, CurrentTime) != GrabSuccess) + unsigned int len; + + for(len = 1000; len; len--) { + if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) + == GrabSuccess) + break; usleep(1000); + } + return len > 0; } static unsigned long @@ -456,10 +462,10 @@ main(int argc, char *argv[]) { root = RootWindow(dpy, screen); if(isatty(STDIN_FILENO)) { maxname = readstdin(); - grabkeyboard(); + running = grabkeyboard(); } else { /* prevent keypress loss */ - grabkeyboard(); + running = grabkeyboard(); maxname = readstdin(); } /* init modifier map */ From 76d054038103f906630a70f9603d231d3282be03 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 7 Mar 2007 13:30:57 +0100 Subject: [PATCH 193/590] Added tag 2.8 for changeset dd3d02b07cac --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 0c95111..97a81c4 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -28,3 +28,4 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3 041143e9fc544c62edc58af52cae9ac5237e5945 2.5 775f761a5647a05038e091d1c99fc35d3034cd68 2.6 fbd9e9d63f202afe6834ccfdf890904f1897ec0b 2.7 +dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 From 36750fa19bc19876890a8616822b9a55413040ea Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 27 Mar 2007 16:52:50 +0200 Subject: [PATCH 194/590] allowing numpad keys as inpyt --- dmenubar/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dmenubar/main.c b/dmenubar/main.c index fa03ec8..9fab328 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -216,6 +216,13 @@ kpress(XKeyEvent * e) { len = strlen(text); buf[0] = 0; num = XLookupString(e, buf, sizeof buf, &ksym, 0); + if(IsKeypadKey(ksym)) { + if(ksym == XK_KP_Enter) { + ksym = XK_Return; + } else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) { + ksym = (ksym - XK_KP_0) + XK_0; + } + } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) From 083d4ad1f966c19fb52f70007002a60f2c13014b Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 28 Mar 2007 08:17:57 +0200 Subject: [PATCH 195/590] next version is 2.9 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 75cc46d..efd00bf 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.8 +VERSION = 2.9 # Customize below to fit your system From 607547ebe916597d599f88638df23e7e1f848b2f Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 13 Apr 2007 11:36:44 +0200 Subject: [PATCH 196/590] making copyright notice more compact --- dmenubar/LICENSE | 4 ++-- dmenubar/Makefile | 2 +- dmenubar/config.mk | 2 +- dmenubar/dmenu.h | 7 +++---- dmenubar/draw.c | 7 +++---- dmenubar/main.c | 9 ++++----- dmenubar/util.c | 6 +++--- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 2d25a17..69214cb 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License -(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> +© 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> +© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 3869f4d..6b273cb 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -1,5 +1,5 @@ # dmenu - dynamic menu -# (C)opyright MMVI-MMVII Anselm R. Garbe +# © 2006-2007 Anselm R. Garbe, Sander van Dijk include config.mk diff --git a/dmenubar/config.mk b/dmenubar/config.mk index efd00bf..5230edb 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 2.9 +VERSION = 3.0 # Customize below to fit your system diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 84e19e6..eba71f4 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -1,7 +1,6 @@ -/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ - +/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> + * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> + * See LICENSE file for license details. */ #include <X11/Xlib.h> #define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*" diff --git a/dmenubar/draw.c b/dmenubar/draw.c index d36df30..29fd0eb 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -1,7 +1,6 @@ -/* (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. - */ +/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> + * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> + * See LICENSE file for license details. */ #include "dmenu.h" #include <string.h> diff --git a/dmenubar/main.c b/dmenubar/main.c index 9fab328..c63ac08 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -1,7 +1,6 @@ -/* (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. - */ +/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> + * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> + * See LICENSE file for license details. */ #include "dmenu.h" #include <ctype.h> #include <locale.h> @@ -458,7 +457,7 @@ main(int argc, char *argv[]) { if(++i < argc) selfg = argv[i]; } else if(!strncmp(argv[i], "-v", 3)) - eprint("dmenu-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n"); + eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk\n"); else usage(); setlocale(LC_CTYPE, ""); diff --git a/dmenubar/util.c b/dmenubar/util.c index 124bcd5..0a8aada 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -1,6 +1,6 @@ -/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ +/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> + * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> + * See LICENSE file for license details. */ #include "dmenu.h" #include <stdarg.h> #include <stdio.h> From c24292229ff228e03f04430e38987bfbc345e7a4 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 19 Apr 2007 09:27:08 +0200 Subject: [PATCH 197/590] Added tag 3.0 for changeset 59b3024854db --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 97a81c4..3c55db9 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -29,3 +29,4 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3 775f761a5647a05038e091d1c99fc35d3034cd68 2.6 fbd9e9d63f202afe6834ccfdf890904f1897ec0b 2.7 dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 +59b3024854db49739c6d237fa9077f04a2da847a 3.0 From f0a8fb790da7474738ec694527a826d8bc788d0c Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 2 May 2007 15:25:52 +0200 Subject: [PATCH 198/590] fixed a small bug in dmenu when an empty font is supplied --- dmenubar/config.mk | 2 +- dmenubar/main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 5230edb..ce5daab 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.0 +VERSION = 3.1 # Customize below to fit your system diff --git a/dmenubar/main.c b/dmenubar/main.c index c63ac08..e4c4903 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -135,6 +135,8 @@ initfont(const char *fontstr) { char *def, **missing; int i, n; + if(!fontstr || fontstr[0] == '\0') + eprint("error, cannot load font: '%s'\n", fontstr); missing = NULL; if(dc.font.set) XFreeFontSet(dpy, dc.font.set); From 11f84282a112888c568e1cabc766351c1463f991 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 14 May 2007 11:56:41 +0200 Subject: [PATCH 199/590] applied anydot's dmenu_path caching patch, thank you! --- dmenubar/dmenu_path | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index f64c82e..e590a5c 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,9 +1,30 @@ #!/bin/sh +CACHE=$HOME/.dmenu_cache +UPTODATE=1 IFS=: -for dir in $PATH -do - for file in "$dir"/* + +if test ! -f $CACHE +then + unset UPTODATE +fi + +if test $UPTODATE +then + for dir in $PATH do - test -x "$file" && echo "${file##*/}" + test $dir -nt $CACHE && unset UPTODATE done -done | sort | uniq +fi + +if test ! $UPTODATE +then + for dir in $PATH + do + for file in "$dir"/* + do + test -x "$file" && echo "${file##*/}" + done + done | sort | uniq > $CACHE +fi + +cat $CACHE From 4b905613dbc89b6323b225466b9b509bb75ae6ee Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Tue, 15 May 2007 13:44:41 +0200 Subject: [PATCH 200/590] removed strip, added -s to LDFLAGs --- dmenubar/Makefile | 1 - dmenubar/config.mk | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 6b273cb..35e30f5 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -23,7 +23,6 @@ ${OBJ}: dmenu.h config.mk dmenu: ${OBJ} @echo CC -o $@ @${CC} -o $@ ${OBJ} ${LDFLAGS} - @strip $@ clean: @echo cleaning diff --git a/dmenubar/config.mk b/dmenubar/config.mk index ce5daab..18565ea 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -16,7 +16,7 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" -LDFLAGS = ${LIBS} +LDFLAGS = -s ${LIBS} #CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = -g ${LIBS} From 63520117fd7eb88c35654899c44ff3b4d9d02c49 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Mon, 21 May 2007 14:36:03 +0200 Subject: [PATCH 201/590] Added tag 3.1 for changeset 8f0f917ac988 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 3c55db9..6e74b75 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -30,3 +30,4 @@ b6e09682c8adcb6569656bee73c311f9ab457715 2.3 fbd9e9d63f202afe6834ccfdf890904f1897ec0b 2.7 dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 59b3024854db49739c6d237fa9077f04a2da847a 3.0 +8f0f917ac988164e1b4446236e3a6ab6cfcb8c67 3.1 From aa9e0df79d4bb6cf2bfd611f64f02abc777efa78 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 23 May 2007 13:22:27 +0200 Subject: [PATCH 202/590] applied Jukka's fix --- dmenubar/config.mk | 2 +- dmenubar/dmenu_path | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 18565ea..f4c2fed 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.1 +VERSION = 3.2 # Customize below to fit your system diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index e590a5c..e725ede 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -3,20 +3,22 @@ CACHE=$HOME/.dmenu_cache UPTODATE=1 IFS=: +uptodate() { [ $UPTODATE -eq 1 ]; } + if test ! -f $CACHE then - unset UPTODATE + UPTODATE=0 fi -if test $UPTODATE +if uptodate then for dir in $PATH do - test $dir -nt $CACHE && unset UPTODATE + test $dir -nt $CACHE && { UPTODATE=0; break; } done fi -if test ! $UPTODATE +if ! uptodate then for dir in $PATH do From 7d99061d01ff7e72bbadc6b7f64457c3c8b4b499 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 23 May 2007 22:13:46 +0200 Subject: [PATCH 203/590] made dmenu_path the way anydot proposed in response to Jukka --- dmenubar/dmenu_path | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index e725ede..cd43748 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,22 +1,15 @@ #!/bin/sh CACHE=$HOME/.dmenu_cache -UPTODATE=1 IFS=: -uptodate() { [ $UPTODATE -eq 1 ]; } - -if test ! -f $CACHE -then - UPTODATE=0 -fi - -if uptodate -then - for dir in $PATH - do - test $dir -nt $CACHE && { UPTODATE=0; break; } - done -fi +uptodate() { + test ! -f $CACHE && return 1 + for dir in $PATH + do + test $dir -nt $CACHE && return 1 + done + return 0 +} if ! uptodate then From 4553dfd9638f2cf92c7ee30627667b275a07dfb0 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 23 May 2007 22:32:43 +0200 Subject: [PATCH 204/590] removed some superflous strncmp's --- dmenubar/main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index e4c4903..22ef71b 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -437,28 +437,28 @@ main(int argc, char *argv[]) { /* command line args */ for(i = 1; i < argc; i++) - if(!strncmp(argv[i], "-b", 3)) { + if(!strcmp(argv[i], "-b")) { bottom = True; } - else if(!strncmp(argv[i], "-fn", 4)) { + else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } - else if(!strncmp(argv[i], "-nb", 4)) { + else if(!strcmp(argv[i], "-nb")) { if(++i < argc) normbg = argv[i]; } - else if(!strncmp(argv[i], "-nf", 4)) { + else if(!strcmp(argv[i], "-nf")) { if(++i < argc) normfg = argv[i]; } - else if(!strncmp(argv[i], "-p", 3)) { + else if(!strcmp(argv[i], "-p")) { if(++i < argc) prompt = argv[i]; } - else if(!strncmp(argv[i], "-sb", 4)) { + else if(!strcmp(argv[i], "-sb")) { if(++i < argc) selbg = argv[i]; } - else if(!strncmp(argv[i], "-sf", 4)) { + else if(!strcmp(argv[i], "-sf")) { if(++i < argc) selfg = argv[i]; } - else if(!strncmp(argv[i], "-v", 3)) + else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk\n"); else usage(); From 46a24617eabfc40a081e985ce9d2e5e7ef730497 Mon Sep 17 00:00:00 2001 From: Kris Maglione <jg@suckless.org> Date: Wed, 23 May 2007 16:42:51 -0400 Subject: [PATCH 205/590] Changed dmenu_path (fixed race, improved speed, check that $PATH is the same as the last run). --- dmenubar/dmenu_path | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index cd43748..84e3015 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,25 +1,26 @@ -#!/bin/sh +#!/bin/sh -f CACHE=$HOME/.dmenu_cache IFS=: +qfind() { + find "$@" 2>/dev/null +} + uptodate() { - test ! -f $CACHE && return 1 - for dir in $PATH - do - test $dir -nt $CACHE && return 1 - done - return 0 -} + test -f $CACHE && + test "$(echo "$PATH")" = "$(sed 1q "$CACHE")" && + qfind $PATH -maxdepth 0 -newer $CACHE +} if ! uptodate then - for dir in $PATH - do - for file in "$dir"/* - do - test -x "$file" && echo "${file##*/}" - done - done | sort | uniq > $CACHE + { + echo "$PATH" + qfind $PATH -type f -maxdepth 1 -perm -u+x -o -perm -g+x -o -perm -o+x | + sed 's,.*/,,' | sort | uniq + } > $CACHE.$pid + mv $CACHE.$pid $CACHE fi -cat $CACHE +tail -n +2 $CACHE + From 808ace9176de2e1e21c5b9ab681d425a70ff5281 Mon Sep 17 00:00:00 2001 From: Kris Maglione <jg@suckless.org> Date: Wed, 23 May 2007 16:59:38 -0400 Subject: [PATCH 206/590] Fix grouping in dmenu_path. --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 84e3015..a9a89b7 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -16,7 +16,7 @@ if ! uptodate then { echo "$PATH" - qfind $PATH -type f -maxdepth 1 -perm -u+x -o -perm -g+x -o -perm -o+x | + qfind $PATH -type f -maxdepth 1 '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' | sed 's,.*/,,' | sort | uniq } > $CACHE.$pid mv $CACHE.$pid $CACHE From 3b3a626c231e60fbe02bac408a236b4273130b39 Mon Sep 17 00:00:00 2001 From: Kris Maglione <jg@suckless.org> Date: Wed, 23 May 2007 18:35:05 -0400 Subject: [PATCH 207/590] Silence the first find in dmenu_path. --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index a9a89b7..94db694 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -9,7 +9,7 @@ qfind() { uptodate() { test -f $CACHE && test "$(echo "$PATH")" = "$(sed 1q "$CACHE")" && - qfind $PATH -maxdepth 0 -newer $CACHE + qfind $PATH -maxdepth 0 -newer $CACHE >/dev/null } if ! uptodate From d0d401e6aab2edabf7106121c6d5058b673d3b95 Mon Sep 17 00:00:00 2001 From: Kris Maglione <jg@suckless.org> Date: Wed, 23 May 2007 19:38:23 -0400 Subject: [PATCH 208/590] Fix the uptodate logic (uptodate if !find newer dirs than the cache). --- dmenubar/dmenu_path | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 94db694..3569077 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -9,7 +9,7 @@ qfind() { uptodate() { test -f $CACHE && test "$(echo "$PATH")" = "$(sed 1q "$CACHE")" && - qfind $PATH -maxdepth 0 -newer $CACHE >/dev/null + ! qfind $PATH -maxdepth 0 -newer $CACHE >/dev/null } if ! uptodate @@ -18,7 +18,7 @@ then echo "$PATH" qfind $PATH -type f -maxdepth 1 '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' | sed 's,.*/,,' | sort | uniq - } > $CACHE.$pid + } mv $CACHE.$pid $CACHE fi From f36570c2c53c923719f422f28435b4464c6d802e Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Thu, 24 May 2007 10:34:44 +0200 Subject: [PATCH 209/590] I agree with the race fix of JG, but I dislike the SUSV3-breaking find, and I don't care about PATH changes, keep it simple, stupid --- dmenubar/dmenu_path | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 3569077..d0a32c5 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,26 +1,26 @@ -#!/bin/sh -f +#!/bin/sh CACHE=$HOME/.dmenu_cache IFS=: -qfind() { - find "$@" 2>/dev/null -} - -uptodate() { - test -f $CACHE && - test "$(echo "$PATH")" = "$(sed 1q "$CACHE")" && - ! qfind $PATH -maxdepth 0 -newer $CACHE >/dev/null +uptodate() { + test ! -f $CACHE && return 1 + for dir in $PATH + do + test $dir -nt $CACHE && return 1 + done + return 0 } if ! uptodate then - { - echo "$PATH" - qfind $PATH -type f -maxdepth 1 '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' | - sed 's,.*/,,' | sort | uniq - } - mv $CACHE.$pid $CACHE + for dir in $PATH + do + for file in "$dir"/* + do + test -x "$file" && echo "${file##*/}" + done + done | sort | uniq > $CACHE.$$ + mv $CACHE.$$ $CACHE fi -tail -n +2 $CACHE - +cat $CACHE From bba29b10addd45568374d3ff6245ac639e464cc8 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 30 May 2007 12:19:06 +0200 Subject: [PATCH 210/590] referred to LICENSE file --- dmenubar/dmenu.h | 4 +--- dmenubar/draw.c | 4 +--- dmenubar/main.c | 4 +--- dmenubar/util.c | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index eba71f4..0b8015c 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -1,6 +1,4 @@ -/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> - * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> - * See LICENSE file for license details. */ +/* See LICENSE file for copyright and license details. */ #include <X11/Xlib.h> #define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*" diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 29fd0eb..72439c5 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -1,6 +1,4 @@ -/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> - * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> - * See LICENSE file for license details. */ +/* See LICENSE file for copyright and license details. */ #include "dmenu.h" #include <string.h> diff --git a/dmenubar/main.c b/dmenubar/main.c index 22ef71b..9c10958 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -1,6 +1,4 @@ -/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> - * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> - * See LICENSE file for license details. */ +/* See LICENSE file for copyright and license details. */ #include "dmenu.h" #include <ctype.h> #include <locale.h> diff --git a/dmenubar/util.c b/dmenubar/util.c index 0a8aada..ff943d0 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -1,6 +1,4 @@ -/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> - * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> - * See LICENSE file for license details. */ +/* See LICENSE file for copyright and license details. */ #include "dmenu.h" #include <stdarg.h> #include <stdio.h> From 6fbcb8effdc469cbfb14f33842b506005db66472 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Wed, 30 May 2007 12:22:38 +0200 Subject: [PATCH 211/590] Added tag 3.2 for changeset e4c81a78ffba --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 6e74b75..a647650 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -31,3 +31,4 @@ fbd9e9d63f202afe6834ccfdf890904f1897ec0b 2.7 dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 59b3024854db49739c6d237fa9077f04a2da847a 3.0 8f0f917ac988164e1b4446236e3a6ab6cfcb8c67 3.1 +e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 From 0ef5c46ea6d790c6da2b659ff05be914a151bb00 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <arg@suckless.org> Date: Fri, 1 Jun 2007 12:28:30 +0200 Subject: [PATCH 212/590] foooooo --- dmenubar/dmenu.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h index 0b8015c..015e808 100644 --- a/dmenubar/dmenu.h +++ b/dmenubar/dmenu.h @@ -26,9 +26,9 @@ typedef struct { } font; } DC; /* draw context */ -int screen; -Display *dpy; -DC dc; /* global drawing context */ +extern int screen; +extern Display *dpy; +extern DC dc; /* global drawing context */ /* draw.c */ void drawtext(const char *text, unsigned long col[ColLast]); @@ -36,6 +36,6 @@ unsigned int textw(const char *text); unsigned int textnw(const char *text, unsigned int len); /* util.c */ -void *emalloc(unsigned int size); /* allocates memory, exits on error */ -void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ -char *estrdup(const char *str); /* duplicates str, exits on allocation error */ +void *emalloc(unsigned int size); /* allocates memory, exits on error */ +void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ +char *estrdup(const char *str); /* duplicates str, exits on allocation error */ From 71a551bf647244f6428e9280aca9062caf89a8d0 Mon Sep 17 00:00:00 2001 From: "arg@f00b4r" <unknown> Date: Tue, 24 Jul 2007 18:19:09 +0200 Subject: [PATCH 213/590] applied ido-matching to dmenu --- dmenubar/main.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dmenubar/main.c b/dmenubar/main.c index 9c10958..bf53763 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -168,6 +168,14 @@ initfont(const char *fontstr) { dc.font.height = dc.font.ascent + dc.font.descent; } +static int +strido(const char *text, const char *pattern) { + for(; *text && *pattern; text++) + if (*text == *pattern) + pattern++; + return !*pattern; +} + static void match(char *pattern) { unsigned int plen; @@ -192,6 +200,19 @@ match(char *pattern) { for(i = allitems; i; i=i->next) if(plen && strncmp(pattern, i->text, plen) && strstr(i->text, pattern)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + for(i = allitems; i; i=i->next) + if(plen && strncmp(pattern, i->text, plen) + && !strstr(i->text, pattern) + && strido(i->text,pattern)) { if(!j) item = i; else From 34e03fa120c85c44b7a55597c47e3cf7c7f05511 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sat, 15 Sep 2007 20:28:20 +0200 Subject: [PATCH 214/590] fixed fallback --- dmenubar/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dmenubar/main.c b/dmenubar/main.c index bf53763..fcabf01 100644 --- a/dmenubar/main.c +++ b/dmenubar/main.c @@ -160,8 +160,10 @@ initfont(const char *fontstr) { 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); + if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))) { + if(!(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) + eprint("error, cannot load font: '%s'\n", fontstr); + } dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; } From 5ba5ad8216fae0e7307a82cb699b48868e8c7e36 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 16 Sep 2007 20:14:09 +0200 Subject: [PATCH 215/590] micromizing dmenu step 1 --- dmenubar/Makefile | 6 +- dmenubar/config.h | 10 +++ dmenubar/{main.c => dmenu.c} | 149 ++++++++++++++++++++++++++++++++--- dmenubar/dmenu.h | 41 ---------- dmenubar/draw.c | 61 -------------- dmenubar/util.c | 34 -------- 6 files changed, 149 insertions(+), 152 deletions(-) create mode 100644 dmenubar/config.h rename dmenubar/{main.c => dmenu.c} (79%) delete mode 100644 dmenubar/dmenu.h delete mode 100644 dmenubar/draw.c delete mode 100644 dmenubar/util.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 35e30f5..dac3b6e 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = draw.c main.c util.c +SRC = dmenu.c OBJ = ${SRC:.c=.o} all: options dmenu @@ -18,7 +18,7 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: dmenu.h config.mk +${OBJ}: config.h config.mk dmenu: ${OBJ} @echo CC -o $@ @@ -31,7 +31,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.h dmenu_path ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 config.h dmenu_path ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/config.h b/dmenubar/config.h new file mode 100644 index 0000000..973b2d1 --- /dev/null +++ b/dmenubar/config.h @@ -0,0 +1,10 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +#define FONT "-*-terminus-medium-r-*-*-12-*-*-*-*-*-iso10646-*" +#define NORMBGCOLOR "#000" +#define NORMFGCOLOR "#ccc" +#define SELBGCOLOR "#00f" +#define SELFGCOLOR "#fff" +/* next macro defines the space between menu items */ +#define SPACE 30 /* px */ diff --git a/dmenubar/main.c b/dmenubar/dmenu.c similarity index 79% rename from dmenubar/main.c rename to dmenubar/dmenu.c index fcabf01..b684175 100644 --- a/dmenubar/main.c +++ b/dmenubar/dmenu.c @@ -1,16 +1,37 @@ /* See LICENSE file for copyright and license details. */ -#include "dmenu.h" #include <ctype.h> #include <locale.h> +#include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> +#include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h> +/* macros */ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +/* enums */ +enum { ColFG, ColBG, ColLast }; + +/* typedefs */ +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; + } font; +} DC; /* draw context */ + typedef struct Item Item; struct Item { Item *next; /* traverses all items */ @@ -18,8 +39,29 @@ struct Item { char *text; }; -/* static */ +/* forward declarations */ +static void *emalloc(unsigned int size); +static void eprint(const char *errstr, ...); +static char *estrdup(const char *str); +static void drawtext(const char *text, unsigned long col[ColLast]); +static unsigned int textw(const char *text); +static unsigned int textnw(const char *text, unsigned int len); +static void calcoffsets(void); +static void drawmenu(void); +static Bool grabkeyboard(void); +static unsigned long getcolor(const char *colstr); +static void initfont(const char *fontstr); +static int strido(const char *text, const char *pattern); +static void match(char *pattern); +static void kpress(XKeyEvent * e); +static char *readstdin(void); +static void usage(void); + +/* variables */ +static int screen; +static Display *dpy; +static DC dc = {0}; static char text[4096]; static char *prompt = NULL; static int mw, mh; @@ -38,6 +80,93 @@ static Item *curr = NULL; static Window root; static Window win; +#include "config.h" + +static void * +emalloc(unsigned int size) { + void *res = malloc(size); + + if(!res) + eprint("fatal: could not malloc() %u bytes\n", size); + return res; +} + +static void +eprint(const char *errstr, ...) { + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +static char * +estrdup(const char *str) { + void *res = strdup(str); + + if(!res) + eprint("fatal: could not malloc() %u bytes\n", strlen(str)); + return res; +} + + +static void +drawtext(const char *text, unsigned long col[ColLast]) { + int x, y, w, h; + static char buf[256]; + unsigned int len, olen; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, col[ColBG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + w = 0; + olen = len = strlen(text); + if(len >= sizeof buf) + len = sizeof buf - 1; + memcpy(buf, text, len); + buf[len] = 0; + h = dc.font.ascent + dc.font.descent; + y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; + x = dc.x + (h / 2); + /* shorten text if necessary */ + while(len && (w = textnw(buf, len)) > dc.w - h) + buf[--len] = 0; + if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; + if(len > 3) + buf[len - 3] = '.'; + } + if(w > dc.w) + return; /* too long */ + XSetForeground(dpy, dc.gc, col[ColFG]); + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + else + XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); +} + +static unsigned int +textw(const char *text) { + return textnw(text, strlen(text)) + dc.font.height; +} + +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); +} + static void calcoffsets(void) { unsigned int tw, w; @@ -119,7 +248,7 @@ grabkeyboard(void) { } static unsigned long -initcolor(const char *colstr) { +getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -435,12 +564,6 @@ usage(void) { " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); } -/* extern */ - -int screen; -Display *dpy; -DC dc = {0}; - int main(int argc, char *argv[]) { Bool bottom = False; @@ -508,10 +631,10 @@ main(int argc, char *argv[]) { } XFreeModifiermap(modmap); /* style */ - dc.norm[ColBG] = initcolor(normbg); - dc.norm[ColFG] = initcolor(normfg); - dc.sel[ColBG] = initcolor(selbg); - dc.sel[ColFG] = initcolor(selfg); + dc.norm[ColBG] = getcolor(normbg); + dc.norm[ColFG] = getcolor(normfg); + dc.sel[ColBG] = getcolor(selbg); + dc.sel[ColFG] = getcolor(selfg); initfont(font); /* menu window */ wa.override_redirect = 1; diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h deleted file mode 100644 index 015e808..0000000 --- a/dmenubar/dmenu.h +++ /dev/null @@ -1,41 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> - -#define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*" -#define NORMBGCOLOR "#eeeeee" -#define NORMFGCOLOR "#222222" -#define SELBGCOLOR "#006699" -#define SELFGCOLOR "#ffffff" -#define SPACE 30 /* px */ - -/* color */ -enum { ColFG, ColBG, ColLast }; - -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; - } font; -} DC; /* draw context */ - -extern int screen; -extern Display *dpy; -extern DC dc; /* global drawing context */ - -/* draw.c */ -void drawtext(const char *text, unsigned long col[ColLast]); -unsigned int textw(const char *text); -unsigned int textnw(const char *text, unsigned int len); - -/* util.c */ -void *emalloc(unsigned int size); /* allocates memory, exits on error */ -void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ -char *estrdup(const char *str); /* duplicates str, exits on allocation error */ diff --git a/dmenubar/draw.c b/dmenubar/draw.c deleted file mode 100644 index 72439c5..0000000 --- a/dmenubar/draw.c +++ /dev/null @@ -1,61 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "dmenu.h" -#include <string.h> - -/* extern */ - -void -drawtext(const char *text, unsigned long col[ColLast]) { - int x, y, w, h; - static char buf[256]; - unsigned int len, olen; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - - XSetForeground(dpy, dc.gc, col[ColBG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; - h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ - XSetForeground(dpy, dc.gc, col[ColFG]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); - else - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -} - -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); -} diff --git a/dmenubar/util.c b/dmenubar/util.c deleted file mode 100644 index ff943d0..0000000 --- a/dmenubar/util.c +++ /dev/null @@ -1,34 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "dmenu.h" -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -void * -emalloc(unsigned int size) { - void *res = malloc(size); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", size); - return res; -} - -void -eprint(const char *errstr, ...) { - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - -char * -estrdup(const char *str) { - void *res = strdup(str); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", strlen(str)); - return res; -} From c5f7a230349d8b6d1266e898af3c44ce169764e8 Mon Sep 17 00:00:00 2001 From: "arg@suckless.org" <unknown> Date: Mon, 17 Sep 2007 09:13:21 +0200 Subject: [PATCH 216/590] next version is 3.3 --- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index f4c2fed..b4c3110 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.2 +VERSION = 3.3 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 56c3bdd..373d193 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -1,4 +1,4 @@ -.TH DMENU 1 dmenu\-VERSION +.TH DMENU 1 dmenu\-3.2 .SH NAME dmenu \- dynamic menu .SH SYNOPSIS From 6b16d827bb9577d11e47a74989eee597d7c6c9b1 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Mon, 17 Sep 2007 20:53:14 +0200 Subject: [PATCH 217/590] reorganized --- dmenubar/dmenu.c | 595 ++++++++++++++++++++++++----------------------- 1 file changed, 303 insertions(+), 292 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b684175..34df9ed 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -40,134 +40,55 @@ struct Item { }; /* forward declarations */ -static void *emalloc(unsigned int size); -static void eprint(const char *errstr, ...); -static char *estrdup(const char *str); -static void drawtext(const char *text, unsigned long col[ColLast]); -static unsigned int textw(const char *text); -static unsigned int textnw(const char *text, unsigned int len); -static void calcoffsets(void); -static void drawmenu(void); -static Bool grabkeyboard(void); -static unsigned long getcolor(const char *colstr); -static void initfont(const char *fontstr); -static int strido(const char *text, const char *pattern); -static void match(char *pattern); -static void kpress(XKeyEvent * e); -static char *readstdin(void); -static void usage(void); - - -/* variables */ -static int screen; -static Display *dpy; -static DC dc = {0}; -static char text[4096]; -static char *prompt = NULL; -static int mw, mh; -static int ret = 0; -static int nitem = 0; -static unsigned int cmdw = 0; -static unsigned int promptw = 0; -static unsigned int numlockmask = 0; -static Bool running = True; -static Item *allitems = NULL; /* first of all items */ -static Item *item = NULL; /* first of pattern matching items */ -static Item *sel = NULL; -static Item *next = NULL; -static Item *prev = NULL; -static Item *curr = NULL; -static Window root; -static Window win; +void calcoffsets(void); +void cleanup(void); +void drawmenu(void); +void drawtext(const char *text, unsigned long col[ColLast]); +void *emalloc(unsigned int size); +void eprint(const char *errstr, ...); +char *estrdup(const char *str); +unsigned long getcolor(const char *colstr); +Bool grabkeyboard(void); +void initfont(const char *fontstr); +void kpress(XKeyEvent * e); +void match(char *pattern); +void readstdin(void); +void run(void); +void setup(Bool bottom); +int strido(const char *text, const char *pattern); +unsigned int textnw(const char *text, unsigned int len); +unsigned int textw(const char *text); #include "config.h" -static void * -emalloc(unsigned int size) { - void *res = malloc(size); +/* variables */ +char *font = FONT; +char *maxname = NULL; +char *normbg = NORMBGCOLOR; +char *normfg = NORMFGCOLOR; +char *prompt = NULL; +char *selbg = SELBGCOLOR; +char *selfg = SELFGCOLOR; +char text[4096]; +int screen; +int ret = 0; +unsigned int cmdw = 0; +unsigned int mw, mh; +unsigned int promptw = 0; +unsigned int nitem = 0; +unsigned int numlockmask = 0; +Bool running = True; +Display *dpy; +DC dc = {0}; +Item *allitems = NULL; /* first of all items */ +Item *item = NULL; /* first of pattern matching items */ +Item *sel = NULL; +Item *next = NULL; +Item *prev = NULL; +Item *curr = NULL; +Window root, win; - if(!res) - eprint("fatal: could not malloc() %u bytes\n", size); - return res; -} - -static void -eprint(const char *errstr, ...) { - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - -static char * -estrdup(const char *str) { - void *res = strdup(str); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", strlen(str)); - return res; -} - - -static void -drawtext(const char *text, unsigned long col[ColLast]) { - int x, y, w, h; - static char buf[256]; - unsigned int len, olen; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - - XSetForeground(dpy, dc.gc, col[ColBG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; - h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ - XSetForeground(dpy, dc.gc, col[ColFG]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); - else - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -} - -static unsigned int -textw(const char *text) { - return textnw(text, strlen(text)) + dc.font.height; -} - -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); -} - -static void +void calcoffsets(void) { unsigned int tw, w; @@ -193,7 +114,27 @@ calcoffsets(void) { } } -static void +void +cleanup(void) { + Item *itm; + + while(allitems) { + itm = allitems->next; + free(allitems->text); + free(allitems); + allitems = itm; + } + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else + XFreeFont(dpy, dc.font.xfont); + XFreePixmap(dpy, dc.drawable); + XFreeGC(dpy, dc.gc); + XDestroyWindow(dpy, win); + XUngrabKeyboard(dpy, CurrentTime); +} + +void drawmenu(void) { Item *i; @@ -234,7 +175,85 @@ drawmenu(void) { XFlush(dpy); } -static Bool +void +drawtext(const char *text, unsigned long col[ColLast]) { + int x, y, w, h; + static char buf[256]; + unsigned int len, olen; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, col[ColBG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + w = 0; + olen = len = strlen(text); + if(len >= sizeof buf) + len = sizeof buf - 1; + memcpy(buf, text, len); + buf[len] = 0; + h = dc.font.ascent + dc.font.descent; + y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; + x = dc.x + (h / 2); + /* shorten text if necessary */ + while(len && (w = textnw(buf, len)) > dc.w - h) + buf[--len] = 0; + if(len < olen) { + if(len > 1) + buf[len - 1] = '.'; + if(len > 2) + buf[len - 2] = '.'; + if(len > 3) + buf[len - 3] = '.'; + } + if(w > dc.w) + return; /* too long */ + XSetForeground(dpy, dc.gc, col[ColFG]); + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + else + XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); +} + +void * +emalloc(unsigned int size) { + void *res = malloc(size); + + if(!res) + eprint("fatal: could not malloc() %u bytes\n", size); + return res; +} + +void +eprint(const char *errstr, ...) { + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +char * +estrdup(const char *str) { + void *res = strdup(str); + + if(!res) + eprint("fatal: could not malloc() %u bytes\n", strlen(str)); + return res; +} + +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; +} + +Bool grabkeyboard(void) { unsigned int len; @@ -247,17 +266,7 @@ grabkeyboard(void) { return len > 0; } -static 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; -} - -static void +void initfont(const char *fontstr) { char *def, **missing; int i, n; @@ -299,65 +308,7 @@ initfont(const char *fontstr) { dc.font.height = dc.font.ascent + dc.font.descent; } -static int -strido(const char *text, const char *pattern) { - for(; *text && *pattern; text++) - if (*text == *pattern) - pattern++; - return !*pattern; -} - -static void -match(char *pattern) { - unsigned int plen; - Item *i, *j; - - if(!pattern) - return; - plen = strlen(pattern); - item = j = NULL; - nitem = 0; - for(i = allitems; i; i=i->next) - if(!plen || !strncmp(pattern, i->text, plen)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } - for(i = allitems; i; i=i->next) - if(plen && strncmp(pattern, i->text, plen) - && strstr(i->text, pattern)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } - for(i = allitems; i; i=i->next) - if(plen && strncmp(pattern, i->text, plen) - && !strstr(i->text, pattern) - && strido(i->text,pattern)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } - curr = prev = next = sel = item; - calcoffsets(); -} - -static void +void kpress(XKeyEvent * e) { char buf[32]; int i, num; @@ -528,9 +479,58 @@ kpress(XKeyEvent * e) { drawmenu(); } -static char * +void +match(char *pattern) { + unsigned int plen; + Item *i, *j; + + if(!pattern) + return; + plen = strlen(pattern); + item = j = NULL; + nitem = 0; + for(i = allitems; i; i=i->next) + if(!plen || !strncmp(pattern, i->text, plen)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + for(i = allitems; i; i=i->next) + if(plen && strncmp(pattern, i->text, plen) + && strstr(i->text, pattern)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + for(i = allitems; i; i=i->next) + if(plen && strncmp(pattern, i->text, plen) + && !strstr(i->text, pattern) + && strido(i->text,pattern)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + curr = prev = next = sel = item; + calcoffsets(); +} + +void readstdin(void) { - static char *maxname = NULL; char *p, buf[1024]; unsigned int len = 0, max = 0; Item *i, *new; @@ -554,30 +554,109 @@ readstdin(void) { i->next = new; i = new; } - - 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"); +void +run(void) { + XEvent ev; + + /* main event loop */ + while(running && !XNextEvent(dpy, &ev)) + switch (ev.type) { + default: /* ignore all crap */ + break; + case KeyPress: + kpress(&ev.xkey); + break; + case Expose: + if(ev.xexpose.count == 0) + drawmenu(); + break; + } +} + +void +setup(Bool bottom) { + unsigned int i, j; + XModifierKeymap *modmap; + XSetWindowAttributes wa; + + /* 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 */ + dc.norm[ColBG] = getcolor(normbg); + dc.norm[ColFG] = getcolor(normfg); + dc.sel[ColBG] = getcolor(selbg); + dc.sel[ColFG] = getcolor(selfg); + initfont(font); + + /* menu window */ + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; + mw = DisplayWidth(dpy, screen); + mh = dc.font.height + 2; + 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); + + /* pixmap */ + dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, root, 0, 0); + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); + if(maxname) + cmdw = textw(maxname); + if(cmdw > mw / 3) + cmdw = mw / 3; + if(prompt) + promptw = textw(prompt); + if(promptw > mw / 5) + promptw = mw / 5; + text[0] = 0; + match(text); + XMapRaised(dpy, win); +} + +int +strido(const char *text, const char *pattern) { + for(; *text && *pattern; text++) + if (*text == *pattern) + pattern++; + return !*pattern; +} + +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); +} + +unsigned int +textw(const char *text) { + return textnw(text, strlen(text)) + dc.font.height; } int main(int argc, char *argv[]) { Bool bottom = False; - char *font = FONT; - char *maxname; - char *normbg = NORMBGCOLOR; - char *normfg = NORMFGCOLOR; - char *selbg = SELBGCOLOR; - char *selfg = SELFGCOLOR; - int i, j; - Item *itm; - XEvent ev; - XModifierKeymap *modmap; - XSetWindowAttributes wa; + unsigned int i; /* command line args */ for(i = 1; i < argc; i++) @@ -605,97 +684,29 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk\n"); else - usage(); + eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" + " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); + if(isatty(STDIN_FILENO)) { - maxname = readstdin(); + readstdin(); running = grabkeyboard(); } else { /* prevent keypress loss */ running = grabkeyboard(); - maxname = readstdin(); + 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 */ - dc.norm[ColBG] = getcolor(normbg); - dc.norm[ColFG] = getcolor(normfg); - dc.sel[ColBG] = getcolor(selbg); - dc.sel[ColFG] = getcolor(selfg); - initfont(font); - /* menu window */ - wa.override_redirect = 1; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; - mw = DisplayWidth(dpy, screen); - mh = dc.font.height + 2; - 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); - /* pixmap */ - dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, 0); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); - if(maxname) - cmdw = textw(maxname); - if(cmdw > mw / 3) - cmdw = mw / 3; - if(prompt) - promptw = textw(prompt); - if(promptw > mw / 5) - promptw = mw / 5; - text[0] = 0; - match(text); - XMapRaised(dpy, win); + + setup(bottom); drawmenu(); XSync(dpy, False); - - /* main event loop */ - while(running && !XNextEvent(dpy, &ev)) - switch (ev.type) { - default: /* ignore all crap */ - break; - case KeyPress: - kpress(&ev.xkey); - break; - case Expose: - if(ev.xexpose.count == 0) - drawmenu(); - break; - } - - /* cleanup */ - while(allitems) { - itm = allitems->next; - free(allitems->text); - free(allitems); - allitems = itm; - } - if(dc.font.set) - XFreeFontSet(dpy, dc.font.set); - else - XFreeFont(dpy, dc.font.xfont); - XFreePixmap(dpy, dc.drawable); - XFreeGC(dpy, dc.gc); - XDestroyWindow(dpy, win); - XUngrabKeyboard(dpy, CurrentTime); + run(); + cleanup(); XCloseDisplay(dpy); return ret; } From f8690b9940d5a2a842f4ff54b8b63aa8b2dc1351 Mon Sep 17 00:00:00 2001 From: "arg@suckless.org" <unknown> Date: Wed, 19 Sep 2007 17:33:35 +0200 Subject: [PATCH 218/590] applied yiyus initfont fix --- dmenubar/dmenu.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 34df9ed..5cb638b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -298,10 +298,9 @@ initfont(const char *fontstr) { if(dc.font.xfont) XFreeFont(dpy, dc.font.xfont); dc.font.xfont = NULL; - if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))) { - if(!(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) - eprint("error, cannot load font: '%s'\n", fontstr); - } + if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) + && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) + eprint("error, cannot load font: '%s'\n", fontstr); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; } From 6dedc680dc80fbca09deb89a292dedc08ab54843 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sat, 22 Sep 2007 09:12:50 +0200 Subject: [PATCH 219/590] Added tag 3.3 for changeset 709df5a4bad7 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index a647650..bd393f0 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -32,3 +32,4 @@ dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 59b3024854db49739c6d237fa9077f04a2da847a 3.0 8f0f917ac988164e1b4446236e3a6ab6cfcb8c67 3.1 e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 +709df5a4bad7015a346b2b44b1b3b573ea3088ff 3.3 From 4a2f2fbdddecbe81fed52fac8a423e380dbd5887 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 23 Sep 2007 18:26:41 +0200 Subject: [PATCH 220/590] =?UTF-8?q?applied=20Micha=C5=82=20Janeczek=20dmen?= =?UTF-8?q?u=20patch,=20made=20dmenu=20match=20case-insensitive=20by=20def?= =?UTF-8?q?ault,=20added=20-i=20command=20line=20option=20to=20enable=20id?= =?UTF-8?q?o=20matching,=20added=20Micha=C5=82=20to=20Copyright=20holders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dmenubar/LICENSE | 1 + dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 4 +++ dmenubar/dmenu.c | 79 +++++++++++++++++++++++----------------------- 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 69214cb..85970bb 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -2,6 +2,7 @@ MIT/X Consortium License © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> +© 2006-2007 Michał Janeczek <janeczek at gmail dot com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/config.mk b/dmenubar/config.mk index b4c3110..22a8adc 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.3 +VERSION = 3.4 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 373d193..dc13f2b 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -4,6 +4,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu .RB [ \-b ] +.RB [ \-i ] .RB [ \-fn " <font>"] .RB [ \-nb " <color>"] .RB [ \-nf " <color>"] @@ -22,6 +23,9 @@ efficiently. .B \-b makes dmenu appear at the screen bottom (by default it appears at the screen top). .TP +.B \-i +makes dmenu match menu entries with ignoring intermediate characters. +.TP .B \-fn <font> defines the font. .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5cb638b..3bb9351 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -37,9 +37,11 @@ struct Item { Item *next; /* traverses all items */ Item *left, *right; /* traverses items matching current search pattern */ char *text; + Bool matched; }; /* forward declarations */ +Item *appenditem(Item *i, Item *last); void calcoffsets(void); void cleanup(void); void drawmenu(void); @@ -55,7 +57,7 @@ void match(char *pattern); void readstdin(void); void run(void); void setup(Bool bottom); -int strido(const char *text, const char *pattern); +int strcaseido(const char *text, const char *pattern); unsigned int textnw(const char *text, unsigned int len); unsigned int textw(const char *text); @@ -77,6 +79,7 @@ unsigned int mw, mh; unsigned int promptw = 0; unsigned int nitem = 0; unsigned int numlockmask = 0; +Bool idomatch = False; Bool running = True; Display *dpy; DC dc = {0}; @@ -88,6 +91,20 @@ Item *prev = NULL; Item *curr = NULL; Window root, win; +Item * +appenditem(Item *i, Item *last) { + if(!last) + item = i; + else + last->right = i; + i->matched = True; + i->left = last; + i->right = NULL; + last = i; + nitem++; + return last; +} + void calcoffsets(void) { unsigned int tw, w; @@ -489,41 +506,21 @@ match(char *pattern) { item = j = NULL; nitem = 0; for(i = allitems; i; i=i->next) - if(!plen || !strncmp(pattern, i->text, plen)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } - for(i = allitems; i; i=i->next) - if(plen && strncmp(pattern, i->text, plen) - && strstr(i->text, pattern)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } - for(i = allitems; i; i=i->next) - if(plen && strncmp(pattern, i->text, plen) - && !strstr(i->text, pattern) - && strido(i->text,pattern)) { - if(!j) - item = i; - else - j->right = i; - i->left = j; - i->right = NULL; - j = i; - nitem++; - } + i->matched = False; + + for(i = allitems; i; i = i->next) + if(!i->matched && !strncasecmp(pattern, i->text, plen)) + j = appenditem(i,j); + + for (i = allitems; i; i = i->next) + if(!i->matched && strcasestr(i->text, pattern)) + j = appenditem(i, j); + + if(idomatch) + for (i = allitems; i; i = i->next) + if(!i->matched && strcaseido(i->text, pattern)) + j = appenditem(i, j); + curr = prev = next = sel = item; calcoffsets(); } @@ -629,9 +626,9 @@ setup(Bool bottom) { } int -strido(const char *text, const char *pattern) { +strcaseido(const char *text, const char *pattern) { for(; *text && *pattern; text++) - if (*text == *pattern) + if (tolower(*text) == tolower(*pattern)) pattern++; return !*pattern; } @@ -662,6 +659,8 @@ main(int argc, char *argv[]) { if(!strcmp(argv[i], "-b")) { bottom = True; } + else if(!strcmp(argv[i], "-i")) + idomatch = True; else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } @@ -681,9 +680,9 @@ main(int argc, char *argv[]) { if(++i < argc) selfg = argv[i]; } else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk\n"); + eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, Michał Janeczek\n"); else - eprint("usage: dmenu [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" + eprint("usage: dmenu [-b] [-i] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); From 64baa5e456ac1e5986c6939358508090a81e0a81 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 23 Sep 2007 18:31:19 +0200 Subject: [PATCH 221/590] small cosmetic fix --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3bb9351..a4fca09 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -510,7 +510,7 @@ match(char *pattern) { for(i = allitems; i; i = i->next) if(!i->matched && !strncasecmp(pattern, i->text, plen)) - j = appenditem(i,j); + j = appenditem(i, j); for (i = allitems; i; i = i->next) if(!i->matched && strcasestr(i->text, pattern)) From 3d8bf688d4f1a00734ce42ed2de6cf28b309ec42 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 23 Sep 2007 18:32:08 +0200 Subject: [PATCH 222/590] yet another cosmetic fix --- dmenubar/dmenu.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a4fca09..dea227e 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -507,20 +507,16 @@ match(char *pattern) { nitem = 0; for(i = allitems; i; i=i->next) i->matched = False; - for(i = allitems; i; i = i->next) if(!i->matched && !strncasecmp(pattern, i->text, plen)) j = appenditem(i, j); - - for (i = allitems; i; i = i->next) + for(i = allitems; i; i = i->next) if(!i->matched && strcasestr(i->text, pattern)) j = appenditem(i, j); - if(idomatch) - for (i = allitems; i; i = i->next) + for(i = allitems; i; i = i->next) if(!i->matched && strcaseido(i->text, pattern)) j = appenditem(i, j); - curr = prev = next = sel = item; calcoffsets(); } From 85e40949942b6c3a835558314eead19b7ebb4d63 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 23 Sep 2007 18:49:24 +0200 Subject: [PATCH 223/590] switching to white --- dmenubar/config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 973b2d1..9efbfd8 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -2,9 +2,9 @@ /* appearance */ #define FONT "-*-terminus-medium-r-*-*-12-*-*-*-*-*-iso10646-*" -#define NORMBGCOLOR "#000" -#define NORMFGCOLOR "#ccc" -#define SELBGCOLOR "#00f" -#define SELFGCOLOR "#fff" +#define NORMBGCOLOR "#ffffff" +#define NORMFGCOLOR "#000000" +#define SELBGCOLOR "#0000ff" +#define SELFGCOLOR "#ffffff" /* next macro defines the space between menu items */ #define SPACE 30 /* px */ From 9740d4757915c308bdce539f08b7678627581d83 Mon Sep 17 00:00:00 2001 From: "arg@suckless.org" <unknown> Date: Mon, 24 Sep 2007 15:04:31 +0200 Subject: [PATCH 224/590] casting char to int when using tolower (thanks to Jukkas careful cosmetic checking!) --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index dea227e..b28a548 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -624,7 +624,7 @@ setup(Bool bottom) { int strcaseido(const char *text, const char *pattern) { for(; *text && *pattern; text++) - if (tolower(*text) == tolower(*pattern)) + if(tolower((int)*text) == tolower((int)*pattern)) pattern++; return !*pattern; } From 51842c9b9b7dcc85f8620bd739e1fd54d20470bc Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Wed, 26 Sep 2007 19:15:47 +0200 Subject: [PATCH 225/590] applied my favorite color scheme --- dmenubar/config.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 9efbfd8..fa40686 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -1,10 +1,10 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -#define FONT "-*-terminus-medium-r-*-*-12-*-*-*-*-*-iso10646-*" -#define NORMBGCOLOR "#ffffff" -#define NORMFGCOLOR "#000000" -#define SELBGCOLOR "#0000ff" -#define SELFGCOLOR "#ffffff" +#define FONT "-*-proggyclean-*-*-*-*-*-*-*-*-*-*-*-*" +#define NORMBGCOLOR "#ffffff" +#define NORMFGCOLOR "#333333" +#define SELBGCOLOR "#3366ff" +#define SELFGCOLOR "#ffffff" /* next macro defines the space between menu items */ #define SPACE 30 /* px */ From 5038ace4e7aa83215d1ba492002c8c5e6e0f9eb2 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Thu, 27 Sep 2007 18:55:05 +0200 Subject: [PATCH 226/590] applied new color nuance --- dmenubar/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index fa40686..1e25b65 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -2,9 +2,9 @@ /* appearance */ #define FONT "-*-proggyclean-*-*-*-*-*-*-*-*-*-*-*-*" -#define NORMBGCOLOR "#ffffff" +#define NORMBGCOLOR "#dddddd" #define NORMFGCOLOR "#333333" -#define SELBGCOLOR "#3366ff" +#define SELBGCOLOR "#0066cc" #define SELFGCOLOR "#ffffff" /* next macro defines the space between menu items */ #define SPACE 30 /* px */ From f84b41a584988a2250fc3fcf9f5c97733f0a48d9 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 30 Sep 2007 12:47:40 +0200 Subject: [PATCH 227/590] using saner defaults --- dmenubar/config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 1e25b65..4fcbba9 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -1,10 +1,10 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -#define FONT "-*-proggyclean-*-*-*-*-*-*-*-*-*-*-*-*" -#define NORMBGCOLOR "#dddddd" -#define NORMFGCOLOR "#333333" -#define SELBGCOLOR "#0066cc" +#define FONT "-*-terminus-*-*-*-*-*-*-*-*-*-*-*-*" +#define NORMBGCOLOR "#cccccc" +#define NORMFGCOLOR "#000000" +#define SELBGCOLOR "#0066ff" #define SELFGCOLOR "#ffffff" /* next macro defines the space between menu items */ #define SPACE 30 /* px */ From 4f5725af957054ccf0fe4478ac212ca156f8d770 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Sun, 30 Sep 2007 19:20:31 +0200 Subject: [PATCH 228/590] fixed dmenu --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index dc13f2b..a8cd0fd 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -1,4 +1,4 @@ -.TH DMENU 1 dmenu\-3.2 +.TH DMENU 1 dmenu\-VERSION .SH NAME dmenu \- dynamic menu .SH SYNOPSIS From b9531d316b65baf6b945d9e73e9ac4cae7e525ed Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Mon, 1 Oct 2007 11:44:25 +0200 Subject: [PATCH 229/590] fixed font definition --- dmenubar/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 4fcbba9..07e28e4 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -#define FONT "-*-terminus-*-*-*-*-*-*-*-*-*-*-*-*" +#define FONT "-*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*" #define NORMBGCOLOR "#cccccc" #define NORMFGCOLOR "#000000" #define SELBGCOLOR "#0066ff" From 2c6f4ebae33e7c5331b3ae15a4986f5616fd7553 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Mon, 1 Oct 2007 15:28:42 +0200 Subject: [PATCH 230/590] implemented strcasestr for dmenu (I call it cistrstr) for portability issues (cygwin has no strcasestr, oh dear) --- dmenubar/dmenu.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b28a548..3256f9c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -58,6 +58,7 @@ void readstdin(void); void run(void); void setup(Bool bottom); int strcaseido(const char *text, const char *pattern); +char *cistrstr(const char *s, const char *sub); unsigned int textnw(const char *text, unsigned int len); unsigned int textw(const char *text); @@ -511,7 +512,7 @@ match(char *pattern) { if(!i->matched && !strncasecmp(pattern, i->text, plen)) j = appenditem(i, j); for(i = allitems; i; i = i->next) - if(!i->matched && strcasestr(i->text, pattern)) + if(!i->matched && cistrstr(i->text, pattern)) j = appenditem(i, j); if(idomatch) for(i = allitems; i; i = i->next) @@ -629,6 +630,29 @@ strcaseido(const char *text, const char *pattern) { return !*pattern; } +char * +cistrstr(const char *s, const char *sub) { + int c, csub; + unsigned int len; + + if(!sub) + return (char *)s; + if((c = *sub++) != 0) { + c = tolower(c); + len = strlen(sub); + do { + do { + if((csub = *s++) == 0) + return (NULL); + } + while(tolower(csub) != c); + } + while(strncasecmp(s, sub, len) != 0); + s--; + } + return (char *)s; +} + unsigned int textnw(const char *text, unsigned int len) { XRectangle r; From 559b38db87abf892dc275bd39fe3e105cb8d0f67 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Wed, 10 Oct 2007 18:57:51 +0200 Subject: [PATCH 231/590] adapted c99 for pedantic checks, even if those checks are somewhat broken --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 22a8adc..5f19207 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -17,7 +17,7 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" LDFLAGS = -s ${LIBS} -#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" +#CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = -g ${LIBS} # Solaris From 9631ee0a2b6e179252417ecef36f4445b07920b2 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" <garbeam@gmail.com> Date: Thu, 25 Oct 2007 20:26:17 +0200 Subject: [PATCH 232/590] Added tag 3.4 for changeset 9ab649b3b3e5 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index bd393f0..33052db 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -33,3 +33,4 @@ dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 8f0f917ac988164e1b4446236e3a6ab6cfcb8c67 3.1 e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 709df5a4bad7015a346b2b44b1b3b573ea3088ff 3.3 +9ab649b3b3e5bfccf1c8f352c59e5361e070a25f 3.4 From 67bf8f1c855b191e40bf3b8d3c1952edb7b284f1 Mon Sep 17 00:00:00 2001 From: "anselm@anselm1" <unknown> Date: Sat, 22 Dec 2007 12:20:20 +0000 Subject: [PATCH 233/590] added dmenu run --- dmenubar/Makefile | 6 ++++-- dmenubar/config.mk | 2 +- dmenubar/dmenu_run | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100755 dmenubar/dmenu_run diff --git a/dmenubar/Makefile b/dmenubar/Makefile index dac3b6e..8c0aa39 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -31,7 +31,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 config.h dmenu_path ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 config.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} @@ -39,9 +39,10 @@ dist: clean install: all @echo installing executable file to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_path ${DESTDIR}${PREFIX}/bin + @cp -f dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path + @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run @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 @@ -50,6 +51,7 @@ install: all uninstall: @echo removing executable file from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_path + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_run @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 5f19207..9406af6 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.4 +VERSION = 3.5 # Customize below to fit your system diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run new file mode 100755 index 0000000..1cecc16 --- /dev/null +++ b/dmenubar/dmenu_run @@ -0,0 +1,2 @@ +#!/bin/sh +exe=`dmenu_path | dmenu $*` && exec $exe From 022cef64697b86ba8cb373c69ffdba526169e311 Mon Sep 17 00:00:00 2001 From: "anselm@aab" <unknown> Date: Mon, 11 Feb 2008 11:22:38 +0000 Subject: [PATCH 234/590] updated --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 1cecc16..97e43ed 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,2 +1,2 @@ #!/bin/sh -exe=`dmenu_path | dmenu $*` && exec $exe +set exe=`dmenu_path | dmenu $*` && exec $exe From 2405d3504177b46e07887c44a47c484bc53b936e Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 12 Feb 2008 09:42:48 +0000 Subject: [PATCH 235/590] removed set --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 97e43ed..1cecc16 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,2 +1,2 @@ #!/bin/sh -set exe=`dmenu_path | dmenu $*` && exec $exe +exe=`dmenu_path | dmenu $*` && exec $exe From 7bc43c37a537f596e498897ddc7bf93494039553 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 12 Mar 2008 15:41:19 +0000 Subject: [PATCH 236/590] removed ido-matching, changed behavior of -i meaning case insensitive matching now, commented -x, -y, -w arguments in dmenu.1 --- dmenubar/LICENSE | 2 +- dmenubar/config.h | 2 +- dmenubar/dmenu.1 | 16 ++++++++++---- dmenubar/dmenu.c | 53 ++++++++++++++++++++--------------------------- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 85970bb..2039f2a 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,6 +1,6 @@ MIT/X Consortium License -© 2006-2007 Anselm R. Garbe <garbeam at gmail dot com> +© 2006-2008 Anselm R. Garbe <garbeam at gmail dot com> © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2006-2007 Michał Janeczek <janeczek at gmail dot com> diff --git a/dmenubar/config.h b/dmenubar/config.h index 07e28e4..1afae6f 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -#define FONT "-*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*" +#define FONT "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*" #define NORMBGCOLOR "#cccccc" #define NORMFGCOLOR "#000000" #define SELBGCOLOR "#0066ff" diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index a8cd0fd..f772634 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,8 +3,10 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-b ] .RB [ \-i ] +.RB [ \-x " <x>"] +.RB [ \-y " <y>"] +.RB [ \-w " <width>"] .RB [ \-fn " <font>"] .RB [ \-nb " <color>"] .RB [ \-nf " <color>"] @@ -20,11 +22,17 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP -.B \-b -makes dmenu appear at the screen bottom (by default it appears at the screen top). +.B \-x +defines the x coordinate dmenu appears at (0 by default). +.TP +.B \-y +defines the y coordinate dmenu appears at (0 by default). +.TP +.B \-w +defines the width of the dmenu window (screen width by default). .TP .B \-i -makes dmenu match menu entries with ignoring intermediate characters. +makes dmenu match menu entries case insensitively. .TP .B \-fn <font> defines the font. diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3256f9c..864c8f0 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -56,8 +56,7 @@ void kpress(XKeyEvent * e); void match(char *pattern); void readstdin(void); void run(void); -void setup(Bool bottom); -int strcaseido(const char *text, const char *pattern); +void setup(int x, int y, int w); char *cistrstr(const char *s, const char *sub); unsigned int textnw(const char *text, unsigned int len); unsigned int textw(const char *text); @@ -80,7 +79,6 @@ unsigned int mw, mh; unsigned int promptw = 0; unsigned int nitem = 0; unsigned int numlockmask = 0; -Bool idomatch = False; Bool running = True; Display *dpy; DC dc = {0}; @@ -91,6 +89,7 @@ Item *next = NULL; Item *prev = NULL; Item *curr = NULL; Window root, win; +char *(*fstrstr)(const char *, const char *) = strstr; Item * appenditem(Item *i, Item *last) { @@ -512,12 +511,8 @@ match(char *pattern) { if(!i->matched && !strncasecmp(pattern, i->text, plen)) j = appenditem(i, j); for(i = allitems; i; i = i->next) - if(!i->matched && cistrstr(i->text, pattern)) + if(!i->matched && fstrstr(i->text, pattern)) j = appenditem(i, j); - if(idomatch) - for(i = allitems; i; i = i->next) - if(!i->matched && strcaseido(i->text, pattern)) - j = appenditem(i, j); curr = prev = next = sel = item; calcoffsets(); } @@ -569,7 +564,7 @@ run(void) { } void -setup(Bool bottom) { +setup(int x, int y, int w) { unsigned int i, j; XModifierKeymap *modmap; XSetWindowAttributes wa; @@ -595,10 +590,9 @@ setup(Bool bottom) { wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; - mw = DisplayWidth(dpy, screen); + mw = w ? w : DisplayWidth(dpy, screen); mh = dc.font.height + 2; - win = XCreateWindow(dpy, root, 0, - bottom ? DisplayHeight(dpy, screen) - mh : 0, mw, mh, 0, + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); @@ -622,14 +616,6 @@ setup(Bool bottom) { XMapRaised(dpy, win); } -int -strcaseido(const char *text, const char *pattern) { - for(; *text && *pattern; text++) - if(tolower((int)*text) == tolower((int)*pattern)) - pattern++; - return !*pattern; -} - char * cistrstr(const char *s, const char *sub) { int c, csub; @@ -671,16 +657,13 @@ textw(const char *text) { int main(int argc, char *argv[]) { - Bool bottom = False; + int x = 0, y = 0, w = 0; unsigned int i; /* command line args */ for(i = 1; i < argc; i++) - if(!strcmp(argv[i], "-b")) { - bottom = True; - } - else if(!strcmp(argv[i], "-i")) - idomatch = True; + if(!strcmp(argv[i], "-i")) + fstrstr = cistrstr; else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } @@ -699,11 +682,21 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) { if(++i < argc) selfg = argv[i]; } + else if(!strcmp(argv[i], "-x")) { + if(++i < argc) x = atoi(argv[i]); + } + else if(!strcmp(argv[i], "-y")) { + if(++i < argc) y = atoi(argv[i]); + } + else if(!strcmp(argv[i], "-w")) { + if(++i < argc) w = atoi(argv[i]); + } else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, Michał Janeczek\n"); + eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); else - eprint("usage: dmenu [-b] [-i] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); + eprint("usage: dmenu [-i] [-fn <font>] [-nb <color>] [-nf <color>]\n" + " [-p <prompt>] [-sb <color>] [-sf <color>]\n" + " [-x <x>] [-y <y>] [-w <w>] [-v]\n"); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) @@ -720,7 +713,7 @@ main(int argc, char *argv[]) { readstdin(); } - setup(bottom); + setup(x, y, w); drawmenu(); XSync(dpy, False); run(); From a2fd1ba078b69def73ded01e3d69508636ee4a3a Mon Sep 17 00:00:00 2001 From: "anselm@anselm1" <unknown> Date: Wed, 12 Mar 2008 21:37:43 +0000 Subject: [PATCH 237/590] applied Sanders patch --- dmenubar/LICENSE | 2 +- dmenubar/dmenu.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 2039f2a..8e87c0f 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License © 2006-2008 Anselm R. Garbe <garbeam at gmail dot com> -© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> +© 2006-2008 Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2006-2007 Michał Janeczek <janeczek at gmail dot com> Permission is hereby granted, free of charge, to any person obtaining a diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 864c8f0..ddde475 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -37,7 +37,6 @@ struct Item { Item *next; /* traverses all items */ Item *left, *right; /* traverses items matching current search pattern */ char *text; - Bool matched; }; /* forward declarations */ @@ -89,6 +88,7 @@ Item *next = NULL; Item *prev = NULL; Item *curr = NULL; Window root, win; +int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; char *(*fstrstr)(const char *, const char *) = strstr; Item * @@ -97,7 +97,6 @@ appenditem(Item *i, Item *last) { item = i; else last->right = i; - i->matched = True; i->left = last; i->right = NULL; last = i; @@ -505,13 +504,10 @@ match(char *pattern) { plen = strlen(pattern); item = j = NULL; nitem = 0; - for(i = allitems; i; i=i->next) - i->matched = False; for(i = allitems; i; i = i->next) - if(!i->matched && !strncasecmp(pattern, i->text, plen)) + if(!fstrncmp(pattern, i->text, plen)) j = appenditem(i, j); - for(i = allitems; i; i = i->next) - if(!i->matched && fstrstr(i->text, pattern)) + else if(fstrstr(i->text, pattern)) j = appenditem(i, j); curr = prev = next = sel = item; calcoffsets(); @@ -662,8 +658,10 @@ main(int argc, char *argv[]) { /* command line args */ for(i = 1; i < argc; i++) - if(!strcmp(argv[i], "-i")) + if(!strcmp(argv[i], "-i")) { + fstrncmp = strncasecmp; fstrstr = cistrstr; + } else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } From 67ca56193976abadf712040097985d180a6b08a1 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 13 Mar 2008 12:02:29 +0000 Subject: [PATCH 238/590] applied next patch of Sander --- dmenubar/dmenu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index ddde475..5f81d25 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -505,9 +505,8 @@ match(char *pattern) { item = j = NULL; nitem = 0; for(i = allitems; i; i = i->next) - if(!fstrncmp(pattern, i->text, plen)) - j = appenditem(i, j); - else if(fstrstr(i->text, pattern)) + if(!fstrncmp(pattern, i->text, plen) + || fstrstr(i->text, pattern)) j = appenditem(i, j); curr = prev = next = sel = item; calcoffsets(); From 4459f0ef6abd73e2ad897b32e80fc17de767676e Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 13 Mar 2008 16:53:25 +0000 Subject: [PATCH 239/590] Added tag 3.5 for changeset 05e5bd706b3b --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 33052db..b572b26 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -34,3 +34,4 @@ dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 709df5a4bad7015a346b2b44b1b3b573ea3088ff 3.3 9ab649b3b3e5bfccf1c8f352c59e5361e070a25f 3.4 +05e5bd706b3b3e61399d57c4bb43df296a20112d 3.5 From a244fee55140fba9513e952fa50ab5026598bb71 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 18 Mar 2008 16:52:51 +0000 Subject: [PATCH 240/590] fixed match() to prefer prefix-matches to strstr-matches in the match list, extended the -y handling, next version is 3.6 --- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 4 ++- dmenubar/dmenu.c | 70 +++++++++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 9406af6..3cc8b32 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.5 +VERSION = 3.6 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index f772634..7dac2a1 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -26,7 +26,9 @@ efficiently. defines the x coordinate dmenu appears at (0 by default). .TP .B \-y -defines the y coordinate dmenu appears at (0 by default). +defines the y coordinate dmenu appears at (0 by default). If it is negative, +dmenu will appear with the bottom at the given positive coordinate. It it is +-0, dmenu appears at the screen bottom. .TP .B \-w defines the width of the dmenu window (screen width by default). diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5f81d25..688fabf 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -34,14 +34,16 @@ typedef struct { typedef struct Item Item; struct Item { + char *text; + Bool matched; Item *next; /* traverses all items */ Item *left, *right; /* traverses items matching current search pattern */ - char *text; }; /* forward declarations */ Item *appenditem(Item *i, Item *last); void calcoffsets(void); +char *cistrstr(const char *s, const char *sub); void cleanup(void); void drawmenu(void); void drawtext(const char *text, unsigned long col[ColLast]); @@ -56,7 +58,6 @@ void match(char *pattern); void readstdin(void); void run(void); void setup(int x, int y, int w); -char *cistrstr(const char *s, const char *sub); unsigned int textnw(const char *text, unsigned int len); unsigned int textw(const char *text); @@ -130,6 +131,29 @@ calcoffsets(void) { } } +char * +cistrstr(const char *s, const char *sub) { + int c, csub; + unsigned int len; + + if(!sub) + return (char *)s; + if((c = *sub++) != 0) { + c = tolower(c); + len = strlen(sub); + do { + do { + if((csub = *s++) == 0) + return (NULL); + } + while(tolower(csub) != c); + } + while(strncasecmp(s, sub, len) != 0); + s--; + } + return (char *)s; +} + void cleanup(void) { Item *itm; @@ -505,8 +529,10 @@ match(char *pattern) { item = j = NULL; nitem = 0; for(i = allitems; i; i = i->next) - if(!fstrncmp(pattern, i->text, plen) - || fstrstr(i->text, pattern)) + if((i->matched = !fstrncmp(pattern, i->text, plen))) + j = appenditem(i, j); + for(i = allitems; i; i = i->next) + if(!i->matched && fstrstr(i->text, pattern)) j = appenditem(i, j); curr = prev = next = sel = item; calcoffsets(); @@ -587,6 +613,12 @@ setup(int x, int y, int w) { wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; mw = w ? w : DisplayWidth(dpy, screen); mh = dc.font.height + 2; + if(y < 0) { + if(y == (int)(unsigned int)-1) + y = DisplayHeight(dpy, screen) - mh; + else + y = (-1 * y) - mh; + } win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), @@ -611,29 +643,6 @@ setup(int x, int y, int w) { XMapRaised(dpy, win); } -char * -cistrstr(const char *s, const char *sub) { - int c, csub; - unsigned int len; - - if(!sub) - return (char *)s; - if((c = *sub++) != 0) { - c = tolower(c); - len = strlen(sub); - do { - do { - if((csub = *s++) == 0) - return (NULL); - } - while(tolower(csub) != c); - } - while(strncasecmp(s, sub, len) != 0); - s--; - } - return (char *)s; -} - unsigned int textnw(const char *text, unsigned int len) { XRectangle r; @@ -683,7 +692,12 @@ main(int argc, char *argv[]) { if(++i < argc) x = atoi(argv[i]); } else if(!strcmp(argv[i], "-y")) { - if(++i < argc) y = atoi(argv[i]); + if(++i < argc) { + if(!strcmp(argv[i], "-0")) + y = (int)(unsigned int)-1; + else + y = atoi(argv[i]); + } } else if(!strcmp(argv[i], "-w")) { if(++i < argc) w = atoi(argv[i]); From 526ac879ceb0ebccf475f3a8a98b8294c85ec5cf Mon Sep 17 00:00:00 2001 From: "anselm@anselm1" <unknown> Date: Sat, 22 Mar 2008 14:52:00 +0000 Subject: [PATCH 241/590] several performance tweaks --- dmenubar/Makefile | 2 +- dmenubar/dmenu.c | 61 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 8c0aa39..e7df2d7 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -1,5 +1,5 @@ # dmenu - dynamic menu -# © 2006-2007 Anselm R. Garbe, Sander van Dijk +# See LICENSE file for copyright and license details. include config.mk diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 688fabf..5191a20 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -35,13 +35,12 @@ typedef struct { typedef struct Item Item; struct Item { char *text; - Bool matched; Item *next; /* traverses all items */ Item *left, *right; /* traverses items matching current search pattern */ }; /* forward declarations */ -Item *appenditem(Item *i, Item *last); +void appenditem(Item *i, Item **list, Item **last); void calcoffsets(void); char *cistrstr(const char *s, const char *sub); void cleanup(void); @@ -92,17 +91,15 @@ Window root, win; int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; char *(*fstrstr)(const char *, const char *) = strstr; -Item * -appenditem(Item *i, Item *last) { - if(!last) - item = i; +void +appenditem(Item *i, Item **list, Item **last) { + if(!(*last)) + *list = i; else - last->right = i; - i->left = last; + (*last)->right = i; + i->left = *last; i->right = NULL; - last = i; - nitem++; - return last; + *last = i; } void @@ -521,19 +518,47 @@ kpress(XKeyEvent * e) { void match(char *pattern) { unsigned int plen; - Item *i, *j; + Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; if(!pattern) return; plen = strlen(pattern); - item = j = NULL; + item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; nitem = 0; for(i = allitems; i; i = i->next) - if((i->matched = !fstrncmp(pattern, i->text, plen))) - j = appenditem(i, j); - for(i = allitems; i; i = i->next) - if(!i->matched && fstrstr(i->text, pattern)) - j = appenditem(i, j); + if(!fstrncmp(pattern, i->text, plen + 1)) { + appenditem(i, &lexact, &exactend); + nitem++; + } + else if(!fstrncmp(pattern, i->text, plen)) { + appenditem(i, &lprefix, &prefixend); + nitem++; + } + else if(fstrstr(i->text, pattern)) { + appenditem(i, &lsubstr, &substrend); + nitem++; + } + if(lexact) { + item = lexact; + itemend = exactend; + } + if(lprefix) { + if(itemend) { + itemend->right - lprefix; + lprefix->left = itemend; + } + else + item = lprefix; + itemend = prefixend; + } + if(lsubstr) { + if(itemend) { + itemend->right = lsubstr; + lsubstr->left = itemend; + } + else + item = lsubstr; + } curr = prev = next = sel = item; calcoffsets(); } From f0b40c2272d5699deb4a8d3fe23ea53fc8368e82 Mon Sep 17 00:00:00 2001 From: "sander@localhost" <unknown> Date: Sun, 23 Mar 2008 12:09:29 +0100 Subject: [PATCH 242/590] removed unused variable nitem. --- dmenubar/dmenu.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5191a20..b07671c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -76,7 +76,6 @@ int ret = 0; unsigned int cmdw = 0; unsigned int mw, mh; unsigned int promptw = 0; -unsigned int nitem = 0; unsigned int numlockmask = 0; Bool running = True; Display *dpy; @@ -524,20 +523,13 @@ match(char *pattern) { return; plen = strlen(pattern); item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; - nitem = 0; for(i = allitems; i; i = i->next) - if(!fstrncmp(pattern, i->text, plen + 1)) { + if(!fstrncmp(pattern, i->text, plen + 1)) appenditem(i, &lexact, &exactend); - nitem++; - } - else if(!fstrncmp(pattern, i->text, plen)) { + else if(!fstrncmp(pattern, i->text, plen)) appenditem(i, &lprefix, &prefixend); - nitem++; - } - else if(fstrstr(i->text, pattern)) { + else if(fstrstr(i->text, pattern)) appenditem(i, &lsubstr, &substrend); - nitem++; - } if(lexact) { item = lexact; itemend = exactend; From d03db2746653b5cebe37953fe0f42aecfab9638e Mon Sep 17 00:00:00 2001 From: Sander van Dijk <a.h.vandijk@gmail.com> Date: Sun, 23 Mar 2008 21:11:42 +0100 Subject: [PATCH 243/590] made some whitespacing consistent. --- dmenubar/dmenu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b07671c..bc69bcf 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -295,7 +295,7 @@ grabkeyboard(void) { for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) - == GrabSuccess) + == GrabSuccess) break; usleep(1000); } @@ -361,8 +361,8 @@ kpress(XKeyEvent * e) { } } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) - || IsPrivateKeypadKey(ksym)) + || IsMiscFunctionKey(ksym) || IsPFKey(ksym) + || IsPrivateKeypadKey(ksym)) return; /* first check if a control mask is omitted */ if(e->state & ControlMask) { From 191b11fa4e59692c3739d7f7fd219ab221113acb Mon Sep 17 00:00:00 2001 From: Sander van Dijk <a.h.vandijk@gmail.com> Date: Sun, 23 Mar 2008 21:17:35 +0100 Subject: [PATCH 244/590] cosmetics --- dmenubar/dmenu.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index bc69bcf..4584c07 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -353,13 +353,11 @@ kpress(XKeyEvent * e) { len = strlen(text); buf[0] = 0; num = XLookupString(e, buf, sizeof buf, &ksym, 0); - if(IsKeypadKey(ksym)) { - if(ksym == XK_KP_Enter) { + if(IsKeypadKey(ksym)) + if(ksym == XK_KP_Enter) ksym = XK_Return; - } else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) { + else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; - } - } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) From b550b3807d8db622b3f95029d31119ce556f898b Mon Sep 17 00:00:00 2001 From: Sander van Dijk <a.h.vandijk@gmail.com> Date: Sun, 23 Mar 2008 22:06:09 +0100 Subject: [PATCH 245/590] more cosmetics --- dmenubar/dmenu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 4584c07..695b25c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -707,12 +707,11 @@ main(int argc, char *argv[]) { if(++i < argc) x = atoi(argv[i]); } else if(!strcmp(argv[i], "-y")) { - if(++i < argc) { + if(++i < argc) if(!strcmp(argv[i], "-0")) y = (int)(unsigned int)-1; else y = atoi(argv[i]); - } } else if(!strcmp(argv[i], "-w")) { if(++i < argc) w = atoi(argv[i]); From edc5bd2624450219d1ae69336dabc80ed3c99c9e Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 24 Mar 2008 15:56:41 +0000 Subject: [PATCH 246/590] applied Jukkas hotfix --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 695b25c..b5638b6 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -534,7 +534,7 @@ match(char *pattern) { } if(lprefix) { if(itemend) { - itemend->right - lprefix; + itemend->right = lprefix; lprefix->left = itemend; } else From 757ded3b27690d05645e94b2c0730406707e1c42 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 25 Mar 2008 09:43:34 +0000 Subject: [PATCH 247/590] bugfix of the -0 case in dmenu (thanks to Sander for his hint) --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b5638b6..78c5a75 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -629,7 +629,7 @@ setup(int x, int y, int w) { mw = w ? w : DisplayWidth(dpy, screen); mh = dc.font.height + 2; if(y < 0) { - if(y == (int)(unsigned int)-1) + if(y == ((~(unsigned int)0)/2)+1) y = DisplayHeight(dpy, screen) - mh; else y = (-1 * y) - mh; @@ -709,7 +709,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-y")) { if(++i < argc) if(!strcmp(argv[i], "-0")) - y = (int)(unsigned int)-1; + y = ((~(unsigned int)0)/2)+1; else y = atoi(argv[i]); } From 3d6fd016a44c7f23721c8b30e8ad0d7e573ac9b2 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 25 Mar 2008 10:18:17 +0000 Subject: [PATCH 248/590] using limits.h --- dmenubar/dmenu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 78c5a75..3d3a928 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> +#include <limits.h> #include <locale.h> #include <stdarg.h> #include <stdlib.h> @@ -629,7 +630,7 @@ setup(int x, int y, int w) { mw = w ? w : DisplayWidth(dpy, screen); mh = dc.font.height + 2; if(y < 0) { - if(y == ((~(unsigned int)0)/2)+1) + if(y == INT_MIN) y = DisplayHeight(dpy, screen) - mh; else y = (-1 * y) - mh; @@ -709,7 +710,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-y")) { if(++i < argc) if(!strcmp(argv[i], "-0")) - y = ((~(unsigned int)0)/2)+1; + y = INT_MIN; else y = atoi(argv[i]); } From 7a1c04e1777219b8bfb61a4c6044e1af8bf0c6c5 Mon Sep 17 00:00:00 2001 From: Sander van Dijk <a.h.vandijk@gmail.com> Date: Tue, 25 Mar 2008 19:18:16 +0100 Subject: [PATCH 249/590] fix typo --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 7dac2a1..8eecf8e 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -27,7 +27,7 @@ defines the x coordinate dmenu appears at (0 by default). .TP .B \-y defines the y coordinate dmenu appears at (0 by default). If it is negative, -dmenu will appear with the bottom at the given positive coordinate. It it is +dmenu will appear with the bottom at the given positive coordinate. If it is -0, dmenu appears at the screen bottom. .TP .B \-w From 79528810c0911b9da9b7503011839bab5f5ca136 Mon Sep 17 00:00:00 2001 From: "anselm@anselm1" <unknown> Date: Thu, 3 Apr 2008 21:56:42 +0100 Subject: [PATCH 250/590] Added tag 3.6 for changeset 0bc2751d06e8 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index b572b26..121a20f 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -35,3 +35,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 709df5a4bad7015a346b2b44b1b3b573ea3088ff 3.3 9ab649b3b3e5bfccf1c8f352c59e5361e070a25f 3.4 05e5bd706b3b3e61399d57c4bb43df296a20112d 3.5 +0bc2751d06e8b95e0138854c7815e154c5c3d990 3.6 From 23c9149e1ac7095205ef542b0ff48d98b8631520 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 9 Apr 2008 23:31:49 +0100 Subject: [PATCH 251/590] re-applied Peter Hartlich's and Jukkas dmenu-related patches, for odd reasons they disappeared --- dmenubar/config.mk | 2 +- dmenubar/dmenu_path | 16 ++++++++-------- dmenubar/dmenu_run | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 3cc8b32..30e8b64 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.6 +VERSION = 3.7 # Customize below to fit your system diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index d0a32c5..a9ddd47 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -3,24 +3,24 @@ CACHE=$HOME/.dmenu_cache IFS=: uptodate() { - test ! -f $CACHE && return 1 + test -f "$CACHE" && for dir in $PATH do - test $dir -nt $CACHE && return 1 + test ! $dir -nt "$CACHE" || return 1 done - return 0 } if ! uptodate then for dir in $PATH do - for file in "$dir"/* + cd "$dir" && + for file in * do - test -x "$file" && echo "${file##*/}" + test -x "$file" && echo "$file" done - done | sort | uniq > $CACHE.$$ - mv $CACHE.$$ $CACHE + done | sort -u > "$CACHE".$$ && + mv "$CACHE".$$ "$CACHE" fi -cat $CACHE +cat "$CACHE" diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 1cecc16..3e1e6e4 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,2 +1,2 @@ #!/bin/sh -exe=`dmenu_path | dmenu $*` && exec $exe +exe=`dmenu_path | dmenu ${1+"$@"}` && exec $exe From aecf6ce78db09820b92e0f320da59c57cfcce08c Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 9 Apr 2008 23:32:46 +0100 Subject: [PATCH 252/590] though sticking to |uniq --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index a9ddd47..7896a9e 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -19,7 +19,7 @@ then do test -x "$file" && echo "$file" done - done | sort -u > "$CACHE".$$ && + done | sort | uniq > "$CACHE".$$ && mv "$CACHE".$$ "$CACHE" fi From 833d8cc9860c309aa2f41bbb6867ad579ffc1f06 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 10 Apr 2008 16:46:32 +0100 Subject: [PATCH 253/590] fixed unquoted dmenu_run $exe-use reported by Jukka --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 3e1e6e4..3858796 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,2 +1,2 @@ #!/bin/sh -exe=`dmenu_path | dmenu ${1+"$@"}` && exec $exe +exe=`dmenu_path | dmenu ${1+"$@"}` && exec "$exe" From bed4bc5fd085c244a4344a9a30adfb2a2c7702a9 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 10 Apr 2008 18:12:00 +0100 Subject: [PATCH 254/590] no exe should be unquoted, agreed to Peter Hartlich --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 3858796..3e1e6e4 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,2 +1,2 @@ #!/bin/sh -exe=`dmenu_path | dmenu ${1+"$@"}` && exec "$exe" +exe=`dmenu_path | dmenu ${1+"$@"}` && exec $exe From fcbababeea202b8e5692b895e9ec657cfe2fd8dc Mon Sep 17 00:00:00 2001 From: "anselm@anselm1" <unknown> Date: Mon, 19 May 2008 20:29:32 +0100 Subject: [PATCH 255/590] added Xinerama support to dmenu, reverted -b behavior, removed -x, -y, -w --- dmenubar/config.mk | 9 +++++-- dmenubar/dmenu.1 | 18 ++++---------- dmenubar/dmenu.c | 60 ++++++++++++++++++++++++---------------------- 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 30e8b64..c3ed11b 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -10,12 +10,17 @@ MANPREFIX = ${PREFIX}/share/man X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib +# Xinerama, comment if you don't want it +XINERAMALIBS = -L${X11LIB} -lXinerama +XINERAMAFLAGS = -DXINERAMA + # includes and libs INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" +CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CFLAGS = -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} #CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = -g ${LIBS} diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 8eecf8e..a072883 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -4,9 +4,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu .RB [ \-i ] -.RB [ \-x " <x>"] -.RB [ \-y " <y>"] -.RB [ \-w " <width>"] +.RB [ \-b ] .RB [ \-fn " <font>"] .RB [ \-nb " <color>"] .RB [ \-nf " <color>"] @@ -22,20 +20,12 @@ It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. .SS Options .TP -.B \-x -defines the x coordinate dmenu appears at (0 by default). -.TP -.B \-y -defines the y coordinate dmenu appears at (0 by default). If it is negative, -dmenu will appear with the bottom at the given positive coordinate. If it is --0, dmenu appears at the screen bottom. -.TP -.B \-w -defines the width of the dmenu window (screen width by default). -.TP .B \-i makes dmenu match menu entries case insensitively. .TP +.B \-b +defines that dmenu appears at the bottom. +.TP .B \-fn <font> defines the font. .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3d3a928..0faa02e 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,6 +1,5 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> -#include <limits.h> #include <locale.h> #include <stdarg.h> #include <stdlib.h> @@ -10,6 +9,9 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h> +#ifdef XINERAMA +#include <X11/extensions/Xinerama.h> +#endif /* macros */ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) @@ -57,7 +59,7 @@ void kpress(XKeyEvent * e); void match(char *pattern); void readstdin(void); void run(void); -void setup(int x, int y, int w); +void setup(Bool topbar); unsigned int textnw(const char *text, unsigned int len); unsigned int textw(const char *text); @@ -601,10 +603,13 @@ run(void) { } void -setup(int x, int y, int w) { - unsigned int i, j; +setup(Bool topbar) { + int i, j, x, y; XModifierKeymap *modmap; XSetWindowAttributes wa; +#if XINERAMA + XineramaScreenInfo *info = NULL; +#endif /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -627,14 +632,25 @@ setup(int x, int y, int w) { wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; - mw = w ? w : DisplayWidth(dpy, screen); + + /* menu window geometry */ mh = dc.font.height + 2; - if(y < 0) { - if(y == INT_MIN) - y = DisplayHeight(dpy, screen) - mh; - else - y = (-1 * y) - mh; +#if XINERAMA + if(XineramaIsActive(dpy)) { + info = XineramaQueryScreens(dpy, &i); + x = info[0].x_org; + y = topbar ? info[0].y_org : info[0].y_org + info[0].height - mh; + mw = info[0].width; + XFree(info); } + else +#endif + { + x = 0; + y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; + mw = DisplayWidth(dpy, screen); + } + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), @@ -677,8 +693,8 @@ textw(const char *text) { int main(int argc, char *argv[]) { - int x = 0, y = 0, w = 0; unsigned int i; + Bool topbar = True; /* command line args */ for(i = 1; i < argc; i++) @@ -686,6 +702,8 @@ main(int argc, char *argv[]) { fstrncmp = strncasecmp; fstrstr = cistrstr; } + else if(!strcmp(argv[i], "-b")) + topbar = False; else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } @@ -704,25 +722,11 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) { if(++i < argc) selfg = argv[i]; } - else if(!strcmp(argv[i], "-x")) { - if(++i < argc) x = atoi(argv[i]); - } - else if(!strcmp(argv[i], "-y")) { - if(++i < argc) - if(!strcmp(argv[i], "-0")) - y = INT_MIN; - else - y = atoi(argv[i]); - } - else if(!strcmp(argv[i], "-w")) { - if(++i < argc) w = atoi(argv[i]); - } else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); else - eprint("usage: dmenu [-i] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>]\n" - " [-x <x>] [-y <y>] [-w <w>] [-v]\n"); + eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" + " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); setlocale(LC_CTYPE, ""); dpy = XOpenDisplay(0); if(!dpy) @@ -739,7 +743,7 @@ main(int argc, char *argv[]) { readstdin(); } - setup(x, y, w); + setup(topbar); drawmenu(); XSync(dpy, False); run(); From 48193a560101bb8b7f4aec38d27b195f5d9bb4b4 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 20 May 2008 15:07:42 +0100 Subject: [PATCH 256/590] foo --- dmenubar/dmenu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0faa02e..4d23d9d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -728,8 +728,7 @@ main(int argc, char *argv[]) { eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); setlocale(LC_CTYPE, ""); - dpy = XOpenDisplay(0); - if(!dpy) + if(!(dpy = XOpenDisplay(0))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); From 41a1e115dc477c5938695859b65640e8a223bd52 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 22 May 2008 11:15:11 +0100 Subject: [PATCH 257/590] s/unsigned int/uint/, s/unsigned long/ulong/ --- dmenubar/dmenu.c | 52 +++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 4d23d9d..849746c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -20,10 +20,12 @@ enum { ColFG, ColBG, ColLast }; /* typedefs */ +typedef unsigned int uint; +typedef unsigned long ulong; typedef struct { int x, y, w, h; - unsigned long norm[ColLast]; - unsigned long sel[ColLast]; + ulong norm[ColLast]; + ulong sel[ColLast]; Drawable drawable; GC gc; struct { @@ -48,11 +50,11 @@ void calcoffsets(void); char *cistrstr(const char *s, const char *sub); void cleanup(void); void drawmenu(void); -void drawtext(const char *text, unsigned long col[ColLast]); -void *emalloc(unsigned int size); +void drawtext(const char *text, ulong col[ColLast]); +void *emalloc(uint size); void eprint(const char *errstr, ...); char *estrdup(const char *str); -unsigned long getcolor(const char *colstr); +ulong getcolor(const char *colstr); Bool grabkeyboard(void); void initfont(const char *fontstr); void kpress(XKeyEvent * e); @@ -60,8 +62,8 @@ void match(char *pattern); void readstdin(void); void run(void); void setup(Bool topbar); -unsigned int textnw(const char *text, unsigned int len); -unsigned int textw(const char *text); +uint textnw(const char *text, uint len); +uint textw(const char *text); #include "config.h" @@ -76,10 +78,10 @@ char *selfg = SELFGCOLOR; char text[4096]; int screen; int ret = 0; -unsigned int cmdw = 0; -unsigned int mw, mh; -unsigned int promptw = 0; -unsigned int numlockmask = 0; +uint cmdw = 0; +uint mw, mh; +uint promptw = 0; +uint numlockmask = 0; Bool running = True; Display *dpy; DC dc = {0}; @@ -106,7 +108,7 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsets(void) { - unsigned int tw, w; + uint tw, w; if(!curr) return; @@ -133,7 +135,7 @@ calcoffsets(void) { char * cistrstr(const char *s, const char *sub) { int c, csub; - unsigned int len; + uint len; if(!sub) return (char *)s; @@ -215,10 +217,10 @@ drawmenu(void) { } void -drawtext(const char *text, unsigned long col[ColLast]) { +drawtext(const char *text, ulong col[ColLast]) { int x, y, w, h; static char buf[256]; - unsigned int len, olen; + uint len, olen; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); @@ -255,7 +257,7 @@ drawtext(const char *text, unsigned long col[ColLast]) { } void * -emalloc(unsigned int size) { +emalloc(uint size) { void *res = malloc(size); if(!res) @@ -282,7 +284,7 @@ estrdup(const char *str) { return res; } -unsigned long +ulong getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -294,7 +296,7 @@ getcolor(const char *colstr) { Bool grabkeyboard(void) { - unsigned int len; + uint len; for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) @@ -350,7 +352,7 @@ void kpress(XKeyEvent * e) { char buf[32]; int i, num; - unsigned int len; + uint len; KeySym ksym; len = strlen(text); @@ -517,7 +519,7 @@ kpress(XKeyEvent * e) { void match(char *pattern) { - unsigned int plen; + uint plen; Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; if(!pattern) @@ -559,7 +561,7 @@ match(char *pattern) { void readstdin(void) { char *p, buf[1024]; - unsigned int len = 0, max = 0; + uint len = 0, max = 0; Item *i, *new; i = 0; @@ -675,8 +677,8 @@ setup(Bool topbar) { XMapRaised(dpy, win); } -unsigned int -textnw(const char *text, unsigned int len) { +uint +textnw(const char *text, uint len) { XRectangle r; if(dc.font.set) { @@ -686,14 +688,14 @@ textnw(const char *text, unsigned int len) { return XTextWidth(dc.font.xfont, text, len); } -unsigned int +uint textw(const char *text) { return textnw(text, strlen(text)) + dc.font.height; } int main(int argc, char *argv[]) { - unsigned int i; + uint i; Bool topbar = True; /* command line args */ From ce0927e93f23f98c9e55ae8ade3e1cb2d0c667b1 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Fri, 13 Jun 2008 11:46:50 +0100 Subject: [PATCH 258/590] cosmetic fixes --- dmenubar/LICENSE | 18 +++---- dmenubar/config.h | 4 +- dmenubar/config.mk | 4 +- dmenubar/dmenu.c | 130 +++++++++++++++++++++------------------------ 4 files changed, 74 insertions(+), 82 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 8e87c0f..8f13918 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -8,16 +8,16 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dmenubar/config.h b/dmenubar/config.h index 1afae6f..73cfe00 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -6,5 +6,5 @@ #define NORMFGCOLOR "#000000" #define SELBGCOLOR "#0066ff" #define SELFGCOLOR "#ffffff" -/* next macro defines the space between menu items */ -#define SPACE 30 /* px */ + +static uint spaceitem = 30; /* px between menu items */ diff --git a/dmenubar/config.mk b/dmenubar/config.mk index c3ed11b..556086f 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -20,10 +20,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -Os ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = -g ${LIBS} # Solaris #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 849746c..0f728c2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -2,13 +2,14 @@ #include <ctype.h> #include <locale.h> #include <stdarg.h> -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <strings.h> #include <unistd.h> +#include <X11/keysym.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#include <X11/keysym.h> #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif @@ -45,55 +46,54 @@ struct Item { }; /* forward declarations */ -void appenditem(Item *i, Item **list, Item **last); -void calcoffsets(void); -char *cistrstr(const char *s, const char *sub); -void cleanup(void); -void drawmenu(void); -void drawtext(const char *text, ulong col[ColLast]); -void *emalloc(uint size); -void eprint(const char *errstr, ...); -char *estrdup(const char *str); -ulong getcolor(const char *colstr); -Bool grabkeyboard(void); -void initfont(const char *fontstr); -void kpress(XKeyEvent * e); -void match(char *pattern); -void readstdin(void); -void run(void); -void setup(Bool topbar); -uint textnw(const char *text, uint len); -uint textw(const char *text); +static void appenditem(Item *i, Item **list, Item **last); +static void calcoffsets(void); +static char *cistrstr(const char *s, const char *sub); +static void cleanup(void); +static void drawmenu(void); +static void drawtext(const char *text, ulong col[ColLast]); +static void *emalloc(uint size); +static void eprint(const char *errstr, ...); +static ulong getcolor(const char *colstr); +static Bool grabkeyboard(void); +static void initfont(const char *fontstr); +static void kpress(XKeyEvent * e); +static void match(char *pattern); +static void readstdin(void); +static void run(void); +static void setup(Bool topbar); +static int textnw(const char *text, uint len); +static int textw(const char *text); #include "config.h" /* variables */ -char *font = FONT; -char *maxname = NULL; -char *normbg = NORMBGCOLOR; -char *normfg = NORMFGCOLOR; -char *prompt = NULL; -char *selbg = SELBGCOLOR; -char *selfg = SELFGCOLOR; -char text[4096]; -int screen; -int ret = 0; -uint cmdw = 0; -uint mw, mh; -uint promptw = 0; -uint numlockmask = 0; -Bool running = True; -Display *dpy; -DC dc = {0}; -Item *allitems = NULL; /* first of all items */ -Item *item = NULL; /* first of pattern matching items */ -Item *sel = NULL; -Item *next = NULL; -Item *prev = NULL; -Item *curr = NULL; -Window root, win; -int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; -char *(*fstrstr)(const char *, const char *) = strstr; +static char *font = FONT; +static char *maxname = NULL; +static char *normbg = NORMBGCOLOR; +static char *normfg = NORMFGCOLOR; +static char *prompt = NULL; +static char *selbg = SELBGCOLOR; +static char *selfg = SELFGCOLOR; +static char text[4096]; +static int cmdw = 0; +static int promptw = 0; +static int ret = 0; +static int screen; +static uint mw, mh; +static uint numlockmask = 0; +static Bool running = True; +static Display *dpy; +static DC dc = {0}; +static Item *allitems = NULL; /* first of all items */ +static Item *item = NULL; /* first of pattern matching items */ +static Item *sel = NULL; +static Item *next = NULL; +static Item *prev = NULL; +static Item *curr = NULL; +static Window root, win; +static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; void appenditem(Item *i, Item **list, Item **last) { @@ -108,11 +108,12 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsets(void) { - uint tw, w; + int tw; + uint w; if(!curr) return; - w = promptw + cmdw + 2 * SPACE; + w = promptw + cmdw + 2 * spaceitem; for(next = curr; next; next=next->right) { tw = textw(next->text); if(tw > mw / 3) @@ -121,7 +122,7 @@ calcoffsets(void) { if(w > mw) break; } - w = promptw + cmdw + 2 * SPACE; + w = promptw + cmdw + 2 * spaceitem; for(prev = curr; prev && prev->left; prev=prev->left) { tw = textw(prev->left->text); if(tw > mw / 3) @@ -197,7 +198,7 @@ drawmenu(void) { drawtext(text[0] ? text : NULL, dc.norm); dc.x += cmdw; if(curr) { - dc.w = SPACE; + dc.w = spaceitem; drawtext((curr && curr->left) ? "<" : NULL, dc.norm); dc.x += dc.w; /* determine maximum items */ @@ -208,8 +209,8 @@ drawmenu(void) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } - dc.x = mw - SPACE; - dc.w = SPACE; + dc.x = mw - spaceitem; + dc.w = spaceitem; drawtext(next ? ">" : NULL, dc.norm); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); @@ -275,15 +276,6 @@ eprint(const char *errstr, ...) { exit(EXIT_FAILURE); } -char * -estrdup(const char *str) { - void *res = strdup(str); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", strlen(str)); - return res; -} - ulong getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); @@ -358,14 +350,15 @@ kpress(XKeyEvent * e) { len = strlen(text); buf[0] = 0; num = XLookupString(e, buf, sizeof buf, &ksym, 0); - if(IsKeypadKey(ksym)) + if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; + } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) - || IsPrivateKeypadKey(ksym)) + || IsMiscFunctionKey(ksym) || IsPFKey(ksym) + || IsPrivateKeypadKey(ksym)) return; /* first check if a control mask is omitted */ if(e->state & ControlMask) { @@ -569,7 +562,8 @@ readstdin(void) { len = strlen(buf); if (buf[len - 1] == '\n') buf[len - 1] = 0; - p = estrdup(buf); + if(!(p = strdup(buf))) + eprint("fatal: could not strdup() %u bytes\n", strlen(buf)); if(max < len) { maxname = p; max = len; @@ -677,7 +671,7 @@ setup(Bool topbar) { XMapRaised(dpy, win); } -uint +int textnw(const char *text, uint len) { XRectangle r; @@ -688,7 +682,7 @@ textnw(const char *text, uint len) { return XTextWidth(dc.font.xfont, text, len); } -uint +int textw(const char *text) { return textnw(text, strlen(text)) + dc.font.height; } From c3806d426ff3ac938f78d4db0ac79b94d690ed6c Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Fri, 13 Jun 2008 11:53:53 +0100 Subject: [PATCH 259/590] yet another cosmetic change --- dmenubar/config.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 73cfe00..43d3a53 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -1,10 +1,14 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -#define FONT "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*" -#define NORMBGCOLOR "#cccccc" -#define NORMFGCOLOR "#000000" -#define SELBGCOLOR "#0066ff" -#define SELFGCOLOR "#ffffff" +#define FONT "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*" +#define NORMBGCOLOR "#cccccc" +#define NORMFGCOLOR "#000000" +#define SELBGCOLOR "#0066ff" +#define SELFGCOLOR "#ffffff" -static uint spaceitem = 30; /* px between menu items */ +static uint spaceitem = 30; /* px between menu items */ + +#ifdef XINERAMA +static uint xidx = 0; /* Xinerama screen index to use */ +#endif From 09dd6c70bd7163496c5c248d4c024ca5a5e09bff Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Fri, 13 Jun 2008 12:04:04 +0100 Subject: [PATCH 260/590] using xidx --- dmenubar/dmenu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0f728c2..a37471a 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -634,9 +634,9 @@ setup(Bool topbar) { #if XINERAMA if(XineramaIsActive(dpy)) { info = XineramaQueryScreens(dpy, &i); - x = info[0].x_org; - y = topbar ? info[0].y_org : info[0].y_org + info[0].height - mh; - mw = info[0].width; + x = info[xidx].x_org; + y = topbar ? info[xidx].y_org : info[xidx].y_org + info[xidx].height - mh; + mw = info[xidx].width; XFree(info); } else From 9f1970ff22ee3470b7258e0b5000a07494cc4283 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Sat, 14 Jun 2008 10:55:13 +0100 Subject: [PATCH 261/590] reusing config.h's color values, note we have to use const char *, instead of const char [] here, because the pointer might change --- dmenubar/config.h | 14 +++++++------- dmenubar/dmenu.c | 21 ++++++++------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 43d3a53..5af4304 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -1,14 +1,14 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -#define FONT "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*" -#define NORMBGCOLOR "#cccccc" -#define NORMFGCOLOR "#000000" -#define SELBGCOLOR "#0066ff" -#define SELFGCOLOR "#ffffff" +static const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; +static const char *normbgcolor = "#cccccc"; +static const char *normfgcolor = "#000000"; +static const char *selbgcolor = "#0066ff"; +static const char *selfgcolor = "#ffffff"; -static uint spaceitem = 30; /* px between menu items */ +static uint spaceitem = 30; /* px between menu items */ #ifdef XINERAMA -static uint xidx = 0; /* Xinerama screen index to use */ +static uint xidx = 0; /* Xinerama screen index to use */ #endif diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a37471a..2afcc48 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -68,13 +68,8 @@ static int textw(const char *text); #include "config.h" /* variables */ -static char *font = FONT; static char *maxname = NULL; -static char *normbg = NORMBGCOLOR; -static char *normfg = NORMFGCOLOR; static char *prompt = NULL; -static char *selbg = SELBGCOLOR; -static char *selfg = SELFGCOLOR; static char text[4096]; static int cmdw = 0; static int promptw = 0; @@ -618,10 +613,10 @@ setup(Bool topbar) { XFreeModifiermap(modmap); /* style */ - dc.norm[ColBG] = getcolor(normbg); - dc.norm[ColFG] = getcolor(normfg); - dc.sel[ColBG] = getcolor(selbg); - dc.sel[ColFG] = getcolor(selfg); + dc.norm[ColBG] = getcolor(normbgcolor); + dc.norm[ColFG] = getcolor(normfgcolor); + dc.sel[ColBG] = getcolor(selbgcolor); + dc.sel[ColFG] = getcolor(selfgcolor); initfont(font); /* menu window */ @@ -704,19 +699,19 @@ main(int argc, char *argv[]) { if(++i < argc) font = argv[i]; } else if(!strcmp(argv[i], "-nb")) { - if(++i < argc) normbg = argv[i]; + if(++i < argc) normbgcolor = argv[i]; } else if(!strcmp(argv[i], "-nf")) { - if(++i < argc) normfg = argv[i]; + if(++i < argc) normfgcolor = argv[i]; } else if(!strcmp(argv[i], "-p")) { if(++i < argc) prompt = argv[i]; } else if(!strcmp(argv[i], "-sb")) { - if(++i < argc) selbg = argv[i]; + if(++i < argc) selbgcolor = argv[i]; } else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfg = argv[i]; + if(++i < argc) selfgcolor = argv[i]; } else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); From 82562d61ff3befd30fd2aae29d0648b0d58bab69 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 18 Jun 2008 18:20:21 +0100 Subject: [PATCH 262/590] minor fix --- dmenubar/config.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 556086f..557f48c 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -26,7 +26,6 @@ LDFLAGS = -s ${LIBS} # Solaris #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" #LDFLAGS = ${LIBS} -#CFLAGS += -xtarget=ultra # compiler and linker CC = cc From 3aa94bbc7d24a69ec3fde026c5b18f29dc4377ff Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 18 Jun 2008 18:21:45 +0100 Subject: [PATCH 263/590] Added tag 3.7 for changeset 0508a3a6ee10 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 121a20f..72e0915 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -36,3 +36,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 9ab649b3b3e5bfccf1c8f352c59e5361e070a25f 3.4 05e5bd706b3b3e61399d57c4bb43df296a20112d 3.5 0bc2751d06e8b95e0138854c7815e154c5c3d990 3.6 +0508a3a6ee106f36d9b8ff07bb5b28584edfa89c 3.7 From faa881ba49b64ce62a06fc469125bfdc3c312029 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 19 Jun 2008 09:18:17 +0100 Subject: [PATCH 264/590] minor fix --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 557f48c..9206a44 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.7 +VERSION = 3.8 # Customize below to fit your system diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2afcc48..bf74edb 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -477,11 +477,11 @@ kpress(XKeyEvent * e) { calcoffsets(); break; case XK_Return: - if((e->state & ShiftMask) && text) + if((e->state & ShiftMask) && *text) fprintf(stdout, "%s", text); else if(sel) fprintf(stdout, "%s", sel->text); - else if(text) + else if(*text) fprintf(stdout, "%s", text); fflush(stdout); running = False; From 05f455d197ec92fc2ed569ea8446b1595d20ae8b Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Sat, 21 Jun 2008 16:43:12 +0100 Subject: [PATCH 265/590] removed emalloc, used only once so obsolete --- dmenubar/dmenu.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index bf74edb..fa7bbe8 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -52,7 +52,6 @@ static char *cistrstr(const char *s, const char *sub); static void cleanup(void); static void drawmenu(void); static void drawtext(const char *text, ulong col[ColLast]); -static void *emalloc(uint size); static void eprint(const char *errstr, ...); static ulong getcolor(const char *colstr); static Bool grabkeyboard(void); @@ -252,15 +251,6 @@ drawtext(const char *text, ulong col[ColLast]) { XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); } -void * -emalloc(uint size) { - void *res = malloc(size); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", size); - return res; -} - void eprint(const char *errstr, ...) { va_list ap; @@ -563,7 +553,8 @@ readstdin(void) { maxname = p; max = len; } - new = emalloc(sizeof(Item)); + if((new = (Item *)malloc(sizeof(Item))) == NULL) + eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); new->next = new->left = new->right = NULL; new->text = p; if(!i) From fb73f3dafcfde75e6dd434cfc2e1cde8290fbbed Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 30 Jun 2008 10:00:00 +0100 Subject: [PATCH 266/590] minor update regarding locale support --- dmenubar/dmenu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fa7bbe8..afb5303 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#define _BSD_SOURCE #include <ctype.h> #include <locale.h> #include <stdarg.h> @@ -709,7 +710,8 @@ main(int argc, char *argv[]) { else eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); - setlocale(LC_CTYPE, ""); + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(0))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); From df33f5f989aba85d8fcbc3591e415bf2c622f1e0 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 16 Jul 2008 18:18:38 +0100 Subject: [PATCH 267/590] reverted uint/ulong introduction --- dmenubar/config.h | 4 ++-- dmenubar/dmenu.c | 38 ++++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index 5af4304..a2c3fa4 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -7,8 +7,8 @@ static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; -static uint spaceitem = 30; /* px between menu items */ +static unsigned int spaceitem = 30; /* px between menu items */ #ifdef XINERAMA -static uint xidx = 0; /* Xinerama screen index to use */ +static unsigned int xidx = 0; /* Xinerama screen index to use */ #endif diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index afb5303..33b1a89 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -22,12 +22,10 @@ enum { ColFG, ColBG, ColLast }; /* typedefs */ -typedef unsigned int uint; -typedef unsigned long ulong; typedef struct { int x, y, w, h; - ulong norm[ColLast]; - ulong sel[ColLast]; + unsigned long norm[ColLast]; + unsigned long sel[ColLast]; Drawable drawable; GC gc; struct { @@ -52,9 +50,9 @@ static void calcoffsets(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); static void drawmenu(void); -static void drawtext(const char *text, ulong col[ColLast]); +static void drawtext(const char *text, unsigned long col[ColLast]); static void eprint(const char *errstr, ...); -static ulong getcolor(const char *colstr); +static unsigned long getcolor(const char *colstr); static Bool grabkeyboard(void); static void initfont(const char *fontstr); static void kpress(XKeyEvent * e); @@ -62,7 +60,7 @@ static void match(char *pattern); static void readstdin(void); static void run(void); static void setup(Bool topbar); -static int textnw(const char *text, uint len); +static int textnw(const char *text, unsigned int len); static int textw(const char *text); #include "config.h" @@ -75,8 +73,8 @@ static int cmdw = 0; static int promptw = 0; static int ret = 0; static int screen; -static uint mw, mh; -static uint numlockmask = 0; +static unsigned int mw, mh; +static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; static DC dc = {0}; @@ -104,7 +102,7 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsets(void) { int tw; - uint w; + unsigned int w; if(!curr) return; @@ -131,7 +129,7 @@ calcoffsets(void) { char * cistrstr(const char *s, const char *sub) { int c, csub; - uint len; + unsigned int len; if(!sub) return (char *)s; @@ -213,10 +211,10 @@ drawmenu(void) { } void -drawtext(const char *text, ulong col[ColLast]) { +drawtext(const char *text, unsigned long col[ColLast]) { int x, y, w, h; static char buf[256]; - uint len, olen; + unsigned int len, olen; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); @@ -262,7 +260,7 @@ eprint(const char *errstr, ...) { exit(EXIT_FAILURE); } -ulong +unsigned long getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -274,7 +272,7 @@ getcolor(const char *colstr) { Bool grabkeyboard(void) { - uint len; + unsigned int len; for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) @@ -330,7 +328,7 @@ void kpress(XKeyEvent * e) { char buf[32]; int i, num; - uint len; + unsigned int len; KeySym ksym; len = strlen(text); @@ -498,7 +496,7 @@ kpress(XKeyEvent * e) { void match(char *pattern) { - uint plen; + unsigned int plen; Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; if(!pattern) @@ -540,7 +538,7 @@ match(char *pattern) { void readstdin(void) { char *p, buf[1024]; - uint len = 0, max = 0; + unsigned int len = 0, max = 0; Item *i, *new; i = 0; @@ -659,7 +657,7 @@ setup(Bool topbar) { } int -textnw(const char *text, uint len) { +textnw(const char *text, unsigned int len) { XRectangle r; if(dc.font.set) { @@ -676,7 +674,7 @@ textw(const char *text) { int main(int argc, char *argv[]) { - uint i; + unsigned int i; Bool topbar = True; /* command line args */ From 333dfdd1e1271537ca8d00e97308883d0e1c1508 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 16 Jul 2008 18:38:53 +0100 Subject: [PATCH 268/590] got rid of compile time xidx, grabbing the mouse pointer instead, falling back to screen 0 if no pointer available --- dmenubar/config.h | 5 ----- dmenubar/dmenu.c | 23 +++++++++++++++++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/dmenubar/config.h b/dmenubar/config.h index a2c3fa4..3e6c616 100644 --- a/dmenubar/config.h +++ b/dmenubar/config.h @@ -6,9 +6,4 @@ static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; - static unsigned int spaceitem = 30; /* px between menu items */ - -#ifdef XINERAMA -static unsigned int xidx = 0; /* Xinerama screen index to use */ -#endif diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 33b1a89..e487333 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -16,7 +16,8 @@ #endif /* macros */ -#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) /* enums */ enum { ColFG, ColBG, ColLast }; @@ -585,7 +586,7 @@ run(void) { void setup(Bool topbar) { - int i, j, x, y; + int i, j, n, x, y; XModifierKeymap *modmap; XSetWindowAttributes wa; #if XINERAMA @@ -618,10 +619,20 @@ setup(Bool topbar) { mh = dc.font.height + 2; #if XINERAMA if(XineramaIsActive(dpy)) { - info = XineramaQueryScreens(dpy, &i); - x = info[xidx].x_org; - y = topbar ? info[xidx].y_org : info[xidx].y_org + info[xidx].height - mh; - mw = info[xidx].width; + i = 0; + info = XineramaQueryScreens(dpy, &n); + if(n > 1) { + int di; + unsigned int dui; + Window dummy; + if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) + for(i = 0; i < n; i++) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + break; + } + x = info[i].x_org; + y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; + mw = info[i].width; XFree(info); } else From d63e517ddbb54dd9f36652a9ecf2ae31d8ab70f1 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Thu, 17 Jul 2008 17:40:42 +0100 Subject: [PATCH 269/590] removed compiler warning if XINERAMA is disabled --- dmenubar/dmenu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index e487333..863a262 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -586,7 +586,7 @@ run(void) { void setup(Bool topbar) { - int i, j, n, x, y; + int i, j, x, y; XModifierKeymap *modmap; XSetWindowAttributes wa; #if XINERAMA @@ -619,6 +619,7 @@ setup(Bool topbar) { mh = dc.font.height + 2; #if XINERAMA if(XineramaIsActive(dpy)) { + int n; i = 0; info = XineramaQueryScreens(dpy, &n); if(n > 1) { From e3e937cb043b9956008a357a3ace781af889f517 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Fri, 18 Jul 2008 20:20:19 +0100 Subject: [PATCH 270/590] similiar change as in dwm --- dmenubar/dmenu.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 863a262..1206e95 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -587,11 +587,12 @@ run(void) { void setup(Bool topbar) { int i, j, x, y; - XModifierKeymap *modmap; - XSetWindowAttributes wa; #if XINERAMA + int n; XineramaScreenInfo *info = NULL; #endif + XModifierKeymap *modmap; + XSetWindowAttributes wa; /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -618,10 +619,8 @@ setup(Bool topbar) { /* menu window geometry */ mh = dc.font.height + 2; #if XINERAMA - if(XineramaIsActive(dpy)) { - int n; + if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; - info = XineramaQueryScreens(dpy, &n); if(n > 1) { int di; unsigned int dui; From f800e4c80e4df75087a6416dc460ed5734b1c350 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 29 Jul 2008 19:20:53 +0100 Subject: [PATCH 271/590] Added tag 3.8 for changeset 644b0798fccc --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 72e0915..db5c86f 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -37,3 +37,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 05e5bd706b3b3e61399d57c4bb43df296a20112d 3.5 0bc2751d06e8b95e0138854c7815e154c5c3d990 3.6 0508a3a6ee106f36d9b8ff07bb5b28584edfa89c 3.7 +644b0798fcccd570fd519899e1601c6857496b91 3.8 From 733bc3923af81ba15aaf06e0c58747857fc1be8f Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 18 Aug 2008 09:31:01 +0100 Subject: [PATCH 272/590] getting rid of setlocale(), it doesn't seem to make sense with Xmb, artifact of Xutf8 times --- dmenubar/dmenu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1206e95..895bdc5 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,7 +1,6 @@ /* See LICENSE file for copyright and license details. */ #define _BSD_SOURCE #include <ctype.h> -#include <locale.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -719,7 +718,7 @@ main(int argc, char *argv[]) { else eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + if(!XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(0))) eprint("dmenu: cannot open display\n"); From 5a254229e17059a2094669ae3d73bcfbec27b597 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 18 Aug 2008 10:03:28 +0100 Subject: [PATCH 273/590] backported drawtext() simplifications to dmenu --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 31 ++++++++++--------------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 9206a44..bd1ee6b 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.8 +VERSION = 3.9 # Customize below to fit your system diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 895bdc5..a9c0f60 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -17,6 +17,7 @@ /* macros */ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) /* enums */ enum { ColFG, ColBG, ColLast }; @@ -212,37 +213,25 @@ drawmenu(void) { void drawtext(const char *text, unsigned long col[ColLast]) { - int x, y, w, h; - static char buf[256]; - unsigned int len, olen; + int i, x, y, h, len, olen; + char buf[256]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); if(!text) return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; + olen = strlen(text); h = dc.font.ascent + dc.font.descent; y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ + for(len = MIN(olen, sizeof buf); len && (i = textnw(buf, len)) > dc.w - h; len--); + if(!len) + return; + memcpy(buf, text, len); + if(len < olen) + for(i = len; i && i > len - 3; buf[--i] = '.'); XSetForeground(dpy, dc.gc, col[ColFG]); if(dc.font.set) XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); From 3e7f0d7dcea5778b6a2b2174576ee8daccc7df5b Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 18 Aug 2008 10:17:15 +0100 Subject: [PATCH 274/590] removed the i = textnw... as remarked by Martin Hurton --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a9c0f60..a799f14 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -226,7 +226,7 @@ drawtext(const char *text, unsigned long col[ColLast]) { y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && (i = textnw(buf, len)) > dc.w - h; len--); + for(len = MIN(olen, sizeof buf); len && textnw(buf, len) > dc.w - h; len--); if(!len) return; memcpy(buf, text, len); From fa4421968c1dbd78e032ebaea83911feeed9fcb7 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 18 Aug 2008 10:20:53 +0100 Subject: [PATCH 275/590] abc... --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a799f14..d67c1ae 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -213,8 +213,8 @@ drawmenu(void) { void drawtext(const char *text, unsigned long col[ColLast]) { - int i, x, y, h, len, olen; char buf[256]; + int i, x, y, h, len, olen; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); From 47748a5922c6995e8bc945169b58f5b80371d2c6 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 18 Aug 2008 19:24:29 +0100 Subject: [PATCH 276/590] fixed a problem when backporting dwm's drawtext() --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d67c1ae..463f929 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -226,7 +226,7 @@ drawtext(const char *text, unsigned long col[ColLast]) { y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(buf, len) > dc.w - h; len--); + for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); if(!len) return; memcpy(buf, text, len); From 48bb4e9e57586ed367b0ea993edeaf364d139664 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Sat, 23 Aug 2008 09:33:56 +0100 Subject: [PATCH 277/590] removed artifact from wmii menu --- dmenubar/dmenu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 463f929..d0c63db 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -280,8 +280,6 @@ initfont(const char *fontstr) { if(!fontstr || fontstr[0] == '\0') eprint("error, cannot load font: '%s'\n", fontstr); missing = NULL; - if(dc.font.set) - XFreeFontSet(dpy, dc.font.set); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); From 3d976301a6f27b5c698b4f9a925fd03745b2b6f1 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Mon, 25 Aug 2008 09:38:19 +0100 Subject: [PATCH 278/590] reverted setlocale() call --- dmenubar/dmenu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d0c63db..18f2a56 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #define _BSD_SOURCE #include <ctype.h> +#include <locale.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -705,7 +706,7 @@ main(int argc, char *argv[]) { else eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); - if(!XSupportsLocale()) + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(0))) eprint("dmenu: cannot open display\n"); From da7189a08769e754e2535812c08652fa6965e8d3 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Fri, 29 Aug 2008 10:09:40 +0100 Subject: [PATCH 279/590] simplified initfont --- dmenubar/dmenu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 18f2a56..c0addad 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -79,7 +79,7 @@ static unsigned int mw, mh; static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; -static DC dc = {0}; +static DC dc; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; @@ -300,9 +300,6 @@ initfont(const char *fontstr) { } } else { - if(dc.font.xfont) - XFreeFont(dpy, dc.font.xfont); - dc.font.xfont = NULL; if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) eprint("error, cannot load font: '%s'\n", fontstr); From 97fe63d8eda76d287249258d7c22228accab35ba Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Tue, 9 Sep 2008 20:45:07 +0100 Subject: [PATCH 280/590] Added tag 3.9 for changeset 21a1ed9a69b9 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index db5c86f..bb50a55 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -38,3 +38,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 0bc2751d06e8b95e0138854c7815e154c5c3d990 3.6 0508a3a6ee106f36d9b8ff07bb5b28584edfa89c 3.7 644b0798fcccd570fd519899e1601c6857496b91 3.8 +21a1ed9a69b9541a355758a57103e294fb722c33 3.9 From 8033eaa3d00c79b84523e099ec4c09c0d389353f Mon Sep 17 00:00:00 2001 From: "a@null" <unknown> Date: Tue, 9 Dec 2008 21:55:47 +0000 Subject: [PATCH 281/590] minor modification --- dmenubar/dmenu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c0addad..44b4254 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -396,10 +396,7 @@ kpress(XKeyEvent * e) { default: if(num && !iscntrl((int) buf[0])) { buf[num] = 0; - if(len > 0) - strncat(text, buf, sizeof text); - else - strncpy(text, buf, sizeof text); + strncpy(text + len, buf, sizeof text - len); match(text); } break; From 88592a9e9fb540db5cda1d4db99a638f4299029a Mon Sep 17 00:00:00 2001 From: "a@null" <unknown> Date: Fri, 12 Dec 2008 19:58:52 +0000 Subject: [PATCH 282/590] next release will be 4.0 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index bd1ee6b..f85e0fc 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 3.9 +VERSION = 4.0 # Customize below to fit your system From 8940a4ec26fa3d41ce48aa6a8b33e6e6e75e320a Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Sat, 21 Feb 2009 19:21:54 +0000 Subject: [PATCH 283/590] applied Matthias Christian Ott's sanity fixes (thanks a lot!) --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index f85e0fc..f6a3652 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -19,7 +19,7 @@ INCS = -I. -I/usr/include -I${X11INC} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 44b4254..0f95af6 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,5 +1,4 @@ /* See LICENSE file for copyright and license details. */ -#define _BSD_SOURCE #include <ctype.h> #include <locale.h> #include <stdarg.h> @@ -141,7 +140,7 @@ cistrstr(const char *s, const char *sub) { do { do { if((csub = *s++) == 0) - return (NULL); + return NULL; } while(tolower(csub) != c); } @@ -318,7 +317,7 @@ kpress(XKeyEvent * e) { len = strlen(text); buf[0] = 0; - num = XLookupString(e, buf, sizeof buf, &ksym, 0); + num = XLookupString(e, buf, sizeof buf, &ksym, NULL); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; @@ -534,7 +533,7 @@ readstdin(void) { maxname = p; max = len; } - if((new = (Item *)malloc(sizeof(Item))) == NULL) + if(!(new = (Item *)malloc(sizeof(Item)))) eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); new->next = new->left = new->right = NULL; new->text = p; @@ -593,7 +592,7 @@ setup(Bool topbar) { initfont(font); /* menu window */ - wa.override_redirect = 1; + wa.override_redirect = True; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; @@ -631,7 +630,7 @@ setup(Bool topbar) { /* pixmap */ dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, 0); + dc.gc = XCreateGC(dpy, root, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); @@ -702,7 +701,7 @@ main(int argc, char *argv[]) { " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(0))) + if(!(dpy = XOpenDisplay(NULL))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); From 0e96e1d07b53100258cb7802311903fed0e83822 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Sat, 18 Apr 2009 12:50:12 +0100 Subject: [PATCH 284/590] Added tag 4.0 for changeset 78f9f72cc9c6 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index bb50a55..b1e6acb 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -39,3 +39,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 0508a3a6ee106f36d9b8ff07bb5b28584edfa89c 3.7 644b0798fcccd570fd519899e1601c6857496b91 3.8 21a1ed9a69b9541a355758a57103e294fb722c33 3.9 +78f9f72cc9c6bdb022ff8908486b61ef5e242aad 4.0 From 0ec702fcc91f573a07adf6df21d554eecb621a38 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 28 Nov 2009 12:28:15 +0000 Subject: [PATCH 285/590] applied cursor, vertical and paste patches for upcoming 4.1 dmenu version (due to the fact that surf is using dmenu as well) --- dmenubar/LICENSE | 5 +- dmenubar/config.mk | 2 +- dmenubar/dmenu.1 | 7 +- dmenubar/dmenu.c | 163 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 149 insertions(+), 28 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 8f13918..1f2db9b 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,6 +1,9 @@ MIT/X Consortium License -© 2006-2008 Anselm R. Garbe <garbeam at gmail dot com> +© 2006-2009 Anselm R. Garbe <anselm@garbe.us> +© 2009 Gottox <gottox@s01.de> +© 2009 Markus Schnalke <meillo@marmaro.de> +© 2009 Evan Gates <evan.gates@gmail.com> © 2006-2008 Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2006-2007 Michał Janeczek <janeczek at gmail dot com> diff --git a/dmenubar/config.mk b/dmenubar/config.mk index f6a3652..75c6abe 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.0 +VERSION = 4.1 # Customize below to fit your system diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index a072883..24ee38b 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -5,6 +5,7 @@ dmenu \- dynamic menu .B dmenu .RB [ \-i ] .RB [ \-b ] +.RB [ \-l " <lines>"] .RB [ \-fn " <font>"] .RB [ \-nb " <color>"] .RB [ \-nf " <color>"] @@ -26,6 +27,10 @@ makes dmenu match menu entries case insensitively. .B \-b defines that dmenu appears at the bottom. .TP +.B \-l <lines> +activates vertical list mode. +The given number of lines will be displayed. Window height will get adjusted. +.TP .B \-fn <font> defines the font. .TP @@ -57,7 +62,7 @@ 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: only items containing this text will be displayed. .TP -.B Left/Right (Mod1\-h/Mod1\-l) +.B Left/Right (Up/Down) (Mod1\-h/Mod1\-l) Select the previous/next item. .TP .B PageUp/PageDown (Mod1\-k/Mod1\-j) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0f95af6..be9b41b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -18,6 +18,7 @@ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) /* enums */ enum { ColFG, ColBG, ColLast }; @@ -47,10 +48,12 @@ struct Item { /* forward declarations */ static void appenditem(Item *i, Item **list, Item **last); -static void calcoffsets(void); +static void calcoffsetsh(void); +static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); -static void drawmenu(void); +static void drawmenuh(void); +static void drawmenuv(void); static void drawtext(const char *text, unsigned long col[ColLast]); static void eprint(const char *errstr, ...); static unsigned long getcolor(const char *colstr); @@ -73,6 +76,7 @@ static char text[4096]; static int cmdw = 0; static int promptw = 0; static int ret = 0; +static int cursor = 0; static int screen; static unsigned int mw, mh; static unsigned int numlockmask = 0; @@ -88,6 +92,10 @@ static Item *curr = NULL; static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; +static Bool vlist = False; +static unsigned int lines = 5; +static void (*calcoffsets)(void) = calcoffsetsh; +static void (*drawmenu)(void) = drawmenuh; void appenditem(Item *i, Item **list, Item **last) { @@ -101,7 +109,7 @@ appenditem(Item *i, Item **list, Item **last) { } void -calcoffsets(void) { +calcoffsetsh(void) { int tw; unsigned int w; @@ -127,6 +135,26 @@ calcoffsets(void) { } } +void +calcoffsetsv(void) { + static unsigned int w; + + if(!curr) + return; + w = (dc.font.height + 2) * (lines + 1); + for(next = curr; next; next=next->right) { + w -= dc.font.height + 2; + if(w <= 0) + break; + } + w = (dc.font.height + 2) * (lines + 1); + for(prev = curr; prev && prev->left; prev=prev->left) { + w -= dc.font.height + 2; + if(w <= 0) + break; + } +} + char * cistrstr(const char *s, const char *sub) { int c, csub; @@ -171,7 +199,17 @@ cleanup(void) { } void -drawmenu(void) { +drawcursor(void) { + XRectangle r = { dc.x, dc.y + 2, 1, dc.h - 4 }; + + r.x += textnw(text, cursor) + dc.font.height / 2; + + XSetForeground(dpy, dc.gc, dc.norm[ColFG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); +} + +void +drawmenuh(void) { Item *i; dc.x = 0; @@ -190,6 +228,7 @@ drawmenu(void) { if(cmdw && item) dc.w = cmdw; drawtext(text[0] ? text : NULL, dc.norm); + drawcursor(); dc.x += cmdw; if(curr) { dc.w = spaceitem; @@ -211,6 +250,39 @@ drawmenu(void) { XFlush(dpy); } +void +drawmenuv(void) { + Item *i; + + dc.x = 0; + dc.y = 0; + dc.w = mw; + dc.h = mh; + drawtext(NULL, dc.norm); + /* print prompt? */ + if(promptw) { + dc.w = promptw; + drawtext(prompt, dc.sel); + } + dc.x += promptw; + dc.w = mw - promptw; + /* print command */ + drawtext(text[0] ? text : NULL, dc.norm); + if(curr) { + dc.x = 0; + dc.w = mw; + dc.y += dc.font.height + 2; + /* determine maximum items */ + for(i = curr; i != next; i=i->right) { + drawtext(i->text, (sel == i) ? dc.sel : dc.norm); + dc.y += dc.font.height + 2; + } + drawtext(NULL, dc.norm); + } + XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); + XFlush(dpy); +} + void drawtext(const char *text, unsigned long col[ColLast]) { char buf[256]; @@ -222,8 +294,8 @@ drawtext(const char *text, unsigned long col[ColLast]) { if(!text) return; olen = strlen(text); - h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; + h = dc.font.height; + y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); @@ -353,7 +425,7 @@ kpress(XKeyEvent * e) { text[0] = 0; match(text); drawmenu(); - return; + break; case XK_w: case XK_W: if(len) { @@ -365,7 +437,7 @@ kpress(XKeyEvent * e) { match(text); drawmenu(); } - return; + break; } } if(CLEANMASK(e->state) & Mod1Mask) { @@ -389,19 +461,39 @@ kpress(XKeyEvent * e) { case XK_G: ksym = XK_End; break; + case XK_p: + { + FILE *fp; + char *c; + if(!(fp = (FILE*)popen("sselp", "r"))) + fprintf(stderr, "dmenu: Could not popen sselp\n"); + c = fgets(text + len, sizeof(text) - len, fp); + pclose(fp); + if(c == NULL) + return; + } + len = strlen(text); + if(len && text[len-1] == '\n') + text[--len] = '\0'; + match(text); + drawmenu(); + return; } } switch(ksym) { default: if(num && !iscntrl((int) buf[0])) { buf[num] = 0; - strncpy(text + len, buf, sizeof text - len); + memmove(text + cursor + num, text + cursor, sizeof text - cursor); + strncpy(text + cursor, buf, sizeof text - cursor); + cursor+=num; match(text); } break; case XK_BackSpace: - if(len) { - text[--len] = 0; + if(cursor > 0) { + memmove(text + cursor + -1, text + cursor, sizeof text - cursor); + cursor--; match(text); } break; @@ -426,13 +518,18 @@ kpress(XKeyEvent * e) { calcoffsets(); break; case XK_Left: - if(!(sel && sel->left)) - return; - sel=sel->left; - if(sel->right == curr) { - curr = prev; - calcoffsets(); + case XK_Up: + if(sel && sel->left){ + sel=sel->left; + if(sel->right == curr) { + curr = prev; + calcoffsets(); + } } + else if(cursor > 0) + cursor--; + else + return; break; case XK_Next: if(!next) @@ -457,21 +554,30 @@ kpress(XKeyEvent * e) { running = False; break; case XK_Right: - if(!(sel && sel->right)) - return; - sel=sel->right; - if(sel == next) { - curr = next; - calcoffsets(); + case XK_Down: + if(cursor < len) + cursor++; + else if(sel && sel->right) { + sel=sel->right; + if(sel == next) { + curr = next; + calcoffsets(); + } } + else + return; break; case XK_Tab: if(!sel) return; strncpy(text, sel->text, sizeof text); + cursor = strlen(text); match(text); break; } + len = strlen(text); + cursor = MIN(cursor, len); + cursor = MAX(cursor, 0); drawmenu(); } @@ -598,6 +704,7 @@ setup(Bool topbar) { /* menu window geometry */ mh = dc.font.height + 2; + mh = vlist ? mh * (lines+1) : mh; #if XINERAMA if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; @@ -676,6 +783,12 @@ main(int argc, char *argv[]) { } else if(!strcmp(argv[i], "-b")) topbar = False; + else if(!strcmp(argv[i], "-l")) { + vlist = True; + calcoffsets = calcoffsetsv; + drawmenu = drawmenuv; + if(++i < argc) lines += atoi(argv[i]); + } else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } @@ -695,9 +808,9 @@ main(int argc, char *argv[]) { if(++i < argc) selfgcolor = argv[i]; } else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); + eprint("dmenu-"VERSION", © 2006-2009 dmenu engineers, see LICENSE for details\n"); else - eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" + eprint("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); From b9e8f899c98804b26e4c3a98d837a6a889694502 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 5 Dec 2009 16:52:53 +0000 Subject: [PATCH 286/590] this is only a temporary workaround, the command executed by -p must be configurable through some switch, that was the initial idea, just using sselp is too limited, I'll look into the other issues soon --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index be9b41b..1f7abca 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -466,7 +466,7 @@ kpress(XKeyEvent * e) { FILE *fp; char *c; if(!(fp = (FILE*)popen("sselp", "r"))) - fprintf(stderr, "dmenu: Could not popen sselp\n"); + eprint("dmenu: Could not popen sselp\n"); c = fgets(text + len, sizeof(text) - len, fp); pclose(fp); if(c == NULL) From b4d8e4cd1bfebea82487e54da9e07c58a0111e45 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sun, 7 Mar 2010 08:32:16 +0000 Subject: [PATCH 287/590] applied Connor's patch, thanks! --- dmenubar/dmenu.c | 77 +++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1f7abca..aef8ae5 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -52,6 +52,7 @@ static void calcoffsetsh(void); static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); +static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); static void drawtext(const char *text, unsigned long col[ColLast]); @@ -95,7 +96,6 @@ static char *(*fstrstr)(const char *, const char *) = strstr; static Bool vlist = False; static unsigned int lines = 5; static void (*calcoffsets)(void) = calcoffsetsh; -static void (*drawmenu)(void) = drawmenuh; void appenditem(Item *i, Item **list, Item **last) { @@ -200,7 +200,7 @@ cleanup(void) { void drawcursor(void) { - XRectangle r = { dc.x, dc.y + 2, 1, dc.h - 4 }; + XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; r.x += textnw(text, cursor) + dc.font.height / 2; @@ -209,9 +209,7 @@ drawcursor(void) { } void -drawmenuh(void) { - Item *i; - +drawmenu(void) { dc.x = 0; dc.y = 0; dc.w = mw; @@ -231,56 +229,48 @@ drawmenuh(void) { drawcursor(); dc.x += cmdw; if(curr) { - dc.w = spaceitem; - drawtext((curr && curr->left) ? "<" : NULL, dc.norm); - dc.x += dc.w; - /* determine maximum items */ - for(i = curr; i != next; i=i->right) { - dc.w = textw(i->text); - if(dc.w > mw / 3) - dc.w = mw / 3; - drawtext(i->text, (sel == i) ? dc.sel : dc.norm); - dc.x += dc.w; - } - dc.x = mw - spaceitem; - dc.w = spaceitem; - drawtext(next ? ">" : NULL, dc.norm); + if(vlist) + drawmenuv(); + else + drawmenuh(); } XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); } +void +drawmenuh(void) { + Item *i; + + dc.w = spaceitem; + drawtext((curr && curr->left) ? "<" : NULL, dc.norm); + dc.x += dc.w; + /* determine maximum items */ + for(i = curr; i != next; i=i->right) { + dc.w = textw(i->text); + if(dc.w > mw / 3) + dc.w = mw / 3; + drawtext(i->text, (sel == i) ? dc.sel : dc.norm); + dc.x += dc.w; + } + dc.x = mw - spaceitem; + dc.w = spaceitem; + drawtext(next ? ">" : NULL, dc.norm); +} + void drawmenuv(void) { Item *i; dc.x = 0; - dc.y = 0; dc.w = mw; - dc.h = mh; - drawtext(NULL, dc.norm); - /* print prompt? */ - if(promptw) { - dc.w = promptw; - drawtext(prompt, dc.sel); - } - dc.x += promptw; - dc.w = mw - promptw; - /* print command */ - drawtext(text[0] ? text : NULL, dc.norm); - if(curr) { - dc.x = 0; - dc.w = mw; + dc.y += dc.font.height + 2; + /* determine maximum items */ + for(i = curr; i != next; i=i->right) { + drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.y += dc.font.height + 2; - /* determine maximum items */ - for(i = curr; i != next; i=i->right) { - drawtext(i->text, (sel == i) ? dc.sel : dc.norm); - dc.y += dc.font.height + 2; - } - drawtext(NULL, dc.norm); } - XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); - XFlush(dpy); + drawtext(NULL, dc.norm); } void @@ -786,8 +776,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-l")) { vlist = True; calcoffsets = calcoffsetsv; - drawmenu = drawmenuv; - if(++i < argc) lines += atoi(argv[i]); + if(++i < argc) lines = atoi(argv[i]); } else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; From 710c2ff174aaac5d9778f784b4bae2ecacb2ab75 Mon Sep 17 00:00:00 2001 From: "anselm@garbe.us" <unknown> Date: Mon, 22 Mar 2010 07:50:26 +0000 Subject: [PATCH 288/590] applied cls' patch, thanks Connor! --- dmenubar/dmenu.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index aef8ae5..5f16894 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -372,7 +372,7 @@ initfont(const char *fontstr) { void kpress(XKeyEvent * e) { - char buf[32]; + char buf[sizeof text]; int i, num; unsigned int len; KeySym ksym; @@ -457,25 +457,23 @@ kpress(XKeyEvent * e) { char *c; if(!(fp = (FILE*)popen("sselp", "r"))) eprint("dmenu: Could not popen sselp\n"); - c = fgets(text + len, sizeof(text) - len, fp); + c = fgets(buf, sizeof buf, fp); pclose(fp); if(c == NULL) return; } - len = strlen(text); - if(len && text[len-1] == '\n') - text[--len] = '\0'; - match(text); - drawmenu(); - return; + num = strlen(buf); + if(num && buf[num-1] == '\n') + buf[--num] = '\0'; + break; } } switch(ksym) { default: + num = MIN(num, sizeof text - cursor); if(num && !iscntrl((int) buf[0])) { - buf[num] = 0; - memmove(text + cursor + num, text + cursor, sizeof text - cursor); - strncpy(text + cursor, buf, sizeof text - cursor); + memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); + memmove(text + cursor, buf, num); cursor+=num; match(text); } @@ -487,6 +485,10 @@ kpress(XKeyEvent * e) { match(text); } break; + case XK_Delete: + memmove(text + cursor, text + cursor + 1, sizeof text - cursor); + match(text); + break; case XK_End: if(!item) return; From 90e0fe8a6145330c8cd9a8e1e2ea97dabd5a441a Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Wed, 31 Mar 2010 22:37:41 +0100 Subject: [PATCH 289/590] applied Connor's next nice patch, thanks a lot! --- dmenubar/dmenu.c | 65 +++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5f16894..6177906 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -52,6 +52,7 @@ static void calcoffsetsh(void); static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); +static void drawcursor(void); static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); @@ -247,9 +248,7 @@ drawmenuh(void) { dc.x += dc.w; /* determine maximum items */ for(i = curr; i != next; i=i->right) { - dc.w = textw(i->text); - if(dc.w > mw / 3) - dc.w = mw / 3; + dc.w = MIN(textw(i->text), mw / 3); drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } @@ -395,7 +394,8 @@ kpress(XKeyEvent * e) { switch (ksym) { default: /* ignore other control sequences */ return; - case XK_bracketleft: + case XK_c: + case XK_C: ksym = XK_Escape; break; case XK_h: @@ -414,18 +414,16 @@ kpress(XKeyEvent * e) { case XK_U: text[0] = 0; match(text); - drawmenu(); break; 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; + if(cursor > 0) { + i = cursor; + while(i-- > 0 && text[i] == ' '); + while(i-- > 0 && text[i] != ' '); + memmove(text + i + 1, text + cursor, sizeof text - cursor); + cursor = i + 1; match(text); - drawmenu(); } break; } @@ -473,14 +471,14 @@ kpress(XKeyEvent * e) { num = MIN(num, sizeof text - cursor); if(num && !iscntrl((int) buf[0])) { memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); - memmove(text + cursor, buf, num); + memcpy(text + cursor, buf, num); cursor+=num; match(text); } break; case XK_BackSpace: if(cursor > 0) { - memmove(text + cursor + -1, text + cursor, sizeof text - cursor); + memmove(text + cursor - 1, text + cursor, sizeof text - cursor + 1); cursor--; match(text); } @@ -490,8 +488,10 @@ kpress(XKeyEvent * e) { match(text); break; case XK_End: - if(!item) - return; + if(cursor < len) { + cursor = len; + break; + } while(next) { sel = curr = next; calcoffsets(); @@ -504,8 +504,10 @@ kpress(XKeyEvent * e) { running = False; break; case XK_Home: - if(!item) - return; + if(sel == item) { + cursor = 0; + break; + } sel = curr = item; calcoffsets(); break; @@ -536,12 +538,10 @@ kpress(XKeyEvent * e) { calcoffsets(); break; case XK_Return: - if((e->state & ShiftMask) && *text) + if((e->state & ShiftMask) || !sel) fprintf(stdout, "%s", text); - else if(sel) + else fprintf(stdout, "%s", sel->text); - else if(*text) - fprintf(stdout, "%s", text); fflush(stdout); running = False; break; @@ -567,9 +567,6 @@ kpress(XKeyEvent * e) { match(text); break; } - len = strlen(text); - cursor = MIN(cursor, len); - cursor = MAX(cursor, 0); drawmenu(); } @@ -620,13 +617,13 @@ readstdin(void) { unsigned int len = 0, max = 0; Item *i, *new; - i = 0; + i = NULL; while(fgets(buf, sizeof buf, stdin)) { len = strlen(buf); - if (buf[len - 1] == '\n') - buf[len - 1] = 0; + if(buf[len-1] == '\n') + buf[--len] = '\0'; if(!(p = strdup(buf))) - eprint("fatal: could not strdup() %u bytes\n", strlen(buf)); + eprint("fatal: could not strdup() %u bytes\n", len); if(max < len) { maxname = p; max = len; @@ -734,13 +731,9 @@ setup(Bool topbar) { if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); if(maxname) - cmdw = textw(maxname); - if(cmdw > mw / 3) - cmdw = mw / 3; + cmdw = MIN(textw(maxname), mw / 3); if(prompt) - promptw = textw(prompt); - if(promptw > mw / 5) - promptw = mw / 5; + promptw = MIN(textw(prompt), mw / 5); text[0] = 0; match(text); XMapRaised(dpy, win); @@ -799,7 +792,7 @@ main(int argc, char *argv[]) { if(++i < argc) selfgcolor = argv[i]; } else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2009 dmenu engineers, see LICENSE for details\n"); + eprint("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); else eprint("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); From d5cfb20b0013770805e99e87ab3911e8b3ed0209 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Wed, 31 Mar 2010 22:43:49 +0100 Subject: [PATCH 290/590] applied Connor's subwindow patch --- dmenubar/dmenu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6177906..fd9baaa 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -768,6 +768,9 @@ main(int argc, char *argv[]) { } else if(!strcmp(argv[i], "-b")) topbar = False; + else if(!strcmp(argv[i], "-e")) { + if(++i < argc) root = atoi(argv[i]); + } else if(!strcmp(argv[i], "-l")) { vlist = True; calcoffsets = calcoffsetsv; @@ -801,7 +804,8 @@ main(int argc, char *argv[]) { if(!(dpy = XOpenDisplay(NULL))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); + if(!root) + root = RootWindow(dpy, screen); if(isatty(STDIN_FILENO)) { readstdin(); From b22d4e438421e643f22633a92c48a87fa9f5e9a7 Mon Sep 17 00:00:00 2001 From: pancake <nopcode.org> Date: Thu, 1 Apr 2010 19:10:41 +0200 Subject: [PATCH 291/590] add ^a and ^e keybindings --- dmenubar/dmenu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fd9baaa..4c87d6a 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -394,6 +394,14 @@ kpress(XKeyEvent * e) { switch (ksym) { default: /* ignore other control sequences */ return; + case XK_a: + case XK_A: + cursor = 0; + break; + case XK_e: + case XK_E: + cursor = strlen(text); + break; case XK_c: case XK_C: ksym = XK_Escape; From cf3a23c6b0cbd1d647c20336369f6bee7487a376 Mon Sep 17 00:00:00 2001 From: pancake <nopcode.org> Date: Thu, 1 Apr 2010 19:30:21 +0200 Subject: [PATCH 292/590] apply nibble patch removing per-item length limit --- dmenubar/dmenu.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 4c87d6a..f6552aa 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -622,24 +622,31 @@ match(char *pattern) { void readstdin(void) { char *p, buf[1024]; - unsigned int len = 0, max = 0; + unsigned int len = 0, blen = 0, max = 0; Item *i, *new; - i = NULL; + i = 0, p = NULL; while(fgets(buf, sizeof buf, stdin)) { - len = strlen(buf); - if(buf[len-1] == '\n') - buf[--len] = '\0'; - if(!(p = strdup(buf))) - eprint("fatal: could not strdup() %u bytes\n", len); + len += (blen = strlen(buf)); + if(!(p = realloc(p, len))) { + eprint("fatal: could not realloc() %u bytes\n", len); + return; + } + memcpy (p + len - blen, buf, blen); + if (p[len - 1] == '\n') + p[len - 1] = 0; + else if (!feof(stdin)) + continue; if(max < len) { maxname = p; max = len; } + len = 0; if(!(new = (Item *)malloc(sizeof(Item)))) eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); new->next = new->left = new->right = NULL; new->text = p; + p = NULL; if(!i) allitems = new; else From 03616b0b011af26880f8be7421cfbcc3bbf530da Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Thu, 1 Apr 2010 21:31:09 +0100 Subject: [PATCH 293/590] commited Connor's sanity patch --- dmenubar/dmenu.c | 83 +++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 51 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f6552aa..97014cc 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -118,18 +118,14 @@ calcoffsetsh(void) { return; w = promptw + cmdw + 2 * spaceitem; for(next = curr; next; next=next->right) { - tw = textw(next->text); - if(tw > mw / 3) - tw = mw / 3; + tw = MIN(textw(next->text), mw / 3); w += tw; if(w > mw) break; } w = promptw + cmdw + 2 * spaceitem; for(prev = curr; prev && prev->left; prev=prev->left) { - tw = textw(prev->left->text); - if(tw > mw / 3) - tw = mw / 3; + tw = MIN(textw(prev->left->text), mw / 3); w += tw; if(w > mw) break; @@ -138,20 +134,20 @@ calcoffsetsh(void) { void calcoffsetsv(void) { - static unsigned int w; + static unsigned int h; if(!curr) return; - w = (dc.font.height + 2) * (lines + 1); + h = (dc.font.height + 2) * (lines + 1); for(next = curr; next; next=next->right) { - w -= dc.font.height + 2; - if(w <= 0) + h -= dc.font.height + 2; + if(h <= 0) break; } - w = (dc.font.height + 2) * (lines + 1); + h = (dc.font.height + 2) * (lines + 1); for(prev = curr; prev && prev->left; prev=prev->left) { - w -= dc.font.height + 2; - if(w <= 0) + h -= dc.font.height + 2; + if(h <= 0) break; } } @@ -352,10 +348,8 @@ initfont(const char *fontstr) { 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; + dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); + dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); xfonts++; } } @@ -396,16 +390,16 @@ kpress(XKeyEvent * e) { return; case XK_a: case XK_A: - cursor = 0; - break; - case XK_e: - case XK_E: - cursor = strlen(text); + ksym = XK_Home; break; case XK_c: case XK_C: ksym = XK_Escape; break; + case XK_e: + case XK_E: + ksym = XK_End; + break; case XK_h: case XK_H: ksym = XK_BackSpace; @@ -429,7 +423,7 @@ kpress(XKeyEvent * e) { i = cursor; while(i-- > 0 && text[i] == ' '); while(i-- > 0 && text[i] != ' '); - memmove(text + i + 1, text + cursor, sizeof text - cursor); + memmove(text + i + 1, text + cursor, sizeof text - cursor + 1); cursor = i + 1; match(text); } @@ -460,12 +454,12 @@ kpress(XKeyEvent * e) { case XK_p: { FILE *fp; - char *c; + char *s; if(!(fp = (FILE*)popen("sselp", "r"))) eprint("dmenu: Could not popen sselp\n"); - c = fgets(buf, sizeof buf, fp); + s = fgets(buf, sizeof buf, fp); pclose(fp); - if(c == NULL) + if(s == NULL) return; } num = strlen(buf); @@ -621,32 +615,25 @@ match(char *pattern) { void readstdin(void) { - char *p, buf[1024]; - unsigned int len = 0, blen = 0, max = 0; + char *p, buf[sizeof text]; + unsigned int len = 0, max = 0; Item *i, *new; - i = 0, p = NULL; + i = NULL; while(fgets(buf, sizeof buf, stdin)) { - len += (blen = strlen(buf)); - if(!(p = realloc(p, len))) { - eprint("fatal: could not realloc() %u bytes\n", len); - return; - } - memcpy (p + len - blen, buf, blen); - if (p[len - 1] == '\n') - p[len - 1] = 0; - else if (!feof(stdin)) - continue; + len = strlen(buf); + if(buf[len-1] == '\n') + buf[--len] = '\0'; + if(!(p = strdup(buf))) + eprint("fatal: could not strdup() %u bytes\n", len); if(max < len) { maxname = p; max = len; } - len = 0; if(!(new = (Item *)malloc(sizeof(Item)))) eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); new->next = new->left = new->right = NULL; new->text = p; - p = NULL; if(!i) allitems = new; else @@ -812,8 +799,8 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); else - eprint("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); + eprint("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" + " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) @@ -822,14 +809,8 @@ main(int argc, char *argv[]) { if(!root) root = RootWindow(dpy, screen); - if(isatty(STDIN_FILENO)) { - readstdin(); - running = grabkeyboard(); - } - else { /* prevent keypress loss */ - running = grabkeyboard(); - readstdin(); - } + readstdin(); + running = grabkeyboard(); setup(topbar); drawmenu(); From 77f201ff04ba7c0f26ba0916a9aee2bdc1b15cf1 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Thu, 1 Apr 2010 21:32:06 +0100 Subject: [PATCH 294/590] added Connor to LICENSE file --- dmenubar/LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 1f2db9b..7cd31db 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,5 +1,6 @@ MIT/X Consortium License +© 2010 Connor Lane Smith <cls@lubutu.com> © 2006-2009 Anselm R. Garbe <anselm@garbe.us> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> From babf4ff1a5fd530641d50465ce9f840d9b734767 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Thu, 1 Apr 2010 21:40:11 +0100 Subject: [PATCH 295/590] applied Troels' patch, thanks Troels! --- dmenubar/dmenu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 97014cc..fbbfac0 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -658,6 +658,10 @@ run(void) { if(ev.xexpose.count == 0) drawmenu(); break; + case VisibilityNotify: + if (ev.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(dpy, win); + break; } } @@ -691,7 +695,7 @@ setup(Bool topbar) { /* menu window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; + wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; /* menu window geometry */ mh = dc.font.height + 2; From f45023cda1498a085e67930d3c00d68434caf982 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 7 Apr 2010 16:15:34 +0000 Subject: [PATCH 296/590] fixed 3 bugs and some inconsistency --- dmenubar/dmenu.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fbbfac0..15a6152 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -159,12 +159,12 @@ cistrstr(const char *s, const char *sub) { if(!sub) return (char *)s; - if((c = *sub++) != 0) { + if((c = *sub++) != '\0') { c = tolower(c); len = strlen(sub); do { do { - if((csub = *s++) == 0) + if((csub = *s++) == '\0') return NULL; } while(tolower(csub) != c); @@ -220,7 +220,7 @@ drawmenu(void) { dc.x += promptw; dc.w = mw - promptw; /* print command */ - if(cmdw && item) + if(cmdw && item && !vlist) dc.w = cmdw; drawtext(text[0] ? text : NULL, dc.norm); drawcursor(); @@ -371,7 +371,7 @@ kpress(XKeyEvent * e) { KeySym ksym; len = strlen(text); - buf[0] = 0; + buf[0] = '\0'; num = XLookupString(e, buf, sizeof buf, &ksym, NULL); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) @@ -414,7 +414,8 @@ kpress(XKeyEvent * e) { break; case XK_u: case XK_U: - text[0] = 0; + cursor = 0; + text[0] = '\0'; match(text); break; case XK_w: @@ -626,7 +627,7 @@ readstdin(void) { buf[--len] = '\0'; if(!(p = strdup(buf))) eprint("fatal: could not strdup() %u bytes\n", len); - if(max < len) { + if(max < len || !maxname) { maxname = p; max = len; } @@ -740,7 +741,7 @@ setup(Bool topbar) { cmdw = MIN(textw(maxname), mw / 3); if(prompt) promptw = MIN(textw(prompt), mw / 5); - text[0] = 0; + text[0] = '\0'; match(text); XMapRaised(dpy, win); } From 03aaf0d3643ae683d5d55bfd585933eb0c86d91b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 13 Apr 2010 20:14:45 +0000 Subject: [PATCH 297/590] fixed ^U cursor support --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 15a6152..9f29c19 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -414,8 +414,8 @@ kpress(XKeyEvent * e) { break; case XK_u: case XK_U: + memmove(text, text + cursor, sizeof text - cursor + 1); cursor = 0; - text[0] = '\0'; match(text); break; case XK_w: From 4a62ee8f9f11b7e6213589f5c8270741e9ff2a1b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 14 Apr 2010 17:35:19 +0000 Subject: [PATCH 298/590] fixed bad parenting, simpler vlist --- dmenubar/dmenu.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9f29c19..f93407d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -91,11 +91,10 @@ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; -static Window root, win; +static Window parent, win; static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; -static Bool vlist = False; -static unsigned int lines = 5; +static unsigned int lines = 0; static void (*calcoffsets)(void) = calcoffsetsh; void @@ -220,13 +219,12 @@ drawmenu(void) { dc.x += promptw; dc.w = mw - promptw; /* print command */ - if(cmdw && item && !vlist) + if(cmdw && item && lines == 0) dc.w = cmdw; drawtext(text[0] ? text : NULL, dc.norm); drawcursor(); - dc.x += cmdw; if(curr) { - if(vlist) + if(lines > 0) drawmenuv(); else drawmenuh(); @@ -239,8 +237,9 @@ void drawmenuh(void) { Item *i; + dc.x += cmdw; dc.w = spaceitem; - drawtext((curr && curr->left) ? "<" : NULL, dc.norm); + drawtext(curr->left ? "<" : NULL, dc.norm); dc.x += dc.w; /* determine maximum items */ for(i = curr; i != next; i=i->right) { @@ -321,7 +320,7 @@ grabkeyboard(void) { unsigned int len; for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) + if(XGrabKeyboard(dpy, parent, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); @@ -675,6 +674,7 @@ setup(Bool topbar) { #endif XModifierKeymap *modmap; XSetWindowAttributes wa; + XWindowAttributes pwa; /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -699,16 +699,15 @@ setup(Bool topbar) { wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; /* menu window geometry */ - mh = dc.font.height + 2; - mh = vlist ? mh * (lines+1) : mh; + mh = (dc.font.height + 2) * (lines + 1); #if XINERAMA - if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; if(n > 1) { int di; unsigned int dui; Window dummy; - if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) + if(XQueryPointer(dpy, parent, &dummy, &dummy, &x, &y, &di, &di, &dui)) for(i = 0; i < n; i++) if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; @@ -721,19 +720,20 @@ setup(Bool topbar) { else #endif { + XGetWindowAttributes(dpy, parent, &pwa); x = 0; - y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; - mw = DisplayWidth(dpy, screen); + y = topbar ? 0 : pwa.height - mh; + mw = pwa.width; } - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + win = XCreateWindow(dpy, parent, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); /* pixmap */ - dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, root, 0, NULL); + dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, parent, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); @@ -776,10 +776,9 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-b")) topbar = False; else if(!strcmp(argv[i], "-e")) { - if(++i < argc) root = atoi(argv[i]); + if(++i < argc) parent = atoi(argv[i]); } else if(!strcmp(argv[i], "-l")) { - vlist = True; calcoffsets = calcoffsetsv; if(++i < argc) lines = atoi(argv[i]); } @@ -811,8 +810,8 @@ main(int argc, char *argv[]) { if(!(dpy = XOpenDisplay(NULL))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); - if(!root) - root = RootWindow(dpy, screen); + if(!parent) + parent = RootWindow(dpy, screen); readstdin(); running = grabkeyboard(); From 6b1eaca6f4889d21e37550f188120408262d74f1 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 2 May 2010 23:17:02 +0100 Subject: [PATCH 299/590] cleaning up --- dmenubar/dmenu.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f93407d..1762dba 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -212,12 +212,12 @@ drawmenu(void) { dc.h = mh; drawtext(NULL, dc.norm); /* print prompt? */ - if(promptw) { + if(prompt) { dc.w = promptw; drawtext(prompt, dc.sel); + dc.x += dc.w; } - dc.x += promptw; - dc.w = mw - promptw; + dc.w = mw - dc.x; /* print command */ if(cmdw && item && lines == 0) dc.w = cmdw; @@ -241,14 +241,13 @@ drawmenuh(void) { dc.w = spaceitem; drawtext(curr->left ? "<" : NULL, dc.norm); dc.x += dc.w; - /* determine maximum items */ for(i = curr; i != next; i=i->right) { dc.w = MIN(textw(i->text), mw / 3); drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } - dc.x = mw - spaceitem; dc.w = spaceitem; + dc.x = mw - dc.w; drawtext(next ? ">" : NULL, dc.norm); } @@ -259,7 +258,6 @@ drawmenuv(void) { dc.x = 0; dc.w = mw; dc.y += dc.font.height + 2; - /* determine maximum items */ for(i = curr; i != next; i=i->right) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.y += dc.font.height + 2; @@ -340,13 +338,11 @@ initfont(const char *fontstr) { 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++) { + for(i = 0; i < n; i++) { dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); xfonts++; From f39a3226bd168a73d2447f7e2e49628db490a0ad Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 5 May 2010 11:42:39 +0100 Subject: [PATCH 300/590] fixed vlist alignment --- dmenubar/dmenu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1762dba..bebc206 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -255,8 +255,7 @@ void drawmenuv(void) { Item *i; - dc.x = 0; - dc.w = mw; + dc.w = mw - dc.x; dc.y += dc.font.height + 2; for(i = curr; i != next; i=i->right) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); From d54005dc266c73d18bfa04fa163ce7529b2adc25 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Fri, 28 May 2010 11:42:49 +0100 Subject: [PATCH 301/590] prepared dmenu-4.1 release --- dmenubar/LICENSE | 2 +- dmenubar/Makefile | 6 +++++- dmenubar/{config.h => config.def.h} | 0 dmenubar/dmenu.c | 8 ++++---- 4 files changed, 10 insertions(+), 6 deletions(-) rename dmenubar/{config.h => config.def.h} (100%) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 7cd31db..f44738e 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License © 2010 Connor Lane Smith <cls@lubutu.com> -© 2006-2009 Anselm R. Garbe <anselm@garbe.us> +© 2006-2010 Anselm R Garbe <anselm@garbe.us> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> diff --git a/dmenubar/Makefile b/dmenubar/Makefile index e7df2d7..5ea6729 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -20,6 +20,10 @@ options: ${OBJ}: config.h config.mk +config.h: + @echo creating $@ from config.def.h + @cp config.def.h $@ + dmenu: ${OBJ} @echo CC -o $@ @${CC} -o $@ ${OBJ} ${LDFLAGS} @@ -31,7 +35,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 config.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/config.h b/dmenubar/config.def.h similarity index 100% rename from dmenubar/config.h rename to dmenubar/config.def.h diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index bebc206..3fd9275 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -42,8 +42,8 @@ typedef struct { typedef struct Item Item; struct Item { char *text; - Item *next; /* traverses all items */ - Item *left, *right; /* traverses items matching current search pattern */ + Item *next; /* traverses all items */ + Item *left, *right; /* traverses items matching current search pattern */ }; /* forward declarations */ @@ -85,8 +85,8 @@ static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; static DC dc; -static Item *allitems = NULL; /* first of all items */ -static Item *item = NULL; /* first of pattern matching items */ +static Item *allitems = NULL; /* first of all items */ +static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; From 9e5c86460944cb03885f128479584844c312f76d Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Fri, 28 May 2010 11:42:54 +0100 Subject: [PATCH 302/590] Added tag 4.1 for changeset 844587572673 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index b1e6acb..dec60a8 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -40,3 +40,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 644b0798fcccd570fd519899e1601c6857496b91 3.8 21a1ed9a69b9541a355758a57103e294fb722c33 3.9 78f9f72cc9c6bdb022ff8908486b61ef5e242aad 4.0 +844587572673cf6326c3f61737264a46b728fc0a 4.1 From c624af41fe01af23b787968c071c608b2c45d51d Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 29 May 2010 12:55:38 +0100 Subject: [PATCH 303/590] applied Ramils patch --- dmenubar/dmenu.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3fd9275..2966954 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -19,6 +19,7 @@ #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) /* enums */ enum { ColFG, ColBG, ColLast }; @@ -360,7 +361,7 @@ initfont(const char *fontstr) { void kpress(XKeyEvent * e) { char buf[sizeof text]; - int i, num; + int i, num, off; unsigned int len; KeySym ksym; @@ -475,13 +476,19 @@ kpress(XKeyEvent * e) { break; case XK_BackSpace: if(cursor > 0) { - memmove(text + cursor - 1, text + cursor, sizeof text - cursor + 1); - cursor--; + off = 1; + while(cursor > off && !IS_UTF8_1ST_CHAR(text[cursor - off])) + off++; + memmove(text + cursor - off, text + cursor, sizeof text - cursor + off); + cursor -= off; match(text); } break; case XK_Delete: - memmove(text + cursor, text + cursor + 1, sizeof text - cursor); + off = 1; + while(cursor + off < sizeof text - 1 && !IS_UTF8_1ST_CHAR(text[cursor + off])) + off++; + memmove(text + cursor, text + cursor + off, sizeof text - cursor); match(text); break; case XK_End: @@ -517,9 +524,11 @@ kpress(XKeyEvent * e) { calcoffsets(); } } - else if(cursor > 0) - cursor--; - else + else if(cursor > 0) { + do { + cursor--; + } while(cursor > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); + } else return; break; case XK_Next: @@ -544,9 +553,11 @@ kpress(XKeyEvent * e) { break; case XK_Right: case XK_Down: - if(cursor < len) - cursor++; - else if(sel && sel->right) { + if(cursor < len) { + do { + cursor++; + } while(cursor < len && !IS_UTF8_1ST_CHAR(text[cursor])); + } else if(sel && sel->right) { sel=sel->right; if(sel == next) { curr = next; From f144f7c7106a0f9d0dfd1b309cf97f65517a7154 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 29 May 2010 12:56:33 +0100 Subject: [PATCH 304/590] prepared bugfix release 4.1.1 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 75c6abe..eb410dc 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.1 +VERSION = 4.1.1 # Customize below to fit your system From 3daec65cbacfcd05fe76f49c0591918362c8868d Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 29 May 2010 12:56:37 +0100 Subject: [PATCH 305/590] Added tag 4.1.1 for changeset 72749a826cab --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index dec60a8..cb351fb 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -41,3 +41,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 21a1ed9a69b9541a355758a57103e294fb722c33 3.9 78f9f72cc9c6bdb022ff8908486b61ef5e242aad 4.0 844587572673cf6326c3f61737264a46b728fc0a 4.1 +72749a826cab0baa805620e44a22e54486c97a4e 4.1.1 From dd18984717e33fff06f2c3af004656d0def4bb98 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 9 Jun 2010 10:13:26 +0100 Subject: [PATCH 306/590] updated manpage --- dmenubar/dmenu.1 | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 24ee38b..03ebda8 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -5,13 +5,14 @@ dmenu \- dynamic menu .B dmenu .RB [ \-i ] .RB [ \-b ] -.RB [ \-l " <lines>"] -.RB [ \-fn " <font>"] -.RB [ \-nb " <color>"] -.RB [ \-nf " <color>"] -.RB [ \-p " <prompt>"] -.RB [ \-sb " <color>"] -.RB [ \-sf " <color>"] +.RB [ \-e " <xid>]" +.RB [ \-l " <lines>]" +.RB [ \-fn " <font>]" +.RB [ \-nb " <color>]" +.RB [ \-nf " <color>]" +.RB [ \-p " <prompt>]" +.RB [ \-sb " <color>]" +.RB [ \-sf " <color>]" .RB [ \-v ] .SH DESCRIPTION .SS Overview @@ -27,6 +28,9 @@ makes dmenu match menu entries case insensitively. .B \-b defines that dmenu appears at the bottom. .TP +.B \-e <xid> +reparents dmenu to the window specified by xid. +.TP .B \-l <lines> activates vertical list mode. The given number of lines will be displayed. Window height will get adjusted. From e139b8febf8d199b543aa9b624ff2c2513ec497e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 11 Jun 2010 09:24:33 +0100 Subject: [PATCH 307/590] fixed vlist paging, cleaned up --- dmenubar/dmenu.c | 90 +++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 58 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2966954..05d1506 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -111,45 +111,30 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsetsh(void) { - int tw; unsigned int w; if(!curr) return; w = promptw + cmdw + 2 * spaceitem; - for(next = curr; next; next=next->right) { - tw = MIN(textw(next->text), mw / 3); - w += tw; - if(w > mw) - break; - } + for(next = curr; next && w < mw; next=next->right) + w += MIN(textw(next->text), mw / 3); w = promptw + cmdw + 2 * spaceitem; - for(prev = curr; prev && prev->left; prev=prev->left) { - tw = MIN(textw(prev->left->text), mw / 3); - w += tw; - if(w > mw) - break; - } + for(prev = curr; prev && prev->left && w < mw; prev=prev->left) + w += MIN(textw(prev->left->text), mw / 3); } void calcoffsetsv(void) { - static unsigned int h; + unsigned int h; if(!curr) return; - h = (dc.font.height + 2) * (lines + 1); - for(next = curr; next; next=next->right) { + h = (dc.font.height + 2) * lines; + for(next = curr; next && h > 0; next = next->right) h -= dc.font.height + 2; - if(h <= 0) - break; - } - h = (dc.font.height + 2) * (lines + 1); - for(prev = curr; prev && prev->left; prev=prev->left) { + h = (dc.font.height + 2) * lines; + for(prev = curr; prev && prev->left && h > 0; prev = prev->left) h -= dc.font.height + 2; - if(h <= 0) - break; - } } char * @@ -177,14 +162,6 @@ cistrstr(const char *s, const char *sub) { void cleanup(void) { - Item *itm; - - while(allitems) { - itm = allitems->next; - free(allitems->text); - free(allitems); - allitems = itm; - } if(dc.font.set) XFreeFontSet(dpy, dc.font.set); else @@ -257,11 +234,13 @@ drawmenuv(void) { Item *i; dc.w = mw - dc.x; - dc.y += dc.font.height + 2; + dc.h = dc.font.height + 2; + dc.y = dc.h; for(i = curr; i != next; i=i->right) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); - dc.y += dc.font.height + 2; + dc.y += dc.h; } + dc.h = mh - dc.y; drawtext(NULL, dc.norm); } @@ -309,7 +288,7 @@ getcolor(const char *colstr) { XColor color; if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) - eprint("error, cannot allocate color '%s'\n", colstr); + eprint("dmenu: cannot allocate color '%s'\n", colstr); return color.pixel; } @@ -328,12 +307,11 @@ grabkeyboard(void) { void initfont(const char *fontstr) { - char *def, **missing; + char *def, **missing = NULL; int i, n; if(!fontstr || fontstr[0] == '\0') - eprint("error, cannot load font: '%s'\n", fontstr); - missing = NULL; + eprint("dmenu: cannot load font: '%s'\n", fontstr); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); @@ -351,7 +329,7 @@ initfont(const char *fontstr) { else { if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) - eprint("error, cannot load font: '%s'\n", fontstr); + eprint("dmenu: cannot load font: '%s'\n", fontstr); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; } @@ -361,12 +339,11 @@ initfont(const char *fontstr) { void kpress(XKeyEvent * e) { char buf[sizeof text]; - int i, num, off; + int i, num; unsigned int len; KeySym ksym; len = strlen(text); - buf[0] = '\0'; num = XLookupString(e, buf, sizeof buf, &ksym, NULL); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) @@ -451,8 +428,8 @@ kpress(XKeyEvent * e) { { FILE *fp; char *s; - if(!(fp = (FILE*)popen("sselp", "r"))) - eprint("dmenu: Could not popen sselp\n"); + if(!(fp = popen("sselp", "r"))) + eprint("dmenu: cannot popen sselp\n"); s = fgets(buf, sizeof buf, fp); pclose(fp); if(s == NULL) @@ -470,25 +447,21 @@ kpress(XKeyEvent * e) { if(num && !iscntrl((int) buf[0])) { memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); memcpy(text + cursor, buf, num); - cursor+=num; + cursor += num; match(text); } break; case XK_BackSpace: if(cursor > 0) { - off = 1; - while(cursor > off && !IS_UTF8_1ST_CHAR(text[cursor - off])) - off++; - memmove(text + cursor - off, text + cursor, sizeof text - cursor + off); - cursor -= off; + for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); + memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); + cursor -= i; match(text); } break; case XK_Delete: - off = 1; - while(cursor + off < sizeof text - 1 && !IS_UTF8_1ST_CHAR(text[cursor + off])) - off++; - memmove(text + cursor, text + cursor + off, sizeof text - cursor); + for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); + memmove(text + cursor, text + cursor + i, sizeof text - cursor); match(text); break; case XK_End: @@ -631,13 +604,13 @@ readstdin(void) { if(buf[len-1] == '\n') buf[--len] = '\0'; if(!(p = strdup(buf))) - eprint("fatal: could not strdup() %u bytes\n", len); + eprint("dmenu: cannot strdup %u bytes\n", len); if(max < len || !maxname) { maxname = p; max = len; } - if(!(new = (Item *)malloc(sizeof(Item)))) - eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); + if(!(new = malloc(sizeof *new))) + eprint("dmenu: cannot malloc %u bytes\n", sizeof *new); new->next = new->left = new->right = NULL; new->text = p; if(!i) @@ -785,8 +758,9 @@ main(int argc, char *argv[]) { if(++i < argc) parent = atoi(argv[i]); } else if(!strcmp(argv[i], "-l")) { - calcoffsets = calcoffsetsv; if(++i < argc) lines = atoi(argv[i]); + if(lines > 0) + calcoffsets = calcoffsetsv; } else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; @@ -812,7 +786,7 @@ main(int argc, char *argv[]) { eprint("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); + fprintf(stderr, "dmenu: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); From 2c584ebe466a337df68d7c919871d29bebbf116d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 16 Jun 2010 15:36:17 +0100 Subject: [PATCH 308/590] cleaned up --- dmenubar/dmenu.c | 52 +++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 05d1506..4a6ca3d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -93,7 +93,7 @@ static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; static Window parent, win; -static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; +static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static unsigned int lines = 0; static void (*calcoffsets)(void) = calcoffsetsh; @@ -144,8 +144,7 @@ cistrstr(const char *s, const char *sub) { if(!sub) return (char *)s; - if((c = *sub++) != '\0') { - c = tolower(c); + if((c = tolower(*sub++)) != '\0') { len = strlen(sub); do { do { @@ -199,7 +198,7 @@ drawmenu(void) { /* print command */ if(cmdw && item && lines == 0) dc.w = cmdw; - drawtext(text[0] ? text : NULL, dc.norm); + drawtext(*text ? text : NULL, dc.norm); drawcursor(); if(curr) { if(lines > 0) @@ -345,15 +344,13 @@ kpress(XKeyEvent * e) { len = strlen(text); num = XLookupString(e, buf, sizeof buf, &ksym, NULL); - if(IsKeypadKey(ksym)) { - if(ksym == XK_KP_Enter) - ksym = XK_Return; - else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) - ksym = (ksym - XK_KP_0) + XK_0; - } - if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) - || IsPrivateKeypadKey(ksym)) + if(ksym == XK_KP_Enter) + ksym = XK_Return; + else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) + ksym = (ksym - XK_KP_0) + XK_0; + else if(IsFunctionKey(ksym) || IsKeypadKey(ksym) + || IsMiscFunctionKey(ksym) || IsPFKey(ksym) + || IsPrivateKeypadKey(ksym)) return; /* first check if a control mask is omitted */ if(e->state & ControlMask) { @@ -405,7 +402,8 @@ kpress(XKeyEvent * e) { } if(CLEANMASK(e->state) & Mod1Mask) { switch(ksym) { - default: return; + default: + return; case XK_h: ksym = XK_Left; break; @@ -491,17 +489,15 @@ kpress(XKeyEvent * e) { case XK_Left: case XK_Up: if(sel && sel->left){ - sel=sel->left; + sel = sel->left; if(sel->right == curr) { curr = prev; calcoffsets(); } } - else if(cursor > 0) { - do { - cursor--; - } while(cursor > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); - } else + else if(cursor > 0) + while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); + else return; break; case XK_Next: @@ -526,12 +522,10 @@ kpress(XKeyEvent * e) { break; case XK_Right: case XK_Down: - if(cursor < len) { - do { - cursor++; - } while(cursor < len && !IS_UTF8_1ST_CHAR(text[cursor])); - } else if(sel && sel->right) { - sel=sel->right; + if(cursor < len) + while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); + else if(sel && sel->right) { + sel = sel->right; if(sel == next) { curr = next; calcoffsets(); @@ -605,10 +599,8 @@ readstdin(void) { buf[--len] = '\0'; if(!(p = strdup(buf))) eprint("dmenu: cannot strdup %u bytes\n", len); - if(max < len || !maxname) { + if((max = MAX(max, len)) == len) maxname = p; - max = len; - } if(!(new = malloc(sizeof *new))) eprint("dmenu: cannot malloc %u bytes\n", sizeof *new); new->next = new->left = new->right = NULL; @@ -628,8 +620,6 @@ run(void) { /* main event loop */ while(running && !XNextEvent(dpy, &ev)) switch (ev.type) { - default: /* ignore all crap */ - break; case KeyPress: kpress(&ev.xkey); break; From bbf8d9d3f0fdb96bcbfbaa9b3884ff3ee6510f77 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 19 Jun 2010 21:44:32 +0100 Subject: [PATCH 309/590] added sselp requirement to readme --- dmenubar/README | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/README b/dmenubar/README index 6e84135..b11fc08 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -6,6 +6,7 @@ dmenu is a generic and efficient menu for X. Requirements ------------ In order to build dmenu you need the Xlib header files. +Pasting the X selection to dmenu requires the sselp utility at runtime. Installation From 5c1e1a08e7c5df821917c7b597f751f8bfbf348e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 20 Jun 2010 00:44:26 +0100 Subject: [PATCH 310/590] added ^K, optimisations --- dmenubar/dmenu.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 4a6ca3d..1d239c2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -79,9 +79,9 @@ static char text[4096]; static int cmdw = 0; static int promptw = 0; static int ret = 0; -static int cursor = 0; static int screen; static unsigned int mw, mh; +static unsigned int cursor = 0; static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; @@ -338,8 +338,8 @@ initfont(const char *fontstr) { void kpress(XKeyEvent * e) { char buf[sizeof text]; - int i, num; - unsigned int len; + int num; + unsigned int i, len; KeySym ksym; len = strlen(text); @@ -381,6 +381,10 @@ kpress(XKeyEvent * e) { case XK_J: ksym = XK_Return; break; + case XK_k: + case XK_K: + text[cursor] = '\0'; + break; case XK_u: case XK_U: memmove(text, text + cursor, sizeof text - cursor + 1); @@ -450,12 +454,12 @@ kpress(XKeyEvent * e) { } break; case XK_BackSpace: - if(cursor > 0) { - for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); - memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); - cursor -= i; - match(text); - } + if(cursor == 0) + return; + for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); + memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); + cursor -= i; + match(text); break; case XK_Delete: for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); @@ -477,7 +481,7 @@ kpress(XKeyEvent * e) { case XK_Escape: ret = 1; running = False; - break; + return; case XK_Home: if(sel == item) { cursor = 0; @@ -519,7 +523,7 @@ kpress(XKeyEvent * e) { fprintf(stdout, "%s", sel->text); fflush(stdout); running = False; - break; + return; case XK_Right: case XK_Down: if(cursor < len) From d24efcbbd319b125434426a8f122e16aedba9f34 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 20 Jun 2010 01:19:17 +0100 Subject: [PATCH 311/590] cleaned up --- dmenubar/dmenu.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1d239c2..ec62602 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -354,45 +354,36 @@ kpress(XKeyEvent * e) { return; /* first check if a control mask is omitted */ if(e->state & ControlMask) { - switch (ksym) { + switch(tolower(ksym)) { default: /* ignore other control sequences */ return; case XK_a: - case XK_A: ksym = XK_Home; break; case XK_c: - case XK_C: ksym = XK_Escape; break; case XK_e: - case XK_E: ksym = XK_End; break; case XK_h: - case XK_H: ksym = XK_BackSpace; break; case XK_i: - case XK_I: ksym = XK_Tab; break; case XK_j: - case XK_J: ksym = XK_Return; break; case XK_k: - case XK_K: text[cursor] = '\0'; break; case XK_u: - case XK_U: memmove(text, text + cursor, sizeof text - cursor + 1); cursor = 0; match(text); break; case XK_w: - case XK_W: if(cursor > 0) { i = cursor; while(i-- > 0 && text[i] == ' '); From 23e4e1a5a157f507274abb0cce2f2016614d6203 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 20 Jun 2010 15:04:15 +0100 Subject: [PATCH 312/590] updated manpage, changed keybinds M- binds tend to be wm level, and there were up to 3 binds for the same action M-{hjkl} also no longer made sense in vlist mode --- dmenubar/dmenu.1 | 46 ++++++++++++-------------- dmenubar/dmenu.c | 84 ++++++++++++++++++++++-------------------------- 2 files changed, 59 insertions(+), 71 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 03ebda8..c994ad7 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -14,12 +14,22 @@ dmenu \- dynamic menu .RB [ \-sb " <color>]" .RB [ \-sf " <color>]" .RB [ \-v ] + +.B dmenu_run +[<options...>] + +.BR dmenu_path .SH DESCRIPTION .SS Overview dmenu is a generic menu for X, originally designed for .BR dwm (1). It manages huge amounts (up to 10.000 and more) of user defined menu items efficiently. + +dmenu_run is a dmenu script used by dwm which lists executables in the user's PATH +and executes the selected item. + +dmenu_path is a script used by dmenu_run to find and cache a list of executables. .SS Options .TP .B \-i @@ -33,7 +43,7 @@ reparents dmenu to the window specified by xid. .TP .B \-l <lines> activates vertical list mode. -The given number of lines will be displayed. Window height will get adjusted. +The given number of lines will be displayed. Window height will be adjusted. .TP .B \-fn <font> defines the font. @@ -60,20 +70,9 @@ dmenu reads a list of newline-separated items from standard input and creates a menu. When the user selects an item or enters any text and presses Return, his/her choice is printed to standard output and dmenu terminates. .P -dmenu is completely controlled by the keyboard. The following keys are recognized: -.TP -.B Any printable character -Appends the character to the text in the input field. This works as a filter: -only items containing this text will be displayed. -.TP -.B Left/Right (Up/Down) (Mod1\-h/Mod1\-l) -Select the previous/next item. -.TP -.B PageUp/PageDown (Mod1\-k/Mod1\-j) -Select the first item of the previous/next 'page' of items. -.TP -.B Home/End (Mod1\-g/Mod1\-G) -Select the first/last item. +dmenu is completely controlled by the keyboard. Besides standard Unix line editing, +and item selection (Up/Down or Left/Right, PageUp/PageDown, Home/End), the following +keys are recognized: .TP .B Tab (Control\-i) Copy the selected item to the input field. @@ -84,24 +83,19 @@ Confirm selection and quit (print the selected item to standard output). Returns on termination. .TP .B Shift\-Return (Control\-Shift\-j) -Confirm selection and quit (print the text in the input field to standard output). +Confirm input and quit (print the text in the input field to standard output). Returns .B 0 on termination. .TP -.B Escape (Control\-bracketleft) +.B Escape (Control\-c) Quit without selecting an item. Returns .B 1 on termination. .TP -.B Backspace (Control\-h) -Remove a character from the input field. -.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. +.B Control\-y +Pastes the X selection into the input field. This requires +.BR sselp (1). .SH SEE ALSO .BR dwm (1), -.BR wmii (1) . +.BR wmii (1). diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index ec62602..15ce8c7 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -355,17 +355,23 @@ kpress(XKeyEvent * e) { /* first check if a control mask is omitted */ if(e->state & ControlMask) { switch(tolower(ksym)) { - default: /* ignore other control sequences */ + default: return; case XK_a: ksym = XK_Home; break; + case XK_b: + ksym = XK_Left; + break; case XK_c: ksym = XK_Escape; break; case XK_e: ksym = XK_End; break; + case XK_f: + ksym = XK_Right; + break; case XK_h: ksym = XK_BackSpace; break; @@ -378,6 +384,12 @@ kpress(XKeyEvent * e) { case XK_k: text[cursor] = '\0'; break; + case XK_n: + ksym = XK_Down; + break; + case XK_p: + ksym = XK_Up; + break; case XK_u: memmove(text, text + cursor, sizeof text - cursor + 1); cursor = 0; @@ -393,31 +405,7 @@ kpress(XKeyEvent * e) { match(text); } break; - } - } - if(CLEANMASK(e->state) & Mod1Mask) { - switch(ksym) { - default: - return; - case XK_h: - ksym = XK_Left; - break; - case XK_l: - ksym = XK_Right; - break; - case XK_j: - ksym = XK_Next; - break; - case XK_k: - ksym = XK_Prior; - break; - case XK_g: - ksym = XK_Home; - break; - case XK_G: - ksym = XK_End; - break; - case XK_p: + case XK_y: { FILE *fp; char *s; @@ -453,6 +441,8 @@ kpress(XKeyEvent * e) { match(text); break; case XK_Delete: + if(cursor == len) + return; for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); memmove(text + cursor, text + cursor + i, sizeof text - cursor); match(text); @@ -482,18 +472,20 @@ kpress(XKeyEvent * e) { calcoffsets(); break; case XK_Left: - case XK_Up: - if(sel && sel->left){ - sel = sel->left; - if(sel->right == curr) { - curr = prev; - calcoffsets(); - } - } - else if(cursor > 0) + if(cursor > 0 && (!sel || !sel->left)) { while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); - else + break; + } + if(lines > 0) return; + case XK_Up: + if(!sel || !sel->left) + return; + sel = sel->left; + if(sel->right == curr) { + curr = prev; + calcoffsets(); + } break; case XK_Next: if(!next) @@ -516,18 +508,20 @@ kpress(XKeyEvent * e) { running = False; return; case XK_Right: - case XK_Down: - if(cursor < len) + if(cursor < len) { while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); - else if(sel && sel->right) { - sel = sel->right; - if(sel == next) { - curr = next; - calcoffsets(); - } + break; } - else + if(lines > 0) return; + case XK_Down: + if(!sel || !sel->right) + return; + sel = sel->right; + if(sel == next) { + curr = next; + calcoffsets(); + } break; case XK_Tab: if(!sel) From 2dca58cb5b7a38d34bac4a13519d4050734b0d98 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 22 Jun 2010 10:45:07 +0100 Subject: [PATCH 313/590] fixed vlist cursor --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 15ce8c7..b89c0da 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -472,7 +472,7 @@ kpress(XKeyEvent * e) { calcoffsets(); break; case XK_Left: - if(cursor > 0 && (!sel || !sel->left)) { + if(cursor > 0 && (!sel || !sel->left || lines > 0)) { while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); break; } From 4ba681557ed9be808a7dbbe3bcb84be4794ab438 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 12:04:54 +0100 Subject: [PATCH 314/590] initial dmenu / dinput separation --- dmenubar/Makefile | 17 +- dmenubar/dinput.c | 387 ++++++++++++++++++++++++++++++++++++++++++++++ dmenubar/dmenu.c | 219 +++----------------------- dmenubar/draw.c | 143 +++++++++++++++++ 4 files changed, 561 insertions(+), 205 deletions(-) create mode 100644 dmenubar/dinput.c create mode 100644 dmenubar/draw.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 5ea6729..d5884da 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,10 +3,10 @@ include config.mk -SRC = dmenu.c +SRC = dinput.c dmenu.c draw.c OBJ = ${SRC:.c=.o} -all: options dmenu +all: options dinput dmenu options: @echo dmenu build options: @@ -18,19 +18,19 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk +${OBJ}: config.h config.mk draw.c config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -dmenu: ${OBJ} +.o: @echo CC -o $@ - @${CC} -o $@ ${OBJ} ${LDFLAGS} + @${CC} -o $@ $< ${LDFLAGS} clean: @echo cleaning - @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dinput dmenu ${OBJ} dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @@ -43,7 +43,8 @@ dist: clean install: all @echo installing executable file to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin + @cp -f dinput dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/dinput @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run @@ -55,7 +56,7 @@ install: all uninstall: @echo removing executable file from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_path - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_run + @rm -f ${DESTDIR}${PREFIX}/bin/dinput ${DESTDIR}${PREFIX}/bin/dmenu_run @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c new file mode 100644 index 0000000..490380d --- /dev/null +++ b/dmenubar/dinput.c @@ -0,0 +1,387 @@ +/* See LICENSE file for copyright and license details. */ +#include <ctype.h> +#include <locale.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <X11/keysym.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#ifdef XINERAMA +#include <X11/extensions/Xinerama.h> +#endif + +/* macros */ +#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) + +/* forward declarations */ +static void cleanup(void); +static void drawcursor(void); +static void drawinput(void); +static void eprint(const char *errstr, ...); +static Bool grabkeyboard(void); +static void kpress(XKeyEvent * e); +static void run(void); +static void setup(Bool topbar); + +#include "config.h" + +/* variables */ +static char *prompt = NULL; +static char text[4096]; +static int promptw = 0; +static int ret = 0; +static int screen; +static unsigned int mw, mh; +static unsigned int cursor = 0; +static unsigned int numlockmask = 0; +static Bool running = True; +static Display *dpy; +static Window parent, win; + +#include "draw.c" + +void +cleanup(void) { + dccleanup(); + XDestroyWindow(dpy, win); + XUngrabKeyboard(dpy, CurrentTime); +} + +void +drawcursor(void) { + XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; + + r.x += textnw(text, cursor) + dc.font.height / 2; + + XSetForeground(dpy, dc.gc, dc.norm[ColFG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); +} + +void +drawinput(void) +{ + dc.x = 0; + dc.y = 0; + dc.w = mw; + dc.h = mh; + drawtext(NULL, dc.norm); + /* print prompt? */ + if(prompt) { + dc.w = promptw; + drawtext(prompt, dc.sel); + dc.x += dc.w; + } + dc.w = mw - dc.x; + drawtext(*text ? text : NULL, dc.norm); + drawcursor(); + XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); + XFlush(dpy); +} + +void +eprint(const char *errstr, ...) { + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +Bool +grabkeyboard(void) { + unsigned int len; + + for(len = 1000; len; len--) { + if(XGrabKeyboard(dpy, parent, True, GrabModeAsync, GrabModeAsync, CurrentTime) + == GrabSuccess) + break; + usleep(1000); + } + return len > 0; +} + +void +kpress(XKeyEvent * e) { + char buf[sizeof text]; + int num; + unsigned int i, len; + KeySym ksym; + + len = strlen(text); + num = XLookupString(e, buf, sizeof buf, &ksym, NULL); + if(ksym == XK_KP_Enter) + ksym = XK_Return; + else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) + ksym = (ksym - XK_KP_0) + XK_0; + else if(IsFunctionKey(ksym) || IsKeypadKey(ksym) + || IsMiscFunctionKey(ksym) || IsPFKey(ksym) + || IsPrivateKeypadKey(ksym)) + return; + /* first check if a control mask is omitted */ + if(e->state & ControlMask) { + switch(tolower(ksym)) { + default: + return; + case XK_a: + ksym = XK_Home; + break; + case XK_b: + ksym = XK_Left; + break; + case XK_c: + ksym = XK_Escape; + break; + case XK_e: + ksym = XK_End; + break; + case XK_f: + ksym = XK_Right; + break; + case XK_h: + ksym = XK_BackSpace; + break; + case XK_j: + ksym = XK_Return; + break; + case XK_k: + text[cursor] = '\0'; + break; + case XK_u: + memmove(text, text + cursor, sizeof text - cursor + 1); + cursor = 0; + break; + case XK_w: + if(cursor > 0) { + i = cursor; + while(i-- > 0 && text[i] == ' '); + while(i-- > 0 && text[i] != ' '); + memmove(text + i + 1, text + cursor, sizeof text - cursor + 1); + cursor = i + 1; + } + break; + case XK_y: + { + FILE *fp; + char *s; + if(!(fp = popen("sselp", "r"))) + eprint("dinput: cannot popen sselp\n"); + s = fgets(buf, sizeof buf, fp); + pclose(fp); + if(s == NULL) + return; + } + num = strlen(buf); + if(num && buf[num-1] == '\n') + buf[--num] = '\0'; + break; + } + } + switch(ksym) { + default: + num = MIN(num, sizeof text - cursor); + if(num && !iscntrl((int) buf[0])) { + memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); + memcpy(text + cursor, buf, num); + cursor += num; + } + break; + case XK_BackSpace: + if(cursor == 0) + return; + for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); + memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); + cursor -= i; + break; + case XK_Delete: + if(cursor == len) + return; + for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); + memmove(text + cursor, text + cursor + i, sizeof text - cursor); + break; + case XK_End: + cursor = len; + break; + case XK_Escape: + ret = 1; + running = False; + return; + case XK_Home: + cursor = 0; + break; + case XK_Left: + if(cursor == 0) + return; + while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); + break; + case XK_Return: + fprintf(stdout, "%s", text); + fflush(stdout); + running = False; + return; + case XK_Right: + if(cursor == len) + return; + while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); + break; + } + drawinput(); +} + +void +run(void) { + XEvent ev; + + /* main event loop */ + while(running && !XNextEvent(dpy, &ev)) + switch (ev.type) { + case KeyPress: + kpress(&ev.xkey); + break; + case Expose: + if(ev.xexpose.count == 0) + drawinput(); + break; + case VisibilityNotify: + if (ev.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(dpy, win); + break; + } +} + +void +setup(Bool topbar) { + int i, j, x, y; +#if XINERAMA + int n; + XineramaScreenInfo *info = NULL; +#endif + XModifierKeymap *modmap; + XSetWindowAttributes wa; + XWindowAttributes pwa; + + /* 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 */ + dc.norm[ColBG] = getcolor(normbgcolor); + dc.norm[ColFG] = getcolor(normfgcolor); + dc.sel[ColBG] = getcolor(selbgcolor); + dc.sel[ColFG] = getcolor(selfgcolor); + initfont(font); + + /* menu window */ + wa.override_redirect = True; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; + + /* menu window geometry */ + mh = (dc.font.height + 2); +#if XINERAMA + if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + i = 0; + if(n > 1) { + int di; + unsigned int dui; + Window dummy; + if(XQueryPointer(dpy, parent, &dummy, &dummy, &x, &y, &di, &di, &dui)) + for(i = 0; i < n; i++) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + break; + } + x = info[i].x_org; + y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; + mw = info[i].width; + XFree(info); + } + else +#endif + { + XGetWindowAttributes(dpy, parent, &pwa); + x = 0; + y = topbar ? 0 : pwa.height - mh; + mw = pwa.width; + } + + win = XCreateWindow(dpy, parent, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + + /* pixmap */ + dcsetup(); + if(prompt) + promptw = MIN(textw(prompt), mw / 5); + cursor = strlen(text); + XMapRaised(dpy, win); +} + +int +main(int argc, char *argv[]) { + unsigned int i; + Bool topbar = True; + + /* command line args */ + for(i = 1; i < argc; i++) + if(!strcmp(argv[i], "-b")) + topbar = False; + else if(!strcmp(argv[i], "-e")) { + if(++i < argc) parent = atoi(argv[i]); + } + else if(!strcmp(argv[i], "-fn")) { + if(++i < argc) font = argv[i]; + } + else if(!strcmp(argv[i], "-nb")) { + if(++i < argc) normbgcolor = argv[i]; + } + else if(!strcmp(argv[i], "-nf")) { + if(++i < argc) normfgcolor = argv[i]; + } + else if(!strcmp(argv[i], "-p")) { + if(++i < argc) prompt = argv[i]; + } + else if(!strcmp(argv[i], "-sb")) { + if(++i < argc) selbgcolor = argv[i]; + } + else if(!strcmp(argv[i], "-sf")) { + if(++i < argc) selfgcolor = argv[i]; + } + else if(!strcmp(argv[i], "-v")) + eprint("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n"); + else if(!*text) + strncpy(text, argv[i], sizeof text); + else + eprint("usage: dinput [-b] [-e <xid>] [-fn <font>] [-nb <color>] [-nf <color>]\n" + " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n"); + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fprintf(stderr, "dinput: warning: no locale support\n"); + if(!(dpy = XOpenDisplay(NULL))) + eprint("dinput: cannot open display\n"); + screen = DefaultScreen(dpy); + if(!parent) + parent = RootWindow(dpy, screen); + + running = grabkeyboard(); + setup(topbar); + drawinput(); + XSync(dpy, False); + run(); + cleanup(); + XCloseDisplay(dpy); + return ret; +} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b89c0da..5434eab 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -21,25 +21,6 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) -/* enums */ -enum { ColFG, ColBG, ColLast }; - -/* typedefs */ -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; - } font; -} DC; /* draw context */ - typedef struct Item Item; struct Item { char *text; @@ -53,22 +34,16 @@ static void calcoffsetsh(void); static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); -static void drawcursor(void); static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); -static void drawtext(const char *text, unsigned long col[ColLast]); static void eprint(const char *errstr, ...); -static unsigned long getcolor(const char *colstr); static Bool grabkeyboard(void); -static void initfont(const char *fontstr); static void kpress(XKeyEvent * e); static void match(char *pattern); static void readstdin(void); static void run(void); static void setup(Bool topbar); -static int textnw(const char *text, unsigned int len); -static int textw(const char *text); #include "config.h" @@ -81,11 +56,9 @@ static int promptw = 0; static int ret = 0; static int screen; static unsigned int mw, mh; -static unsigned int cursor = 0; static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; -static DC dc; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; @@ -98,6 +71,8 @@ static char *(*fstrstr)(const char *, const char *) = strstr; static unsigned int lines = 0; static void (*calcoffsets)(void) = calcoffsetsh; +#include "draw.c" + void appenditem(Item *i, Item **list, Item **last) { if(!(*last)) @@ -161,26 +136,11 @@ cistrstr(const char *s, const char *sub) { void cleanup(void) { - if(dc.font.set) - XFreeFontSet(dpy, dc.font.set); - else - XFreeFont(dpy, dc.font.xfont); - XFreePixmap(dpy, dc.drawable); - XFreeGC(dpy, dc.gc); + dccleanup(); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); } -void -drawcursor(void) { - XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; - - r.x += textnw(text, cursor) + dc.font.height / 2; - - XSetForeground(dpy, dc.gc, dc.norm[ColFG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); -} - void drawmenu(void) { dc.x = 0; @@ -199,7 +159,6 @@ drawmenu(void) { if(cmdw && item && lines == 0) dc.w = cmdw; drawtext(*text ? text : NULL, dc.norm); - drawcursor(); if(curr) { if(lines > 0) drawmenuv(); @@ -243,34 +202,6 @@ drawmenuv(void) { drawtext(NULL, dc.norm); } -void -drawtext(const char *text, unsigned long col[ColLast]) { - char buf[256]; - int i, x, y, h, len, olen; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - - XSetForeground(dpy, dc.gc, col[ColBG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - olen = strlen(text); - h = dc.font.height; - y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); - if(!len) - return; - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dpy, dc.gc, col[ColFG]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); - else - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -} - void eprint(const char *errstr, ...) { va_list ap; @@ -281,16 +212,6 @@ eprint(const char *errstr, ...) { exit(EXIT_FAILURE); } -unsigned long -getcolor(const char *colstr) { - Colormap cmap = DefaultColormap(dpy, screen); - XColor color; - - if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) - eprint("dmenu: cannot allocate color '%s'\n", colstr); - return color.pixel; -} - Bool grabkeyboard(void) { unsigned int len; @@ -304,37 +225,6 @@ grabkeyboard(void) { return len > 0; } -void -initfont(const char *fontstr) { - char *def, **missing = NULL; - int i, n; - - if(!fontstr || fontstr[0] == '\0') - eprint("dmenu: cannot load font: '%s'\n", fontstr); - dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); - if(missing) - XFreeStringList(missing); - if(dc.font.set) { - XFontStruct **xfonts; - char **font_names; - dc.font.ascent = dc.font.descent = 0; - n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); - for(i = 0; i < n; i++) { - dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); - dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); - xfonts++; - } - } - else { - if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) - && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) - eprint("dmenu: 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; -} - void kpress(XKeyEvent * e) { char buf[sizeof text]; @@ -381,9 +271,6 @@ kpress(XKeyEvent * e) { case XK_j: ksym = XK_Return; break; - case XK_k: - text[cursor] = '\0'; - break; case XK_n: ksym = XK_Down; break; @@ -391,67 +278,42 @@ kpress(XKeyEvent * e) { ksym = XK_Up; break; case XK_u: - memmove(text, text + cursor, sizeof text - cursor + 1); - cursor = 0; + text[0] = '\0'; match(text); break; case XK_w: - if(cursor > 0) { - i = cursor; - while(i-- > 0 && text[i] == ' '); - while(i-- > 0 && text[i] != ' '); - memmove(text + i + 1, text + cursor, sizeof text - cursor + 1); - cursor = i + 1; - match(text); - } + if(len == 0) + return; + i = len; + while(i-- > 0 && text[i] == ' '); + while(i-- > 0 && text[i] != ' '); + text[++i] = '\0'; + match(text); break; - case XK_y: - { - FILE *fp; - char *s; - if(!(fp = popen("sselp", "r"))) - eprint("dmenu: cannot popen sselp\n"); - s = fgets(buf, sizeof buf, fp); - pclose(fp); - if(s == NULL) - return; - } - num = strlen(buf); - if(num && buf[num-1] == '\n') - buf[--num] = '\0'; + case XK_x: + execlp("dinput", "dinput", text, NULL); /* todo: argv */ + eprint("dmenu: cannot exec dinput:"); break; } } switch(ksym) { default: - num = MIN(num, sizeof text - cursor); + num = MIN(num, sizeof text); if(num && !iscntrl((int) buf[0])) { - memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); - memcpy(text + cursor, buf, num); - cursor += num; + memcpy(text + len, buf, num + 1); + len += num; match(text); } break; case XK_BackSpace: - if(cursor == 0) + if(len == 0) return; - for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); - memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); - cursor -= i; - match(text); - break; - case XK_Delete: - if(cursor == len) - return; - for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); - memmove(text + cursor, text + cursor + i, sizeof text - cursor); + for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[len - i]); i++); + len -= i; + text[len] = '\0'; match(text); break; case XK_End: - if(cursor < len) { - cursor = len; - break; - } while(next) { sel = curr = next; calcoffsets(); @@ -464,20 +326,10 @@ kpress(XKeyEvent * e) { running = False; return; case XK_Home: - if(sel == item) { - cursor = 0; - break; - } sel = curr = item; calcoffsets(); break; case XK_Left: - if(cursor > 0 && (!sel || !sel->left || lines > 0)) { - while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); - break; - } - if(lines > 0) - return; case XK_Up: if(!sel || !sel->left) return; @@ -508,12 +360,6 @@ kpress(XKeyEvent * e) { running = False; return; case XK_Right: - if(cursor < len) { - while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); - break; - } - if(lines > 0) - return; case XK_Down: if(!sel || !sel->right) return; @@ -527,7 +373,6 @@ kpress(XKeyEvent * e) { if(!sel) return; strncpy(text, sel->text, sizeof text); - cursor = strlen(text); match(text); break; } @@ -690,11 +535,7 @@ setup(Bool topbar) { CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); /* pixmap */ - dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, parent, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); + dcsetup(); if(maxname) cmdw = MIN(textw(maxname), mw / 3); if(prompt) @@ -704,22 +545,6 @@ setup(Bool topbar) { XMapRaised(dpy, win); } -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); -} - -int -textw(const char *text) { - return textnw(text, strlen(text)) + dc.font.height; -} - int main(int argc, char *argv[]) { unsigned int i; diff --git a/dmenubar/draw.c b/dmenubar/draw.c new file mode 100644 index 0000000..6851a34 --- /dev/null +++ b/dmenubar/draw.c @@ -0,0 +1,143 @@ +/* See LICENSE file for copyright and license details. */ + +/* enums */ +enum { ColFG, ColBG, ColLast }; + +/* typedefs */ +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; + } font; +} DC; /* draw context */ + +/* forward declarations */ +static void dccleanup(void); +static void dcsetup(void); +static void drawtext(const char *text, unsigned long col[ColLast]); +static unsigned long getcolor(const char *colstr); +static void initfont(const char *fontstr); +static int textnw(const char *text, unsigned int len); +static int textw(const char *text); + +static DC dc; + +void +dccleanup(void) { + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else + XFreeFont(dpy, dc.font.xfont); + XFreePixmap(dpy, dc.drawable); + XFreeGC(dpy, dc.gc); +} + +void +dcsetup() { + /* style */ + dc.norm[ColBG] = getcolor(normbgcolor); + dc.norm[ColFG] = getcolor(normfgcolor); + dc.sel[ColBG] = getcolor(selbgcolor); + dc.sel[ColFG] = getcolor(selfgcolor); + initfont(font); + + /* pixmap */ + dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); + dc.gc = XCreateGC(dpy, parent, 0, NULL); + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); +} + +void +drawtext(const char *text, unsigned long col[ColLast]) { + char buf[256]; + int i, x, y, h, len, olen; + XRectangle r = { dc.x, dc.y, dc.w, dc.h }; + + XSetForeground(dpy, dc.gc, col[ColBG]); + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + if(!text) + return; + olen = strlen(text); + h = dc.font.height; + y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; + x = dc.x + (h / 2); + /* shorten text if necessary */ + for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); + if(!len) + return; + memcpy(buf, text, len); + if(len < olen) + for(i = len; i && i > len - 3; buf[--i] = '.'); + XSetForeground(dpy, dc.gc, col[ColFG]); + if(dc.font.set) + XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + else + XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); +} + +unsigned long +getcolor(const char *colstr) { + Colormap cmap = DefaultColormap(dpy, screen); + XColor color; + + if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) + eprint("drawtext: cannot allocate color '%s'\n", colstr); + return color.pixel; +} + +void +initfont(const char *fontstr) { + char *def, **missing = NULL; + int i, n; + + if(!fontstr || fontstr[0] == '\0') + eprint("drawtext: cannot load font: '%s'\n", fontstr); + dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); + if(missing) + XFreeStringList(missing); + if(dc.font.set) { + XFontStruct **xfonts; + char **font_names; + dc.font.ascent = dc.font.descent = 0; + n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); + for(i = 0; i < n; i++) { + dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); + dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); + xfonts++; + } + } + else { + if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) + && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) + eprint("drawtext: 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; +} + +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); +} + +int +textw(const char *text) { + return textnw(text, strlen(text)) + dc.font.height; +} From 82ba86fad4ad14b379abf9e845458e8c1cf1fb76 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 12:15:07 +0100 Subject: [PATCH 315/590] typo fixes --- dmenubar/dmenu.1 | 2 +- dmenubar/draw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index c994ad7..f0c45f4 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -18,7 +18,7 @@ dmenu \- dynamic menu .B dmenu_run [<options...>] -.BR dmenu_path +.B dmenu_path .SH DESCRIPTION .SS Overview dmenu is a generic menu for X, originally designed for diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 6851a34..41022f0 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -41,7 +41,7 @@ dccleanup(void) { } void -dcsetup() { +dcsetup(void) { /* style */ dc.norm[ColBG] = getcolor(normbgcolor); dc.norm[ColFG] = getcolor(normfgcolor); From c4184fedda7d712fd4e33d3edfa5a31c8fac7b3d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 12:42:08 +0100 Subject: [PATCH 316/590] overlapping code --- dmenubar/dinput.c | 6 ------ dmenubar/dmenu.c | 6 ------ dmenubar/draw.c | 1 - 3 files changed, 13 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 490380d..52118e5 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -278,11 +278,6 @@ setup(Bool topbar) { } XFreeModifiermap(modmap); - /* style */ - dc.norm[ColBG] = getcolor(normbgcolor); - dc.norm[ColFG] = getcolor(normfgcolor); - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); initfont(font); /* menu window */ @@ -323,7 +318,6 @@ setup(Bool topbar) { DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - /* pixmap */ dcsetup(); if(prompt) promptw = MIN(textw(prompt), mw / 5); diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5434eab..7672eac 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -489,11 +489,6 @@ setup(Bool topbar) { } XFreeModifiermap(modmap); - /* style */ - dc.norm[ColBG] = getcolor(normbgcolor); - dc.norm[ColFG] = getcolor(normfgcolor); - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); initfont(font); /* menu window */ @@ -534,7 +529,6 @@ setup(Bool topbar) { DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - /* pixmap */ dcsetup(); if(maxname) cmdw = MIN(textw(maxname), mw / 3); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 41022f0..932b2f6 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -47,7 +47,6 @@ dcsetup(void) { dc.norm[ColFG] = getcolor(normfgcolor); dc.sel[ColBG] = getcolor(selbgcolor); dc.sel[ColFG] = getcolor(selfgcolor); - initfont(font); /* pixmap */ dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); From 7275278d1cc14c361b0753a603e888c799cde8f7 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 13:29:15 +0100 Subject: [PATCH 317/590] added draw.h --- dmenubar/Makefile | 6 +++--- dmenubar/dinput.c | 23 ++++---------------- dmenubar/dmenu.c | 22 ++++--------------- dmenubar/draw.c | 55 +++++++++++++++++++++-------------------------- dmenubar/draw.h | 45 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 dmenubar/draw.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index d5884da..2f1cada 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -6,7 +6,7 @@ include config.mk SRC = dinput.c dmenu.c draw.c OBJ = ${SRC:.c=.o} -all: options dinput dmenu +all: options draw.o dinput dmenu options: @echo dmenu build options: @@ -18,7 +18,7 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk draw.c +${OBJ}: config.h config.mk draw.h config.h: @echo creating $@ from config.def.h @@ -26,7 +26,7 @@ config.h: .o: @echo CC -o $@ - @${CC} -o $@ $< ${LDFLAGS} + @${CC} -o $@ $< draw.o ${LDFLAGS} clean: @echo cleaning diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 52118e5..f2b504a 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -25,32 +25,27 @@ static void cleanup(void); static void drawcursor(void); static void drawinput(void); -static void eprint(const char *errstr, ...); static Bool grabkeyboard(void); static void kpress(XKeyEvent * e); static void run(void); static void setup(Bool topbar); #include "config.h" +#include "draw.h" /* variables */ static char *prompt = NULL; static char text[4096]; static int promptw = 0; static int ret = 0; -static int screen; -static unsigned int mw, mh; static unsigned int cursor = 0; static unsigned int numlockmask = 0; static Bool running = True; -static Display *dpy; -static Window parent, win; - -#include "draw.c" +static Window win; void cleanup(void) { - dccleanup(); + drawcleanup(); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); } @@ -86,16 +81,6 @@ drawinput(void) XFlush(dpy); } -void -eprint(const char *errstr, ...) { - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - Bool grabkeyboard(void) { unsigned int len; @@ -318,7 +303,7 @@ setup(Bool topbar) { DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - dcsetup(); + drawsetup(); if(prompt) promptw = MIN(textw(prompt), mw / 5); cursor = strlen(text); diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 7672eac..0d89474 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -46,6 +46,7 @@ static void run(void); static void setup(Bool topbar); #include "config.h" +#include "draw.h" /* variables */ static char *maxname = NULL; @@ -54,25 +55,20 @@ static char text[4096]; static int cmdw = 0; static int promptw = 0; static int ret = 0; -static int screen; -static unsigned int mw, mh; static unsigned int numlockmask = 0; static Bool running = True; -static Display *dpy; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; -static Window parent, win; +static Window win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static unsigned int lines = 0; static void (*calcoffsets)(void) = calcoffsetsh; -#include "draw.c" - void appenditem(Item *i, Item **list, Item **last) { if(!(*last)) @@ -136,7 +132,7 @@ cistrstr(const char *s, const char *sub) { void cleanup(void) { - dccleanup(); + drawcleanup(); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); } @@ -202,16 +198,6 @@ drawmenuv(void) { drawtext(NULL, dc.norm); } -void -eprint(const char *errstr, ...) { - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - Bool grabkeyboard(void) { unsigned int len; @@ -529,7 +515,7 @@ setup(Bool topbar) { DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - dcsetup(); + drawsetup(); if(maxname) cmdw = MIN(textw(maxname), mw / 3); if(prompt) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 932b2f6..688bd69 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -1,37 +1,20 @@ /* See LICENSE file for copyright and license details. */ +#include <ctype.h> +#include <locale.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <X11/Xlib.h> +#include "draw.h" -/* enums */ -enum { ColFG, ColBG, ColLast }; - -/* typedefs */ -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; - } font; -} DC; /* draw context */ - -/* forward declarations */ -static void dccleanup(void); -static void dcsetup(void); -static void drawtext(const char *text, unsigned long col[ColLast]); -static unsigned long getcolor(const char *colstr); -static void initfont(const char *fontstr); -static int textnw(const char *text, unsigned int len); -static int textw(const char *text); - -static DC dc; +/* macros */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) void -dccleanup(void) { +drawcleanup(void) { if(dc.font.set) XFreeFontSet(dpy, dc.font.set); else @@ -41,7 +24,7 @@ dccleanup(void) { } void -dcsetup(void) { +drawsetup(void) { /* style */ dc.norm[ColBG] = getcolor(normbgcolor); dc.norm[ColFG] = getcolor(normfgcolor); @@ -84,6 +67,16 @@ drawtext(const char *text, unsigned long col[ColLast]) { XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); } +void +eprint(const char *errstr, ...) { + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + unsigned long getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); diff --git a/dmenubar/draw.h b/dmenubar/draw.h new file mode 100644 index 0000000..79db37e --- /dev/null +++ b/dmenubar/draw.h @@ -0,0 +1,45 @@ +/* See LICENSE file for copyright and license details. */ + +/* enums */ +enum { ColFG, ColBG, ColLast }; + +/* typedefs */ +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; + } font; +} DC; /* draw context */ + +/* forward declarations */ +void drawcleanup(void); +void drawsetup(void); +void drawtext(const char *text, unsigned long col[ColLast]); +void eprint(const char *errstr, ...); +unsigned long getcolor(const char *colstr); +void initfont(const char *fontstr); +int textnw(const char *text, unsigned int len); +int textw(const char *text); + +/* variables */ +Display *dpy; +DC dc; +int screen; +unsigned int mw, mh; +unsigned int spaceitem; +Window parent; + +/* style */ +const char *font; +const char *normbgcolor; +const char *normfgcolor; +const char *selbgcolor; +const char *selfgcolor; From 2d52820bf0c6aef312744882a8b65d5a49a912ba Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 13:31:11 +0100 Subject: [PATCH 318/590] cleaned up --- dmenubar/dmenu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0d89474..339f949 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -37,7 +37,6 @@ static void cleanup(void); static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); -static void eprint(const char *errstr, ...); static Bool grabkeyboard(void); static void kpress(XKeyEvent * e); static void match(char *pattern); From 5eda52ee53828ee8777992b1d740337b2e2fb63b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 13:49:24 +0100 Subject: [PATCH 319/590] cleaned up --- dmenubar/dinput.c | 6 ++++++ dmenubar/dmenu.c | 16 +++++++++++++++- dmenubar/draw.h | 21 ++++++++++----------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index f2b504a..d8f2515 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -43,6 +43,12 @@ static unsigned int numlockmask = 0; static Bool running = True; static Window win; +Display *dpy; +DC dc; +int screen; +unsigned int mw, mh; +Window parent; + void cleanup(void) { drawcleanup(); diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 339f949..8b40aa7 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -54,6 +54,7 @@ static char text[4096]; static int cmdw = 0; static int promptw = 0; static int ret = 0; +static unsigned int lines = 0; static unsigned int numlockmask = 0; static Bool running = True; static Item *allitems = NULL; /* first of all items */ @@ -65,9 +66,14 @@ static Item *curr = NULL; static Window win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; -static unsigned int lines = 0; static void (*calcoffsets)(void) = calcoffsetsh; +Display *dpy; +DC dc; +int screen; +unsigned int mw, mh; +Window parent; + void appenditem(Item *i, Item **list, Item **last) { if(!(*last)) @@ -131,6 +137,14 @@ cistrstr(const char *s, const char *sub) { void cleanup(void) { + Item *itm; + + while(allitems) { + itm = allitems->next; + free(allitems->text); + free(allitems); + allitems = itm; + } drawcleanup(); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); diff --git a/dmenubar/draw.h b/dmenubar/draw.h index 79db37e..b6615ab 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw.h @@ -30,16 +30,15 @@ int textnw(const char *text, unsigned int len); int textw(const char *text); /* variables */ -Display *dpy; -DC dc; -int screen; -unsigned int mw, mh; -unsigned int spaceitem; -Window parent; +extern Display *dpy; +extern DC dc; +extern int screen; +extern unsigned int mw, mh; +extern Window parent; /* style */ -const char *font; -const char *normbgcolor; -const char *normfgcolor; -const char *selbgcolor; -const char *selfgcolor; +extern const char *font; +extern const char *normbgcolor; +extern const char *normfgcolor; +extern const char *selbgcolor; +extern const char *selfgcolor; From f70de02be105adfa172ff5e7cd9f562c2c2af1ff Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Jun 2010 14:29:32 +0100 Subject: [PATCH 320/590] fixed makefile --- dmenubar/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 2f1cada..da5344b 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -6,7 +6,7 @@ include config.mk SRC = dinput.c dmenu.c draw.c OBJ = ${SRC:.c=.o} -all: options draw.o dinput dmenu +all: options dinput dmenu options: @echo dmenu build options: @@ -24,9 +24,13 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -.o: +dinput: dinput.o draw.o @echo CC -o $@ - @${CC} -o $@ $< draw.o ${LDFLAGS} + @${CC} -o $@ $+ ${LDFLAGS} + +dmenu: dmenu.o draw.o + @echo CC -o $@ + @${CC} -o $@ $+ ${LDFLAGS} clean: @echo cleaning From 28bf1ca60b1924caa4db7e5d481c601e713e1c64 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 24 Jun 2010 11:30:30 +0100 Subject: [PATCH 321/590] fixed static symbols in config.def.h --- dmenubar/config.def.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 3e6c616..cda3b2a 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -1,9 +1,9 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -static const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; -static const char *normbgcolor = "#cccccc"; -static const char *normfgcolor = "#000000"; -static const char *selbgcolor = "#0066ff"; -static const char *selfgcolor = "#ffffff"; -static unsigned int spaceitem = 30; /* px between menu items */ +const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; +const char *normbgcolor = "#cccccc"; +const char *normfgcolor = "#000000"; +const char *selbgcolor = "#0066ff"; +const char *selfgcolor = "#ffffff"; +unsigned int spaceitem = 30; /* px between menu items */ From 0c0bcf7cdb42deab46d31b2c2474c6722a94e6b6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 24 Jun 2010 14:22:34 +0100 Subject: [PATCH 322/590] fixed offsets, updated eprint, cleaned up --- dmenubar/dinput.c | 5 +++-- dmenubar/dmenu.c | 56 +++++++++++++++++++++++++---------------------- dmenubar/draw.c | 12 ++++++---- dmenubar/draw.h | 2 +- 4 files changed, 42 insertions(+), 33 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index d8f2515..15f5e26 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -164,7 +164,7 @@ kpress(XKeyEvent * e) { FILE *fp; char *s; if(!(fp = popen("sselp", "r"))) - eprint("dinput: cannot popen sselp\n"); + eprint("cannot popen sselp\n"); s = fgets(buf, sizeof buf, fp); pclose(fp); if(s == NULL) @@ -322,6 +322,7 @@ main(int argc, char *argv[]) { Bool topbar = True; /* command line args */ + progname = argv[0]; for(i = 1; i < argc; i++) if(!strcmp(argv[i], "-b")) topbar = False; @@ -356,7 +357,7 @@ main(int argc, char *argv[]) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "dinput: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) - eprint("dinput: cannot open display\n"); + eprint("cannot open display\n"); screen = DefaultScreen(dpy); if(!parent) parent = RootWindow(dpy, screen); diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8b40aa7..878bc95 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -34,6 +34,7 @@ static void calcoffsetsh(void); static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); +static void dinput(void); static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); @@ -89,28 +90,25 @@ void calcoffsetsh(void) { unsigned int w; - if(!curr) - return; - w = promptw + cmdw + 2 * spaceitem; - for(next = curr; next && w < mw; next=next->right) - w += MIN(textw(next->text), mw / 3); - w = promptw + cmdw + 2 * spaceitem; - for(prev = curr; prev && prev->left && w < mw; prev=prev->left) - w += MIN(textw(prev->left->text), mw / 3); + w = promptw + cmdw + (2 * spaceitem); + for(next = curr; next; next = next->right) + if((w += MIN(textw(next->text), mw / 3)) > mw) + break; + w = promptw + cmdw + (2 * spaceitem); + for(prev = curr; prev && prev->left; prev = prev->left) + if((w += MIN(textw(prev->left->text), mw / 3)) > mw) + break; } void calcoffsetsv(void) { - unsigned int h; + unsigned int i; - if(!curr) - return; - h = (dc.font.height + 2) * lines; - for(next = curr; next && h > 0; next = next->right) - h -= dc.font.height + 2; - h = (dc.font.height + 2) * lines; - for(prev = curr; prev && prev->left && h > 0; prev = prev->left) - h -= dc.font.height + 2; + next = prev = curr; + for(i = 0; i < lines && next; i++) + next = next->right; + for(i = 0; i < lines && prev && prev->left; i++) + prev = prev->left; } char * @@ -150,6 +148,13 @@ cleanup(void) { XUngrabKeyboard(dpy, CurrentTime); } +void +dinput(void) { + cleanup(); + execlp("dinput", "dinput", text, NULL); /* todo: argv */ + eprint("cannot exec dinput\n"); +} + void drawmenu(void) { dc.x = 0; @@ -290,8 +295,7 @@ kpress(XKeyEvent * e) { match(text); break; case XK_x: - execlp("dinput", "dinput", text, NULL); /* todo: argv */ - eprint("dmenu: cannot exec dinput:"); + dinput(); break; } } @@ -369,10 +373,9 @@ kpress(XKeyEvent * e) { } break; case XK_Tab: - if(!sel) - return; - strncpy(text, sel->text, sizeof text); - match(text); + if(sel) + strncpy(text, sel->text, sizeof text); + dinput(); break; } drawmenu(); @@ -431,11 +434,11 @@ readstdin(void) { if(buf[len-1] == '\n') buf[--len] = '\0'; if(!(p = strdup(buf))) - eprint("dmenu: cannot strdup %u bytes\n", len); + eprint("cannot strdup %u bytes\n", len); if((max = MAX(max, len)) == len) maxname = p; if(!(new = malloc(sizeof *new))) - eprint("dmenu: cannot malloc %u bytes\n", sizeof *new); + eprint("cannot malloc %u bytes\n", sizeof *new); new->next = new->left = new->right = NULL; new->text = p; if(!i) @@ -544,6 +547,7 @@ main(int argc, char *argv[]) { Bool topbar = True; /* command line args */ + progname = argv[0]; for(i = 1; i < argc; i++) if(!strcmp(argv[i], "-i")) { fstrncmp = strncasecmp; @@ -585,7 +589,7 @@ main(int argc, char *argv[]) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "dmenu: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) - eprint("dmenu: cannot open display\n"); + eprint("cannot open display\n"); screen = DefaultScreen(dpy); if(!parent) parent = RootWindow(dpy, screen); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 688bd69..6791b97 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -13,6 +13,9 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +/* variables */ +char *progname; + void drawcleanup(void) { if(dc.font.set) @@ -71,6 +74,7 @@ void eprint(const char *errstr, ...) { va_list ap; + fprintf(stderr, "%s: ", progname); va_start(ap, errstr); vfprintf(stderr, errstr, ap); va_end(ap); @@ -83,7 +87,7 @@ getcolor(const char *colstr) { XColor color; if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) - eprint("drawtext: cannot allocate color '%s'\n", colstr); + eprint("cannot allocate color '%s'\n", colstr); return color.pixel; } @@ -92,8 +96,8 @@ initfont(const char *fontstr) { char *def, **missing = NULL; int i, n; - if(!fontstr || fontstr[0] == '\0') - eprint("drawtext: cannot load font: '%s'\n", fontstr); + if(!fontstr || !*fontstr) + eprint("cannot load null font\n"); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); @@ -111,7 +115,7 @@ initfont(const char *fontstr) { else { if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) - eprint("drawtext: cannot load font: '%s'\n", fontstr); + eprint("cannot load font '%s'\n", fontstr); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; } diff --git a/dmenubar/draw.h b/dmenubar/draw.h index b6615ab..d1f1a7c 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw.h @@ -30,13 +30,13 @@ int textnw(const char *text, unsigned int len); int textw(const char *text); /* variables */ +extern char *progname; extern Display *dpy; extern DC dc; extern int screen; extern unsigned int mw, mh; extern Window parent; -/* style */ extern const char *font; extern const char *normbgcolor; extern const char *normfgcolor; From 2b8a4a867143a52e317ba960572446edde5f3c02 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 24 Jun 2010 16:18:18 +0100 Subject: [PATCH 323/590] decoupled draw.c from dmenu & dinput --- dmenubar/dinput.c | 40 +++++++++-------- dmenubar/dmenu.c | 49 +++++++++++---------- dmenubar/draw.c | 107 ++++++++++++++++++++++------------------------ dmenubar/draw.h | 30 +++++-------- 4 files changed, 110 insertions(+), 116 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 15f5e26..39889b3 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -38,20 +38,18 @@ static char *prompt = NULL; static char text[4096]; static int promptw = 0; static int ret = 0; +static int screen; static unsigned int cursor = 0; static unsigned int numlockmask = 0; +static unsigned int mw, mh; static Bool running = True; -static Window win; - -Display *dpy; -DC dc; -int screen; -unsigned int mw, mh; -Window parent; +static DC dc; +static Display *dpy; +static Window win, parent; void cleanup(void) { - drawcleanup(); + cleanupdraw(&dc); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); } @@ -60,7 +58,7 @@ void drawcursor(void) { XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; - r.x += textnw(text, cursor) + dc.font.height / 2; + r.x += textnw(&dc, text, cursor) + dc.font.height / 2; XSetForeground(dpy, dc.gc, dc.norm[ColFG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); @@ -73,15 +71,15 @@ drawinput(void) dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, dc.norm); + drawtext(&dc, NULL, dc.norm); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(prompt, dc.sel); + drawtext(&dc, prompt, dc.sel); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(*text ? text : NULL, dc.norm); + drawtext(&dc, *text ? text : NULL, dc.norm); drawcursor(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -269,15 +267,21 @@ setup(Bool topbar) { } XFreeModifiermap(modmap); - initfont(font); + dc.dpy = dpy; + dc.norm[ColBG] = getcolor(&dc, normbgcolor); + dc.norm[ColFG] = getcolor(&dc, normfgcolor); + dc.sel[ColBG] = getcolor(&dc, selbgcolor); + dc.sel[ColFG] = getcolor(&dc, selfgcolor); + initfont(&dc, font); + fprintf(stderr, "dc.font.xfont: %u\n", (size_t)dc.font.xfont); - /* menu window */ + /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; - /* menu window geometry */ - mh = (dc.font.height + 2); + /* input window geometry */ + mh = dc.font.height + 2; #if XINERAMA if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; @@ -309,9 +313,9 @@ setup(Bool topbar) { DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - drawsetup(); + setupdraw(&dc, win); if(prompt) - promptw = MIN(textw(prompt), mw / 5); + promptw = MIN(textw(&dc, prompt), mw / 5); cursor = strlen(text); XMapRaised(dpy, win); } diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 878bc95..0b42073 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -55,26 +55,24 @@ static char text[4096]; static int cmdw = 0; static int promptw = 0; static int ret = 0; +static int screen; static unsigned int lines = 0; static unsigned int numlockmask = 0; +static unsigned int mw, mh; static Bool running = True; +static DC dc; +static Display *dpy; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; -static Window win; +static Window win, parent; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static void (*calcoffsets)(void) = calcoffsetsh; -Display *dpy; -DC dc; -int screen; -unsigned int mw, mh; -Window parent; - void appenditem(Item *i, Item **list, Item **last) { if(!(*last)) @@ -92,11 +90,11 @@ calcoffsetsh(void) { w = promptw + cmdw + (2 * spaceitem); for(next = curr; next; next = next->right) - if((w += MIN(textw(next->text), mw / 3)) > mw) + if((w += MIN(textw(&dc, next->text), mw / 3)) > mw) break; w = promptw + cmdw + (2 * spaceitem); for(prev = curr; prev && prev->left; prev = prev->left) - if((w += MIN(textw(prev->left->text), mw / 3)) > mw) + if((w += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) break; } @@ -143,7 +141,7 @@ cleanup(void) { free(allitems); allitems = itm; } - drawcleanup(); + cleanupdraw(&dc); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); } @@ -161,18 +159,18 @@ drawmenu(void) { dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(NULL, dc.norm); + drawtext(&dc, NULL, dc.norm); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(prompt, dc.sel); + drawtext(&dc, prompt, dc.sel); dc.x += dc.w; } dc.w = mw - dc.x; /* print command */ if(cmdw && item && lines == 0) dc.w = cmdw; - drawtext(*text ? text : NULL, dc.norm); + drawtext(&dc, *text ? text : NULL, dc.norm); if(curr) { if(lines > 0) drawmenuv(); @@ -189,16 +187,16 @@ drawmenuh(void) { dc.x += cmdw; dc.w = spaceitem; - drawtext(curr->left ? "<" : NULL, dc.norm); + drawtext(&dc, curr->left ? "<" : NULL, dc.norm); dc.x += dc.w; for(i = curr; i != next; i=i->right) { - dc.w = MIN(textw(i->text), mw / 3); - drawtext(i->text, (sel == i) ? dc.sel : dc.norm); + dc.w = MIN(textw(&dc, i->text), mw / 3); + drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } dc.w = spaceitem; dc.x = mw - dc.w; - drawtext(next ? ">" : NULL, dc.norm); + drawtext(&dc, next ? ">" : NULL, dc.norm); } void @@ -209,11 +207,11 @@ drawmenuv(void) { dc.h = dc.font.height + 2; dc.y = dc.h; for(i = curr; i != next; i=i->right) { - drawtext(i->text, (sel == i) ? dc.sel : dc.norm); + drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm); dc.y += dc.h; } dc.h = mh - dc.y; - drawtext(NULL, dc.norm); + drawtext(&dc, NULL, dc.norm); } Bool @@ -491,7 +489,12 @@ setup(Bool topbar) { } XFreeModifiermap(modmap); - initfont(font); + dc.dpy = dpy; + dc.norm[ColBG] = getcolor(&dc, normbgcolor); + dc.norm[ColFG] = getcolor(&dc, normfgcolor); + dc.sel[ColBG] = getcolor(&dc, selbgcolor); + dc.sel[ColFG] = getcolor(&dc, selfgcolor); + initfont(&dc, font); /* menu window */ wa.override_redirect = True; @@ -531,11 +534,11 @@ setup(Bool topbar) { DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - drawsetup(); + setupdraw(&dc, win); if(maxname) - cmdw = MIN(textw(maxname), mw / 3); + cmdw = MIN(textw(&dc, maxname), mw / 3); if(prompt) - promptw = MIN(textw(prompt), mw / 5); + promptw = MIN(textw(&dc, prompt), mw / 5); text[0] = '\0'; match(text); XMapRaised(dpy, win); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 6791b97..9142905 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -14,126 +14,123 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) /* variables */ -char *progname; +const char *progname; void -drawcleanup(void) { - if(dc.font.set) - XFreeFontSet(dpy, dc.font.set); +cleanupdraw(DC *dc) { + if(dc->font.set) + XFreeFontSet(dc->dpy, dc->font.set); else - XFreeFont(dpy, dc.font.xfont); - XFreePixmap(dpy, dc.drawable); - XFreeGC(dpy, dc.gc); + XFreeFont(dc->dpy, dc->font.xfont); + XFreePixmap(dc->dpy, dc->drawable); + XFreeGC(dc->dpy, dc->gc); } void -drawsetup(void) { - /* style */ - dc.norm[ColBG] = getcolor(normbgcolor); - dc.norm[ColFG] = getcolor(normfgcolor); - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); +setupdraw(DC *dc, Window w) { + XWindowAttributes wa; - /* pixmap */ - dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); - dc.gc = XCreateGC(dpy, parent, 0, NULL); - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); + XGetWindowAttributes(dc->dpy, w, &wa); + dc->drawable = XCreatePixmap(dc->dpy, w, wa.width, wa.height, + DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); + dc->gc = XCreateGC(dc->dpy, w, 0, NULL); + XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc->font.set) + XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); } void -drawtext(const char *text, unsigned long col[ColLast]) { +drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { char buf[256]; int i, x, y, h, len, olen; - 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]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + XSetForeground(dc->dpy, dc->gc, col[ColBG]); + XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); if(!text) return; olen = strlen(text); - h = dc.font.height; - y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); + h = dc->font.height; + y = dc->y + ((h+2) / 2) - (h / 2) + dc->font.ascent; + x = dc->x + (h / 2); /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); + for(len = MIN(olen, sizeof buf); len && textnw(dc, text, len) > dc->w - h; len--); if(!len) return; memcpy(buf, text, len); if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dpy, dc.gc, col[ColFG]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); + XSetForeground(dc->dpy, dc->gc, col[ColFG]); + if(dc->font.set) + XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len); else - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); + XDrawString(dc->dpy, dc->drawable, dc->gc, x, y, buf, len); } void -eprint(const char *errstr, ...) { +eprint(const char *fmt, ...) { va_list ap; fprintf(stderr, "%s: ", progname); - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); va_end(ap); exit(EXIT_FAILURE); } unsigned long -getcolor(const char *colstr) { - Colormap cmap = DefaultColormap(dpy, screen); +getcolor(DC *dc, const char *colstr) { + Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); XColor color; - if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) + if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) eprint("cannot allocate color '%s'\n", colstr); return color.pixel; } void -initfont(const char *fontstr) { +initfont(DC *dc, const char *fontstr) { char *def, **missing = NULL; int i, n; if(!fontstr || !*fontstr) eprint("cannot load null font\n"); - dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); + dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); - if(dc.font.set) { + if(dc->font.set) { XFontStruct **xfonts; char **font_names; - dc.font.ascent = dc.font.descent = 0; - n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); + dc->font.ascent = dc->font.descent = 0; + n = XFontsOfFontSet(dc->font.set, &xfonts, &font_names); for(i = 0; i < n; i++) { - dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent); - dc.font.descent = MAX(dc.font.descent, (*xfonts)->descent); + dc->font.ascent = MAX(dc->font.ascent, (*xfonts)->ascent); + dc->font.descent = MAX(dc->font.descent, (*xfonts)->descent); xfonts++; } } else { - if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) - && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) + if(!(dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)) + && !(dc->font.xfont = XLoadQueryFont(dc->dpy, "fixed"))) eprint("cannot load font '%s'\n", fontstr); - dc.font.ascent = dc.font.xfont->ascent; - dc.font.descent = dc.font.xfont->descent; + dc->font.ascent = dc->font.xfont->ascent; + dc->font.descent = dc->font.xfont->descent; } - dc.font.height = dc.font.ascent + dc.font.descent; + dc->font.height = dc->font.ascent + dc->font.descent; } int -textnw(const char *text, unsigned int len) { +textnw(DC *dc, const char *text, unsigned int len) { XRectangle r; - if(dc.font.set) { - XmbTextExtents(dc.font.set, text, len, NULL, &r); + if(dc->font.set) { + XmbTextExtents(dc->font.set, text, len, NULL, &r); return r.width; } - return XTextWidth(dc.font.xfont, text, len); + return XTextWidth(dc->font.xfont, text, len); } int -textw(const char *text) { - return textnw(text, strlen(text)) + dc.font.height; +textw(DC *dc, const char *text) { + return textnw(dc, text, strlen(text)) + dc->font.height; } diff --git a/dmenubar/draw.h b/dmenubar/draw.h index d1f1a7c..e4f937a 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw.h @@ -9,6 +9,7 @@ typedef struct { unsigned long norm[ColLast]; unsigned long sel[ColLast]; Drawable drawable; + Display *dpy; GC gc; struct { XFontStruct *xfont; @@ -20,25 +21,14 @@ typedef struct { } DC; /* draw context */ /* forward declarations */ -void drawcleanup(void); -void drawsetup(void); -void drawtext(const char *text, unsigned long col[ColLast]); -void eprint(const char *errstr, ...); -unsigned long getcolor(const char *colstr); -void initfont(const char *fontstr); -int textnw(const char *text, unsigned int len); -int textw(const char *text); +void cleanupdraw(DC *dc); +void setupdraw(DC *dc, Window w); +void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); +void eprint(const char *fmt, ...); +unsigned long getcolor(DC *dc, const char *colstr); +void initfont(DC *dc, const char *fontstr); +int textnw(DC *dc, const char *text, unsigned int len); +int textw(DC *dc, const char *text); /* variables */ -extern char *progname; -extern Display *dpy; -extern DC dc; -extern int screen; -extern unsigned int mw, mh; -extern Window parent; - -extern const char *font; -extern const char *normbgcolor; -extern const char *normfgcolor; -extern const char *selbgcolor; -extern const char *selfgcolor; +extern const char *progname; From e5ee718f6635cde895545a4e4e89c53a8ee37902 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 24 Jun 2010 16:24:04 +0100 Subject: [PATCH 324/590] removed colors from dc --- dmenubar/dinput.c | 18 ++++++++++-------- dmenubar/dmenu.c | 26 ++++++++++++++------------ dmenubar/draw.h | 2 -- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 39889b3..cd13b1d 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -42,6 +42,8 @@ static int screen; static unsigned int cursor = 0; static unsigned int numlockmask = 0; static unsigned int mw, mh; +static unsigned long normcol[ColLast]; +static unsigned long selcol[ColLast]; static Bool running = True; static DC dc; static Display *dpy; @@ -60,7 +62,7 @@ drawcursor(void) { r.x += textnw(&dc, text, cursor) + dc.font.height / 2; - XSetForeground(dpy, dc.gc, dc.norm[ColFG]); + XSetForeground(dpy, dc.gc, normcol[ColFG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); } @@ -71,15 +73,15 @@ drawinput(void) dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, dc.norm); + drawtext(&dc, NULL, normcol); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, dc.sel); + drawtext(&dc, prompt, selcol); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(&dc, *text ? text : NULL, dc.norm); + drawtext(&dc, *text ? text : NULL, normcol); drawcursor(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -268,10 +270,10 @@ setup(Bool topbar) { XFreeModifiermap(modmap); dc.dpy = dpy; - dc.norm[ColBG] = getcolor(&dc, normbgcolor); - dc.norm[ColFG] = getcolor(&dc, normfgcolor); - dc.sel[ColBG] = getcolor(&dc, selbgcolor); - dc.sel[ColFG] = getcolor(&dc, selfgcolor); + normcol[ColBG] = getcolor(&dc, normbgcolor); + normcol[ColFG] = getcolor(&dc, normfgcolor); + selcol[ColBG] = getcolor(&dc, selbgcolor); + selcol[ColFG] = getcolor(&dc, selfgcolor); initfont(&dc, font); fprintf(stderr, "dc.font.xfont: %u\n", (size_t)dc.font.xfont); diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0b42073..6641ba2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -59,6 +59,8 @@ static int screen; static unsigned int lines = 0; static unsigned int numlockmask = 0; static unsigned int mw, mh; +static unsigned long normcol[ColLast]; +static unsigned long selcol[ColLast]; static Bool running = True; static DC dc; static Display *dpy; @@ -159,18 +161,18 @@ drawmenu(void) { dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, dc.norm); + drawtext(&dc, NULL, normcol); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, dc.sel); + drawtext(&dc, prompt, selcol); dc.x += dc.w; } dc.w = mw - dc.x; /* print command */ if(cmdw && item && lines == 0) dc.w = cmdw; - drawtext(&dc, *text ? text : NULL, dc.norm); + drawtext(&dc, *text ? text : NULL, normcol); if(curr) { if(lines > 0) drawmenuv(); @@ -187,16 +189,16 @@ drawmenuh(void) { dc.x += cmdw; dc.w = spaceitem; - drawtext(&dc, curr->left ? "<" : NULL, dc.norm); + drawtext(&dc, curr->left ? "<" : NULL, normcol); dc.x += dc.w; for(i = curr; i != next; i=i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); - drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm); + drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.x += dc.w; } dc.w = spaceitem; dc.x = mw - dc.w; - drawtext(&dc, next ? ">" : NULL, dc.norm); + drawtext(&dc, next ? ">" : NULL, normcol); } void @@ -207,11 +209,11 @@ drawmenuv(void) { dc.h = dc.font.height + 2; dc.y = dc.h; for(i = curr; i != next; i=i->right) { - drawtext(&dc, i->text, (sel == i) ? dc.sel : dc.norm); + drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.y += dc.h; } dc.h = mh - dc.y; - drawtext(&dc, NULL, dc.norm); + drawtext(&dc, NULL, normcol); } Bool @@ -490,10 +492,10 @@ setup(Bool topbar) { XFreeModifiermap(modmap); dc.dpy = dpy; - dc.norm[ColBG] = getcolor(&dc, normbgcolor); - dc.norm[ColFG] = getcolor(&dc, normfgcolor); - dc.sel[ColBG] = getcolor(&dc, selbgcolor); - dc.sel[ColFG] = getcolor(&dc, selfgcolor); + normcol[ColBG] = getcolor(&dc, normbgcolor); + normcol[ColFG] = getcolor(&dc, normfgcolor); + selcol[ColBG] = getcolor(&dc, selbgcolor); + selcol[ColFG] = getcolor(&dc, selfgcolor); initfont(&dc, font); /* menu window */ diff --git a/dmenubar/draw.h b/dmenubar/draw.h index e4f937a..1705909 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw.h @@ -6,8 +6,6 @@ enum { ColFG, ColBG, ColLast }; /* typedefs */ typedef struct { int x, y, w, h; - unsigned long norm[ColLast]; - unsigned long sel[ColLast]; Drawable drawable; Display *dpy; GC gc; From 920a13026331e629af87fa1a75c1235e7d6b0a5f Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 24 Jun 2010 17:44:35 +0100 Subject: [PATCH 325/590] moved draw.c to libdraw.a --- dmenubar/Makefile | 16 ++--- dmenubar/config.mk | 4 +- dmenubar/dinput.c | 1 - dmenubar/draw.c | 136 ------------------------------------ dmenubar/draw/Makefile | 26 +++++++ dmenubar/draw/cleanupdraw.c | 13 ++++ dmenubar/{ => draw}/draw.h | 3 +- dmenubar/draw/drawtext.c | 34 +++++++++ dmenubar/draw/eprint.c | 18 +++++ dmenubar/draw/getcolor.c | 13 ++++ dmenubar/draw/initfont.c | 36 ++++++++++ dmenubar/draw/setupdraw.c | 16 +++++ dmenubar/draw/textnw.c | 14 ++++ dmenubar/draw/textw.c | 9 +++ 14 files changed, 191 insertions(+), 148 deletions(-) delete mode 100644 dmenubar/draw.c create mode 100644 dmenubar/draw/Makefile create mode 100644 dmenubar/draw/cleanupdraw.c rename dmenubar/{ => draw}/draw.h (97%) create mode 100644 dmenubar/draw/drawtext.c create mode 100644 dmenubar/draw/eprint.c create mode 100644 dmenubar/draw/getcolor.c create mode 100644 dmenubar/draw/initfont.c create mode 100644 dmenubar/draw/setupdraw.c create mode 100644 dmenubar/draw/textnw.c create mode 100644 dmenubar/draw/textw.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index da5344b..90f178b 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = dinput.c dmenu.c draw.c +SRC = dinput.c dmenu.c OBJ = ${SRC:.c=.o} all: options dinput dmenu @@ -18,28 +18,28 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk draw.h +${OBJ}: config.h config.mk draw/libdraw.a config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -dinput: dinput.o draw.o +.o: @echo CC -o $@ - @${CC} -o $@ $+ ${LDFLAGS} + @${CC} -o $@ $< ${LDFLAGS} -dmenu: dmenu.o draw.o - @echo CC -o $@ - @${CC} -o $@ $+ ${LDFLAGS} +draw/libdraw.a: + @cd draw && make clean: @echo cleaning @rm -f dinput dmenu ${OBJ} dmenu-${VERSION}.tar.gz + @cd draw && make clean dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run draw ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/config.mk b/dmenubar/config.mk index eb410dc..431754e 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -15,8 +15,8 @@ XINERAMALIBS = -L${X11LIB} -lXinerama XINERAMAFLAGS = -DXINERAMA # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} +INCS = -I. -Idraw -I/usr/include -I${X11INC} +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -Ldraw -ldraw ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index cd13b1d..283b018 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -5,7 +5,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <strings.h> #include <unistd.h> #include <X11/keysym.h> #include <X11/Xlib.h> diff --git a/dmenubar/draw.c b/dmenubar/draw.c deleted file mode 100644 index 9142905..0000000 --- a/dmenubar/draw.c +++ /dev/null @@ -1,136 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <ctype.h> -#include <locale.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <X11/Xlib.h> -#include "draw.h" - -/* macros */ -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -/* variables */ -const char *progname; - -void -cleanupdraw(DC *dc) { - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); - else - XFreeFont(dc->dpy, dc->font.xfont); - XFreePixmap(dc->dpy, dc->drawable); - XFreeGC(dc->dpy, dc->gc); -} - -void -setupdraw(DC *dc, Window w) { - XWindowAttributes wa; - - XGetWindowAttributes(dc->dpy, w, &wa); - dc->drawable = XCreatePixmap(dc->dpy, w, wa.width, wa.height, - DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); - dc->gc = XCreateGC(dc->dpy, w, 0, NULL); - XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc->font.set) - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); -} - -void -drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - char buf[256]; - int i, x, y, h, len, olen; - XRectangle r = { dc->x, dc->y, dc->w, dc->h }; - - XSetForeground(dc->dpy, dc->gc, col[ColBG]); - XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); - if(!text) - return; - olen = strlen(text); - h = dc->font.height; - y = dc->y + ((h+2) / 2) - (h / 2) + dc->font.ascent; - x = dc->x + (h / 2); - /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(dc, text, len) > dc->w - h; len--); - if(!len) - return; - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dc->dpy, dc->gc, col[ColFG]); - if(dc->font.set) - XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len); - else - XDrawString(dc->dpy, dc->drawable, dc->gc, x, y, buf, len); -} - -void -eprint(const char *fmt, ...) { - va_list ap; - - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - -unsigned long -getcolor(DC *dc, const char *colstr) { - Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); - XColor color; - - if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) - eprint("cannot allocate color '%s'\n", colstr); - return color.pixel; -} - -void -initfont(DC *dc, const char *fontstr) { - char *def, **missing = NULL; - int i, n; - - if(!fontstr || !*fontstr) - eprint("cannot load null font\n"); - dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def); - if(missing) - XFreeStringList(missing); - if(dc->font.set) { - XFontStruct **xfonts; - char **font_names; - dc->font.ascent = dc->font.descent = 0; - n = XFontsOfFontSet(dc->font.set, &xfonts, &font_names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, (*xfonts)->ascent); - dc->font.descent = MAX(dc->font.descent, (*xfonts)->descent); - xfonts++; - } - } - else { - if(!(dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)) - && !(dc->font.xfont = XLoadQueryFont(dc->dpy, "fixed"))) - eprint("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; -} - -int -textnw(DC *dc, 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); -} - -int -textw(DC *dc, const char *text) { - return textnw(dc, text, strlen(text)) + dc->font.height; -} diff --git a/dmenubar/draw/Makefile b/dmenubar/draw/Makefile new file mode 100644 index 0000000..1f72b61 --- /dev/null +++ b/dmenubar/draw/Makefile @@ -0,0 +1,26 @@ +# libdraw - dynamic drawing library +# See LICENSE file for copyright and license details. + +include ../config.mk + +SRC = cleanupdraw.c setupdraw.c drawtext.c eprint.c getcolor.c initfont.c \ +textnw.c textw.c +OBJ = ${SRC:.c=.o} + +all: libdraw.a + +.c.o: + @echo CC $< + @${CC} -c ${CFLAGS} $< + +${OBJ}: ../config.mk draw.h + +libdraw.a: ${OBJ} + @echo AR $@ + @ar cr $@ $+ + +clean: + @echo cleaning libdraw + @rm -f libdraw.a ${OBJ} + +.PHONY: all options clean diff --git a/dmenubar/draw/cleanupdraw.c b/dmenubar/draw/cleanupdraw.c new file mode 100644 index 0000000..28bce13 --- /dev/null +++ b/dmenubar/draw/cleanupdraw.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> +#include "draw.h" + +void +cleanupdraw(DC *dc) { + if(dc->font.set) + XFreeFontSet(dc->dpy, dc->font.set); + else + XFreeFont(dc->dpy, dc->font.xfont); + XFreePixmap(dc->dpy, dc->drawable); + XFreeGC(dc->dpy, dc->gc); +} diff --git a/dmenubar/draw.h b/dmenubar/draw/draw.h similarity index 97% rename from dmenubar/draw.h rename to dmenubar/draw/draw.h index 1705909..4646a18 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw/draw.h @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> /* enums */ enum { ColFG, ColBG, ColLast }; @@ -20,11 +21,11 @@ typedef struct { /* forward declarations */ void cleanupdraw(DC *dc); -void setupdraw(DC *dc, Window w); void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); void eprint(const char *fmt, ...); unsigned long getcolor(DC *dc, const char *colstr); void initfont(DC *dc, const char *fontstr); +void setupdraw(DC *dc, Window w); int textnw(DC *dc, const char *text, unsigned int len); int textw(DC *dc, const char *text); diff --git a/dmenubar/draw/drawtext.c b/dmenubar/draw/drawtext.c new file mode 100644 index 0000000..cf7b015 --- /dev/null +++ b/dmenubar/draw/drawtext.c @@ -0,0 +1,34 @@ +/* See LICENSE file for copyright and license details. */ +#include <string.h> +#include <X11/Xlib.h> +#include "draw.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +void +drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { + char buf[256]; + int i, x, y, h, len, olen; + XRectangle r = { dc->x, dc->y, dc->w, dc->h }; + + XSetForeground(dc->dpy, dc->gc, col[ColBG]); + XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); + if(!text) + return; + olen = strlen(text); + h = dc->font.height; + y = dc->y + ((h+2) / 2) - (h / 2) + dc->font.ascent; + x = dc->x + (h / 2); + /* shorten text if necessary */ + for(len = MIN(olen, sizeof buf); len && textnw(dc, text, len) > dc->w - h; len--); + if(!len) + return; + memcpy(buf, text, len); + if(len < olen) + for(i = len; i && i > len - 3; buf[--i] = '.'); + XSetForeground(dc->dpy, dc->gc, col[ColFG]); + if(dc->font.set) + XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len); + else + XDrawString(dc->dpy, dc->drawable, dc->gc, x, y, buf, len); +} diff --git a/dmenubar/draw/eprint.c b/dmenubar/draw/eprint.c new file mode 100644 index 0000000..3094b61 --- /dev/null +++ b/dmenubar/draw/eprint.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include "draw.h" + +const char *progname; + +void +eprint(const char *fmt, ...) { + va_list ap; + + fprintf(stderr, "%s: ", progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EXIT_FAILURE); +} diff --git a/dmenubar/draw/getcolor.c b/dmenubar/draw/getcolor.c new file mode 100644 index 0000000..c0e5d21 --- /dev/null +++ b/dmenubar/draw/getcolor.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> +#include "draw.h" + +unsigned long +getcolor(DC *dc, const char *colstr) { + Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); + XColor color; + + if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) + eprint("cannot allocate color '%s'\n", colstr); + return color.pixel; +} diff --git a/dmenubar/draw/initfont.c b/dmenubar/draw/initfont.c new file mode 100644 index 0000000..77d3182 --- /dev/null +++ b/dmenubar/draw/initfont.c @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> +#include "draw.h" + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +void +initfont(DC *dc, const char *fontstr) { + char *def, **missing = NULL; + int i, n; + + if(!fontstr || !*fontstr) + eprint("cannot load null font\n"); + dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def); + if(missing) + XFreeStringList(missing); + if(dc->font.set) { + XFontStruct **xfonts; + char **font_names; + dc->font.ascent = dc->font.descent = 0; + n = XFontsOfFontSet(dc->font.set, &xfonts, &font_names); + for(i = 0; i < n; i++) { + dc->font.ascent = MAX(dc->font.ascent, (*xfonts)->ascent); + dc->font.descent = MAX(dc->font.descent, (*xfonts)->descent); + xfonts++; + } + } + else { + if(!(dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)) + && !(dc->font.xfont = XLoadQueryFont(dc->dpy, "fixed"))) + eprint("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; +} diff --git a/dmenubar/draw/setupdraw.c b/dmenubar/draw/setupdraw.c new file mode 100644 index 0000000..7dd5012 --- /dev/null +++ b/dmenubar/draw/setupdraw.c @@ -0,0 +1,16 @@ +/* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> +#include "draw.h" + +void +setupdraw(DC *dc, Window w) { + XWindowAttributes wa; + + XGetWindowAttributes(dc->dpy, w, &wa); + dc->drawable = XCreatePixmap(dc->dpy, w, wa.width, wa.height, + DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); + dc->gc = XCreateGC(dc->dpy, w, 0, NULL); + XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc->font.set) + XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); +} diff --git a/dmenubar/draw/textnw.c b/dmenubar/draw/textnw.c new file mode 100644 index 0000000..9c0c122 --- /dev/null +++ b/dmenubar/draw/textnw.c @@ -0,0 +1,14 @@ +/* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> +#include "draw.h" + +int +textnw(DC *dc, 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); +} diff --git a/dmenubar/draw/textw.c b/dmenubar/draw/textw.c new file mode 100644 index 0000000..a8407f6 --- /dev/null +++ b/dmenubar/draw/textw.c @@ -0,0 +1,9 @@ +/* See LICENSE file for copyright and license details. */ +#include <string.h> +#include <X11/Xlib.h> +#include "draw.h" + +int +textw(DC *dc, const char *text) { + return textnw(dc, text, strlen(text)) + dc->font.height; +} From b36d8de8adfa89b5b2ba55302769140f1d3a2a61 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 25 Jun 2010 04:33:41 +0100 Subject: [PATCH 326/590] cleaned up --- dmenubar/dinput.c | 8 ++++---- dmenubar/dmenu.c | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 283b018..228780c 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -25,7 +25,7 @@ static void cleanup(void); static void drawcursor(void); static void drawinput(void); static Bool grabkeyboard(void); -static void kpress(XKeyEvent * e); +static void kpress(XKeyEvent *e); static void run(void); static void setup(Bool topbar); @@ -100,7 +100,7 @@ grabkeyboard(void) { } void -kpress(XKeyEvent * e) { +kpress(XKeyEvent *e) { char buf[sizeof text]; int num; unsigned int i, len; @@ -140,6 +140,7 @@ kpress(XKeyEvent * e) { ksym = XK_BackSpace; break; case XK_j: + case XK_m: ksym = XK_Return; break; case XK_k: @@ -274,12 +275,11 @@ setup(Bool topbar) { selcol[ColBG] = getcolor(&dc, selbgcolor); selcol[ColFG] = getcolor(&dc, selfgcolor); initfont(&dc, font); - fprintf(stderr, "dc.font.xfont: %u\n", (size_t)dc.font.xfont); /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; + wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; /* input window geometry */ mh = dc.font.height + 2; diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6641ba2..8c0ea41 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -39,7 +39,7 @@ static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); static Bool grabkeyboard(void); -static void kpress(XKeyEvent * e); +static void kpress(XKeyEvent *e); static void match(char *pattern); static void readstdin(void); static void run(void); @@ -191,7 +191,7 @@ drawmenuh(void) { dc.w = spaceitem; drawtext(&dc, curr->left ? "<" : NULL, normcol); dc.x += dc.w; - for(i = curr; i != next; i=i->right) { + for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.x += dc.w; @@ -208,7 +208,7 @@ drawmenuv(void) { dc.w = mw - dc.x; dc.h = dc.font.height + 2; dc.y = dc.h; - for(i = curr; i != next; i=i->right) { + for(i = curr; i != next; i = i->right) { drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.y += dc.h; } @@ -230,7 +230,7 @@ grabkeyboard(void) { } void -kpress(XKeyEvent * e) { +kpress(XKeyEvent *e) { char buf[sizeof text]; int num; unsigned int i, len; @@ -273,6 +273,7 @@ kpress(XKeyEvent * e) { ksym = XK_Tab; break; case XK_j: + case XK_m: ksym = XK_Return; break; case XK_n: @@ -501,7 +502,7 @@ setup(Bool topbar) { /* menu window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; + wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; /* menu window geometry */ mh = (dc.font.height + 2) * (lines + 1); From c984dc95dcb6304fd08817b9d28bc7a91e203f9d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 28 Jun 2010 06:09:34 +0100 Subject: [PATCH 327/590] extended libdraw --- dmenubar/dinput.c | 8 ++++---- dmenubar/dmenu.c | 18 +++++++++--------- dmenubar/draw/Makefile | 4 ++-- dmenubar/draw/draw.h | 5 +++-- dmenubar/draw/drawsquare.c | 19 +++++++++++++++++++ dmenubar/draw/drawtext.c | 6 +++--- 6 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 dmenubar/draw/drawsquare.c diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 228780c..0bf2679 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -72,15 +72,15 @@ drawinput(void) dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, normcol); + drawtext(&dc, NULL, normcol, False); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, selcol); + drawtext(&dc, prompt, selcol, False); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(&dc, *text ? text : NULL, normcol); + drawtext(&dc, *text ? text : NULL, normcol, False); drawcursor(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -233,7 +233,7 @@ run(void) { /* main event loop */ while(running && !XNextEvent(dpy, &ev)) - switch (ev.type) { + switch(ev.type) { case KeyPress: kpress(&ev.xkey); break; diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8c0ea41..8059f29 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -161,18 +161,18 @@ drawmenu(void) { dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, normcol); + drawtext(&dc, NULL, normcol, False); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, selcol); + drawtext(&dc, prompt, selcol, False); dc.x += dc.w; } dc.w = mw - dc.x; /* print command */ if(cmdw && item && lines == 0) dc.w = cmdw; - drawtext(&dc, *text ? text : NULL, normcol); + drawtext(&dc, *text ? text : NULL, normcol, False); if(curr) { if(lines > 0) drawmenuv(); @@ -189,16 +189,16 @@ drawmenuh(void) { dc.x += cmdw; dc.w = spaceitem; - drawtext(&dc, curr->left ? "<" : NULL, normcol); + drawtext(&dc, curr->left ? "<" : NULL, normcol, False); dc.x += dc.w; for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); - drawtext(&dc, i->text, (sel == i) ? selcol : normcol); + drawtext(&dc, i->text, (sel == i) ? selcol : normcol, False); dc.x += dc.w; } dc.w = spaceitem; dc.x = mw - dc.w; - drawtext(&dc, next ? ">" : NULL, normcol); + drawtext(&dc, next ? ">" : NULL, normcol, False); } void @@ -209,11 +209,11 @@ drawmenuv(void) { dc.h = dc.font.height + 2; dc.y = dc.h; for(i = curr; i != next; i = i->right) { - drawtext(&dc, i->text, (sel == i) ? selcol : normcol); + drawtext(&dc, i->text, (sel == i) ? selcol : normcol, False); dc.y += dc.h; } dc.h = mh - dc.y; - drawtext(&dc, NULL, normcol); + drawtext(&dc, NULL, normcol, False); } Bool @@ -456,7 +456,7 @@ run(void) { /* main event loop */ while(running && !XNextEvent(dpy, &ev)) - switch (ev.type) { + switch(ev.type) { case KeyPress: kpress(&ev.xkey); break; diff --git a/dmenubar/draw/Makefile b/dmenubar/draw/Makefile index 1f72b61..4b39490 100644 --- a/dmenubar/draw/Makefile +++ b/dmenubar/draw/Makefile @@ -3,8 +3,8 @@ include ../config.mk -SRC = cleanupdraw.c setupdraw.c drawtext.c eprint.c getcolor.c initfont.c \ -textnw.c textw.c +SRC = cleanupdraw.c drawsquare.c drawtext.c eprint.c getcolor.c initfont.c \ +setupdraw.c textnw.c textw.c OBJ = ${SRC:.c=.o} all: libdraw.a diff --git a/dmenubar/draw/draw.h b/dmenubar/draw/draw.h index 4646a18..f282392 100644 --- a/dmenubar/draw/draw.h +++ b/dmenubar/draw/draw.h @@ -2,7 +2,7 @@ #include <X11/Xlib.h> /* enums */ -enum { ColFG, ColBG, ColLast }; +enum { ColBorder, ColFG, ColBG, ColLast }; /* typedefs */ typedef struct { @@ -21,7 +21,8 @@ typedef struct { /* forward declarations */ void cleanupdraw(DC *dc); -void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); +void drawsquare(DC *dc, Bool filled, unsigned long col[ColLast], Bool invert); +void drawtext(DC *dc, const char *text, unsigned long col[ColLast], Bool invert); void eprint(const char *fmt, ...); unsigned long getcolor(DC *dc, const char *colstr); void initfont(DC *dc, const char *fontstr); diff --git a/dmenubar/draw/drawsquare.c b/dmenubar/draw/drawsquare.c new file mode 100644 index 0000000..8899043 --- /dev/null +++ b/dmenubar/draw/drawsquare.c @@ -0,0 +1,19 @@ +/* See LICENSE file for copyright and license details. */ +#include <X11/Xlib.h> +#include "draw.h" + +void +drawsquare(DC *dc, Bool filled, unsigned long col[ColLast], Bool invert) { + int n; + XRectangle r = { dc->x, dc->y, dc->w, dc->h }; + + XSetForeground(dc->dpy, dc->gc, col[invert ? ColBG : ColFG]); + n = ((dc->font.ascent + dc->font.descent + 2) / 4) + (filled ? 1 : 0); + r.width = r.height = n; + r.x = dc->x + 1; + r.y = dc->y + 1; + if(filled) + XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); + else + XDrawRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); +} diff --git a/dmenubar/draw/drawtext.c b/dmenubar/draw/drawtext.c index cf7b015..d347b36 100644 --- a/dmenubar/draw/drawtext.c +++ b/dmenubar/draw/drawtext.c @@ -6,12 +6,12 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) void -drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { +drawtext(DC *dc, const char *text, unsigned long col[ColLast], Bool invert) { char buf[256]; int i, x, y, h, len, olen; XRectangle r = { dc->x, dc->y, dc->w, dc->h }; - XSetForeground(dc->dpy, dc->gc, col[ColBG]); + XSetForeground(dc->dpy, dc->gc, col[invert ? ColFG : ColBG]); XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); if(!text) return; @@ -26,7 +26,7 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { memcpy(buf, text, len); if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dc->dpy, dc->gc, col[ColFG]); + XSetForeground(dc->dpy, dc->gc, col[invert ? ColBG : ColFG]); if(dc->font.set) XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len); else From ed5b452950416978580462061d7df5e55e4e84e6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 29 Jun 2010 16:07:31 +0100 Subject: [PATCH 328/590] dinput with dmenu flags, fixed usage & -v, cosmetics --- dmenubar/dinput.c | 24 ++++++++++++++++-------- dmenubar/dmenu.c | 22 ++++++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 0bf2679..b69dcb3 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -76,11 +76,11 @@ drawinput(void) /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, selcol, False); + drawtext(&dc, prompt, normcol, False); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(&dc, *text ? text : NULL, normcol, False); + drawtext(&dc, *text ? text : NULL, selcol, False); drawcursor(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -329,11 +329,15 @@ main(int argc, char *argv[]) { /* command line args */ progname = argv[0]; for(i = 1; i < argc; i++) - if(!strcmp(argv[i], "-b")) + if(!strcmp(argv[i], "-i")) + ; /* ignore flag */ + else if(!strcmp(argv[i], "-b")) topbar = False; else if(!strcmp(argv[i], "-e")) { if(++i < argc) parent = atoi(argv[i]); } + else if(!strcmp(argv[i], "-l")) + i++; /* ignore flag */ else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } @@ -352,13 +356,17 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) { if(++i < argc) selfgcolor = argv[i]; } - else if(!strcmp(argv[i], "-v")) - eprint("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n"); + else if(!strcmp(argv[i], "-v")) { + printf("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n"); + exit(EXIT_SUCCESS); + } else if(!*text) strncpy(text, argv[i], sizeof text); - else - eprint("usage: dinput [-b] [-e <xid>] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n"); + else { + fputs("usage: dinput [-b] [-e <xid>] [-fn <font>] [-nb <color>] [-nf <color>]\n" + " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr); + exit(EXIT_FAILURE); + } if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "dinput: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8059f29..9e30add 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -49,6 +49,7 @@ static void setup(Bool topbar); #include "draw.h" /* variables */ +static char **argp = NULL; static char *maxname = NULL; static char *prompt = NULL; static char text[4096]; @@ -151,7 +152,9 @@ cleanup(void) { void dinput(void) { cleanup(); - execlp("dinput", "dinput", text, NULL); /* todo: argv */ + argp[0] = "dinput"; + argp[1] = text; + execvp("dinput", argp); eprint("cannot exec dinput\n"); } @@ -587,11 +590,15 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) { if(++i < argc) selfgcolor = argv[i]; } - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); - else - eprint("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" - " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); + else if(!strcmp(argv[i], "-v")) { + printf("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); + exit(EXIT_SUCCESS); + } + else { + fputs("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" + " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); + exit(EXIT_FAILURE); + } if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "dmenu: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) @@ -599,6 +606,9 @@ main(int argc, char *argv[]) { screen = DefaultScreen(dpy); if(!parent) parent = RootWindow(dpy, screen); + if(!(argp = malloc(sizeof *argp * (argc+2)))) + eprint("cannot malloc %u bytes\n", sizeof *argp * (argc+2)); + memcpy(argp + 2, argv + 1, sizeof *argp * argc); readstdin(); running = grabkeyboard(); From 3449a56aae35f5d06f51326008b9b58695cad1b0 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 29 Jun 2010 19:19:20 +0100 Subject: [PATCH 329/590] decosmetics --- dmenubar/dinput.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index b69dcb3..6b78598 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -76,11 +76,11 @@ drawinput(void) /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, normcol, False); + drawtext(&dc, prompt, selcol, False); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(&dc, *text ? text : NULL, selcol, False); + drawtext(&dc, *text ? text : NULL, normcol, False); drawcursor(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); From 23f129ecbc90f5b4c30fa80ce5962504bd2f50f3 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 30 Jun 2010 00:05:32 +0100 Subject: [PATCH 330/590] cleaned up --- dmenubar/dmenu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9e30add..2d53f9b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -43,7 +43,7 @@ static void kpress(XKeyEvent *e); static void match(char *pattern); static void readstdin(void); static void run(void); -static void setup(Bool topbar); +static void setup(void); #include "config.h" #include "draw.h" @@ -63,6 +63,7 @@ static unsigned int mw, mh; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Bool running = True; +static Bool topbar = True; static DC dc; static Display *dpy; static Item *allitems = NULL; /* first of all items */ @@ -475,7 +476,7 @@ run(void) { } void -setup(Bool topbar) { +setup(void) { int i, j, x, y; #if XINERAMA int n; @@ -529,7 +530,8 @@ setup(Bool topbar) { else #endif { - XGetWindowAttributes(dpy, parent, &pwa); + if(!XGetWindowAttributes(dpy, parent, &pwa)) + eprint("cannot get window attributes"); x = 0; y = topbar ? 0 : pwa.height - mh; mw = pwa.width; @@ -553,7 +555,6 @@ setup(Bool topbar) { int main(int argc, char *argv[]) { unsigned int i; - Bool topbar = True; /* command line args */ progname = argv[0]; @@ -613,7 +614,7 @@ main(int argc, char *argv[]) { readstdin(); running = grabkeyboard(); - setup(topbar); + setup(); drawmenu(); XSync(dpy, False); run(); From 14b2a6638dc8b392a19769db431a658094188d6b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 30 Jun 2010 00:52:14 +0100 Subject: [PATCH 331/590] resizing vlist, new dinput binding --- dmenubar/dmenu.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2d53f9b..764e0f0 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -109,6 +109,7 @@ calcoffsetsv(void) { next = prev = curr; for(i = 0; i < lines && next; i++) next = next->right; + mh = (dc.font.height + 2) * (i + 1); for(i = 0; i < lines && prev && prev->left; i++) prev = prev->left; } @@ -166,6 +167,8 @@ drawmenu(void) { dc.w = mw; dc.h = mh; drawtext(&dc, NULL, normcol, False); + dc.h = dc.font.height + 2; + dc.y = topbar ? 0 : mh - dc.h; /* print prompt? */ if(prompt) { dc.w = promptw; @@ -177,12 +180,10 @@ drawmenu(void) { if(cmdw && item && lines == 0) dc.w = cmdw; drawtext(&dc, *text ? text : NULL, normcol, False); - if(curr) { - if(lines > 0) - drawmenuv(); - else - drawmenuh(); - } + if(lines > 0) + drawmenuv(); + else + drawmenuh(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); } @@ -193,7 +194,7 @@ drawmenuh(void) { dc.x += cmdw; dc.w = spaceitem; - drawtext(&dc, curr->left ? "<" : NULL, normcol, False); + drawtext(&dc, curr && curr->left ? "<" : NULL, normcol, False); dc.x += dc.w; for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); @@ -208,16 +209,17 @@ drawmenuh(void) { void drawmenuv(void) { Item *i; + XWindowAttributes wa; + dc.y = topbar ? dc.h : 0; dc.w = mw - dc.x; - dc.h = dc.font.height + 2; - dc.y = dc.h; for(i = curr; i != next; i = i->right) { drawtext(&dc, i->text, (sel == i) ? selcol : normcol, False); dc.y += dc.h; } - dc.h = mh - dc.y; - drawtext(&dc, NULL, normcol, False); + if(!XGetWindowAttributes(dpy, win, &wa)) + eprint("cannot get window attributes"); + XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); } Bool @@ -299,9 +301,6 @@ kpress(XKeyEvent *e) { text[++i] = '\0'; match(text); break; - case XK_x: - dinput(); - break; } } switch(ksym) { @@ -360,10 +359,9 @@ kpress(XKeyEvent *e) { calcoffsets(); break; case XK_Return: - if((e->state & ShiftMask) || !sel) - fprintf(stdout, "%s", text); - else - fprintf(stdout, "%s", sel->text); + if(e->state & ShiftMask) + dinput(); + fprintf(stdout, "%s", sel ? sel->text : text); fflush(stdout); running = False; return; From 96f158414e1aca127c00bdd50be15bd676a7ef5f Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 30 Jun 2010 01:36:15 +0100 Subject: [PATCH 332/590] libdraw now has own repo --- dmenubar/Makefile | 8 ++------ dmenubar/README | 2 ++ dmenubar/config.mk | 4 ++-- dmenubar/dinput.c | 2 +- dmenubar/dmenu.c | 2 +- dmenubar/draw/Makefile | 26 -------------------------- dmenubar/draw/cleanupdraw.c | 13 ------------- dmenubar/draw/draw.h | 34 ---------------------------------- dmenubar/draw/drawsquare.c | 19 ------------------- dmenubar/draw/drawtext.c | 34 ---------------------------------- dmenubar/draw/eprint.c | 18 ------------------ dmenubar/draw/getcolor.c | 13 ------------- dmenubar/draw/initfont.c | 36 ------------------------------------ dmenubar/draw/setupdraw.c | 16 ---------------- dmenubar/draw/textnw.c | 14 -------------- dmenubar/draw/textw.c | 9 --------- 16 files changed, 8 insertions(+), 242 deletions(-) delete mode 100644 dmenubar/draw/Makefile delete mode 100644 dmenubar/draw/cleanupdraw.c delete mode 100644 dmenubar/draw/draw.h delete mode 100644 dmenubar/draw/drawsquare.c delete mode 100644 dmenubar/draw/drawtext.c delete mode 100644 dmenubar/draw/eprint.c delete mode 100644 dmenubar/draw/getcolor.c delete mode 100644 dmenubar/draw/initfont.c delete mode 100644 dmenubar/draw/setupdraw.c delete mode 100644 dmenubar/draw/textnw.c delete mode 100644 dmenubar/draw/textw.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 90f178b..0f29652 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -18,7 +18,7 @@ options: @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk draw/libdraw.a +${OBJ}: config.h config.mk config.h: @echo creating $@ from config.def.h @@ -28,18 +28,14 @@ config.h: @echo CC -o $@ @${CC} -o $@ $< ${LDFLAGS} -draw/libdraw.a: - @cd draw && make - clean: @echo cleaning @rm -f dinput dmenu ${OBJ} dmenu-${VERSION}.tar.gz - @cd draw && make clean dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run draw ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/README b/dmenubar/README index b11fc08..3706ef1 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -6,6 +6,8 @@ dmenu is a generic and efficient menu for X. Requirements ------------ In order to build dmenu you need the Xlib header files. +You also need libdraw, available from http://hg.suckless.org/libdraw + Pasting the X selection to dmenu requires the sselp utility at runtime. diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 431754e..c8bbdcd 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -15,8 +15,8 @@ XINERAMALIBS = -L${X11LIB} -lXinerama XINERAMAFLAGS = -DXINERAMA # includes and libs -INCS = -I. -Idraw -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -Ldraw -ldraw ${XINERAMALIBS} +INCS = -I. -I/usr/include -I${X11INC} +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -ldraw ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 6b78598..64ce036 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -12,6 +12,7 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif +#include <draw.h> /* macros */ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) @@ -30,7 +31,6 @@ static void run(void); static void setup(Bool topbar); #include "config.h" -#include "draw.h" /* variables */ static char *prompt = NULL; diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 764e0f0..c353c60 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -13,6 +13,7 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif +#include <draw.h> /* macros */ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) @@ -46,7 +47,6 @@ static void run(void); static void setup(void); #include "config.h" -#include "draw.h" /* variables */ static char **argp = NULL; diff --git a/dmenubar/draw/Makefile b/dmenubar/draw/Makefile deleted file mode 100644 index 4b39490..0000000 --- a/dmenubar/draw/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# libdraw - dynamic drawing library -# See LICENSE file for copyright and license details. - -include ../config.mk - -SRC = cleanupdraw.c drawsquare.c drawtext.c eprint.c getcolor.c initfont.c \ -setupdraw.c textnw.c textw.c -OBJ = ${SRC:.c=.o} - -all: libdraw.a - -.c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< - -${OBJ}: ../config.mk draw.h - -libdraw.a: ${OBJ} - @echo AR $@ - @ar cr $@ $+ - -clean: - @echo cleaning libdraw - @rm -f libdraw.a ${OBJ} - -.PHONY: all options clean diff --git a/dmenubar/draw/cleanupdraw.c b/dmenubar/draw/cleanupdraw.c deleted file mode 100644 index 28bce13..0000000 --- a/dmenubar/draw/cleanupdraw.c +++ /dev/null @@ -1,13 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> -#include "draw.h" - -void -cleanupdraw(DC *dc) { - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); - else - XFreeFont(dc->dpy, dc->font.xfont); - XFreePixmap(dc->dpy, dc->drawable); - XFreeGC(dc->dpy, dc->gc); -} diff --git a/dmenubar/draw/draw.h b/dmenubar/draw/draw.h deleted file mode 100644 index f282392..0000000 --- a/dmenubar/draw/draw.h +++ /dev/null @@ -1,34 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> - -/* enums */ -enum { ColBorder, ColFG, ColBG, ColLast }; - -/* typedefs */ -typedef struct { - int x, y, w, h; - Drawable drawable; - Display *dpy; - GC gc; - struct { - XFontStruct *xfont; - XFontSet set; - int ascent; - int descent; - int height; - } font; -} DC; /* draw context */ - -/* forward declarations */ -void cleanupdraw(DC *dc); -void drawsquare(DC *dc, Bool filled, unsigned long col[ColLast], Bool invert); -void drawtext(DC *dc, const char *text, unsigned long col[ColLast], Bool invert); -void eprint(const char *fmt, ...); -unsigned long getcolor(DC *dc, const char *colstr); -void initfont(DC *dc, const char *fontstr); -void setupdraw(DC *dc, Window w); -int textnw(DC *dc, const char *text, unsigned int len); -int textw(DC *dc, const char *text); - -/* variables */ -extern const char *progname; diff --git a/dmenubar/draw/drawsquare.c b/dmenubar/draw/drawsquare.c deleted file mode 100644 index 8899043..0000000 --- a/dmenubar/draw/drawsquare.c +++ /dev/null @@ -1,19 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> -#include "draw.h" - -void -drawsquare(DC *dc, Bool filled, unsigned long col[ColLast], Bool invert) { - int n; - XRectangle r = { dc->x, dc->y, dc->w, dc->h }; - - XSetForeground(dc->dpy, dc->gc, col[invert ? ColBG : ColFG]); - n = ((dc->font.ascent + dc->font.descent + 2) / 4) + (filled ? 1 : 0); - r.width = r.height = n; - r.x = dc->x + 1; - r.y = dc->y + 1; - if(filled) - XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); - else - XDrawRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); -} diff --git a/dmenubar/draw/drawtext.c b/dmenubar/draw/drawtext.c deleted file mode 100644 index d347b36..0000000 --- a/dmenubar/draw/drawtext.c +++ /dev/null @@ -1,34 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <string.h> -#include <X11/Xlib.h> -#include "draw.h" - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -void -drawtext(DC *dc, const char *text, unsigned long col[ColLast], Bool invert) { - char buf[256]; - int i, x, y, h, len, olen; - XRectangle r = { dc->x, dc->y, dc->w, dc->h }; - - XSetForeground(dc->dpy, dc->gc, col[invert ? ColFG : ColBG]); - XFillRectangles(dc->dpy, dc->drawable, dc->gc, &r, 1); - if(!text) - return; - olen = strlen(text); - h = dc->font.height; - y = dc->y + ((h+2) / 2) - (h / 2) + dc->font.ascent; - x = dc->x + (h / 2); - /* shorten text if necessary */ - for(len = MIN(olen, sizeof buf); len && textnw(dc, text, len) > dc->w - h; len--); - if(!len) - return; - memcpy(buf, text, len); - if(len < olen) - for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dc->dpy, dc->gc, col[invert ? ColBG : ColFG]); - if(dc->font.set) - XmbDrawString(dc->dpy, dc->drawable, dc->font.set, dc->gc, x, y, buf, len); - else - XDrawString(dc->dpy, dc->drawable, dc->gc, x, y, buf, len); -} diff --git a/dmenubar/draw/eprint.c b/dmenubar/draw/eprint.c deleted file mode 100644 index 3094b61..0000000 --- a/dmenubar/draw/eprint.c +++ /dev/null @@ -1,18 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include "draw.h" - -const char *progname; - -void -eprint(const char *fmt, ...) { - va_list ap; - - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(EXIT_FAILURE); -} diff --git a/dmenubar/draw/getcolor.c b/dmenubar/draw/getcolor.c deleted file mode 100644 index c0e5d21..0000000 --- a/dmenubar/draw/getcolor.c +++ /dev/null @@ -1,13 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> -#include "draw.h" - -unsigned long -getcolor(DC *dc, const char *colstr) { - Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); - XColor color; - - if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) - eprint("cannot allocate color '%s'\n", colstr); - return color.pixel; -} diff --git a/dmenubar/draw/initfont.c b/dmenubar/draw/initfont.c deleted file mode 100644 index 77d3182..0000000 --- a/dmenubar/draw/initfont.c +++ /dev/null @@ -1,36 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> -#include "draw.h" - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -void -initfont(DC *dc, const char *fontstr) { - char *def, **missing = NULL; - int i, n; - - if(!fontstr || !*fontstr) - eprint("cannot load null font\n"); - dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def); - if(missing) - XFreeStringList(missing); - if(dc->font.set) { - XFontStruct **xfonts; - char **font_names; - dc->font.ascent = dc->font.descent = 0; - n = XFontsOfFontSet(dc->font.set, &xfonts, &font_names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, (*xfonts)->ascent); - dc->font.descent = MAX(dc->font.descent, (*xfonts)->descent); - xfonts++; - } - } - else { - if(!(dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr)) - && !(dc->font.xfont = XLoadQueryFont(dc->dpy, "fixed"))) - eprint("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; -} diff --git a/dmenubar/draw/setupdraw.c b/dmenubar/draw/setupdraw.c deleted file mode 100644 index 7dd5012..0000000 --- a/dmenubar/draw/setupdraw.c +++ /dev/null @@ -1,16 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> -#include "draw.h" - -void -setupdraw(DC *dc, Window w) { - XWindowAttributes wa; - - XGetWindowAttributes(dc->dpy, w, &wa); - dc->drawable = XCreatePixmap(dc->dpy, w, wa.width, wa.height, - DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); - dc->gc = XCreateGC(dc->dpy, w, 0, NULL); - XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc->font.set) - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); -} diff --git a/dmenubar/draw/textnw.c b/dmenubar/draw/textnw.c deleted file mode 100644 index 9c0c122..0000000 --- a/dmenubar/draw/textnw.c +++ /dev/null @@ -1,14 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <X11/Xlib.h> -#include "draw.h" - -int -textnw(DC *dc, 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); -} diff --git a/dmenubar/draw/textw.c b/dmenubar/draw/textw.c deleted file mode 100644 index a8407f6..0000000 --- a/dmenubar/draw/textw.c +++ /dev/null @@ -1,9 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <string.h> -#include <X11/Xlib.h> -#include "draw.h" - -int -textw(DC *dc, const char *text) { - return textnw(dc, text, strlen(text)) + dc->font.height; -} From 311463f82980e4e412057f4989682b9919fdec64 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 30 Jun 2010 10:45:24 +0100 Subject: [PATCH 333/590] fixed no-input invisible text bug --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c353c60..9315181 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -182,7 +182,7 @@ drawmenu(void) { drawtext(&dc, *text ? text : NULL, normcol, False); if(lines > 0) drawmenuv(); - else + else if(curr) drawmenuh(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); XFlush(dpy); @@ -194,7 +194,7 @@ drawmenuh(void) { dc.x += cmdw; dc.w = spaceitem; - drawtext(&dc, curr && curr->left ? "<" : NULL, normcol, False); + drawtext(&dc, curr->left ? "<" : NULL, normcol, False); dc.x += dc.w; for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); From 827c29f7464ebe61991e78100dd19cce1d7f1d0e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 30 Jun 2010 22:42:15 +0100 Subject: [PATCH 334/590] removed -e flag (too buggy), cleaned up --- dmenubar/dinput.c | 28 ++++++++++------------------ dmenubar/dmenu.c | 30 ++++++++++-------------------- 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 64ce036..b789bd7 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -1,7 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <locale.h> -#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -15,7 +14,6 @@ #include <draw.h> /* macros */ -#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -46,7 +44,7 @@ static unsigned long selcol[ColLast]; static Bool running = True; static DC dc; static Display *dpy; -static Window win, parent; +static Window win, root; void cleanup(void) { @@ -91,7 +89,7 @@ grabkeyboard(void) { unsigned int len; for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, parent, True, GrabModeAsync, GrabModeAsync, CurrentTime) + if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); @@ -257,7 +255,6 @@ setup(Bool topbar) { #endif XModifierKeymap *modmap; XSetWindowAttributes wa; - XWindowAttributes pwa; /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -284,13 +281,13 @@ setup(Bool topbar) { /* input window geometry */ mh = dc.font.height + 2; #if XINERAMA - if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; if(n > 1) { int di; unsigned int dui; Window dummy; - if(XQueryPointer(dpy, parent, &dummy, &dummy, &x, &y, &di, &di, &dui)) + if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) for(i = 0; i < n; i++) if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; @@ -303,13 +300,12 @@ setup(Bool topbar) { else #endif { - XGetWindowAttributes(dpy, parent, &pwa); x = 0; - y = topbar ? 0 : pwa.height - mh; - mw = pwa.width; + y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; + mw = DisplayWidth(dpy, screen); } - win = XCreateWindow(dpy, parent, x, y, mw, mh, 0, + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); @@ -327,15 +323,12 @@ main(int argc, char *argv[]) { Bool topbar = True; /* command line args */ - progname = argv[0]; + progname = "dinput"; for(i = 1; i < argc; i++) if(!strcmp(argv[i], "-i")) ; /* ignore flag */ else if(!strcmp(argv[i], "-b")) topbar = False; - else if(!strcmp(argv[i], "-e")) { - if(++i < argc) parent = atoi(argv[i]); - } else if(!strcmp(argv[i], "-l")) i++; /* ignore flag */ else if(!strcmp(argv[i], "-fn")) { @@ -363,7 +356,7 @@ main(int argc, char *argv[]) { else if(!*text) strncpy(text, argv[i], sizeof text); else { - fputs("usage: dinput [-b] [-e <xid>] [-fn <font>] [-nb <color>] [-nf <color>]\n" + fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr); exit(EXIT_FAILURE); } @@ -372,8 +365,7 @@ main(int argc, char *argv[]) { if(!(dpy = XOpenDisplay(NULL))) eprint("cannot open display\n"); screen = DefaultScreen(dpy); - if(!parent) - parent = RootWindow(dpy, screen); + root = RootWindow(dpy, screen); running = grabkeyboard(); setup(topbar); diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9315181..680b4e7 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,11 +1,9 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <locale.h> -#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <strings.h> #include <unistd.h> #include <X11/keysym.h> #include <X11/Xlib.h> @@ -16,7 +14,6 @@ #include <draw.h> /* macros */ -#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -72,7 +69,7 @@ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; -static Window win, parent; +static Window win, root; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static void (*calcoffsets)(void) = calcoffsetsh; @@ -227,7 +224,7 @@ grabkeyboard(void) { unsigned int len; for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, parent, True, GrabModeAsync, GrabModeAsync, CurrentTime) + if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); @@ -482,7 +479,6 @@ setup(void) { #endif XModifierKeymap *modmap; XSetWindowAttributes wa; - XWindowAttributes pwa; /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -509,13 +505,13 @@ setup(void) { /* menu window geometry */ mh = (dc.font.height + 2) * (lines + 1); #if XINERAMA - if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; if(n > 1) { int di; unsigned int dui; Window dummy; - if(XQueryPointer(dpy, parent, &dummy, &dummy, &x, &y, &di, &di, &dui)) + if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) for(i = 0; i < n; i++) if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; @@ -528,14 +524,12 @@ setup(void) { else #endif { - if(!XGetWindowAttributes(dpy, parent, &pwa)) - eprint("cannot get window attributes"); x = 0; - y = topbar ? 0 : pwa.height - mh; - mw = pwa.width; + y = topbar ? 0 : mh - DisplayHeight(dpy, screen); + mw = DisplayWidth(dpy, screen); } - win = XCreateWindow(dpy, parent, x, y, mw, mh, 0, + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); @@ -555,7 +549,7 @@ main(int argc, char *argv[]) { unsigned int i; /* command line args */ - progname = argv[0]; + progname = "dmenu"; for(i = 1; i < argc; i++) if(!strcmp(argv[i], "-i")) { fstrncmp = strncasecmp; @@ -563,9 +557,6 @@ main(int argc, char *argv[]) { } else if(!strcmp(argv[i], "-b")) topbar = False; - else if(!strcmp(argv[i], "-e")) { - if(++i < argc) parent = atoi(argv[i]); - } else if(!strcmp(argv[i], "-l")) { if(++i < argc) lines = atoi(argv[i]); if(lines > 0) @@ -594,7 +585,7 @@ main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } else { - fputs("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" + fputs("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>]\n" " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); exit(EXIT_FAILURE); } @@ -603,8 +594,7 @@ main(int argc, char *argv[]) { if(!(dpy = XOpenDisplay(NULL))) eprint("cannot open display\n"); screen = DefaultScreen(dpy); - if(!parent) - parent = RootWindow(dpy, screen); + root = RootWindow(dpy, screen); if(!(argp = malloc(sizeof *argp * (argc+2)))) eprint("cannot malloc %u bytes\n", sizeof *argp * (argc+2)); memcpy(argp + 2, argv + 1, sizeof *argp * argc); From 0146b3c47881900c9f608241b0693096f8740d2e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 2 Jul 2010 03:44:01 +0100 Subject: [PATCH 335/590] atexit cleanup --- dmenubar/dinput.c | 35 +++++++++++++++-------------------- dmenubar/dmenu.c | 47 +++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index b789bd7..4c90cd7 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -26,7 +26,7 @@ static void drawinput(void); static Bool grabkeyboard(void); static void kpress(XKeyEvent *e); static void run(void); -static void setup(Bool topbar); +static void setup(void); #include "config.h" @@ -34,14 +34,13 @@ static void setup(Bool topbar); static char *prompt = NULL; static char text[4096]; static int promptw = 0; -static int ret = 0; static int screen; static unsigned int cursor = 0; static unsigned int numlockmask = 0; static unsigned int mw, mh; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; -static Bool running = True; +static Bool topbar = True; static DC dc; static Display *dpy; static Window win, root; @@ -51,6 +50,7 @@ cleanup(void) { cleanupdraw(&dc); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); + XCloseDisplay(dpy); } void @@ -81,7 +81,6 @@ drawinput(void) drawtext(&dc, *text ? text : NULL, normcol, False); drawcursor(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); - XFlush(dpy); } Bool @@ -200,9 +199,7 @@ kpress(XKeyEvent *e) { cursor = len; break; case XK_Escape: - ret = 1; - running = False; - return; + exit(EXIT_FAILURE); case XK_Home: cursor = 0; break; @@ -214,8 +211,7 @@ kpress(XKeyEvent *e) { case XK_Return: fprintf(stdout, "%s", text); fflush(stdout); - running = False; - return; + exit(EXIT_SUCCESS); case XK_Right: if(cursor == len) return; @@ -230,7 +226,8 @@ run(void) { XEvent ev; /* main event loop */ - while(running && !XNextEvent(dpy, &ev)) + XSync(dpy, False); + while(!XNextEvent(dpy, &ev)) switch(ev.type) { case KeyPress: kpress(&ev.xkey); @@ -240,14 +237,15 @@ run(void) { drawinput(); break; case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) + if(ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); break; } + exit(EXIT_FAILURE); } void -setup(Bool topbar) { +setup(void) { int i, j, x, y; #if XINERAMA int n; @@ -320,7 +318,6 @@ setup(Bool topbar) { int main(int argc, char *argv[]) { unsigned int i; - Bool topbar = True; /* command line args */ progname = "dinput"; @@ -364,15 +361,13 @@ main(int argc, char *argv[]) { fprintf(stderr, "dinput: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) eprint("cannot open display\n"); + if(atexit(&cleanup) != 0) + eprint("cannot register cleanup\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - running = grabkeyboard(); - setup(topbar); - drawinput(); - XSync(dpy, False); + grabkeyboard(); + setup(); run(); - cleanup(); - XCloseDisplay(dpy); - return ret; + return 0; } diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 680b4e7..2cc2cad 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -36,7 +36,7 @@ static void dinput(void); static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); -static Bool grabkeyboard(void); +static void grabkeyboard(void); static void kpress(XKeyEvent *e); static void match(char *pattern); static void readstdin(void); @@ -52,14 +52,12 @@ static char *prompt = NULL; static char text[4096]; static int cmdw = 0; static int promptw = 0; -static int ret = 0; static int screen; static unsigned int lines = 0; static unsigned int numlockmask = 0; static unsigned int mw, mh; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; -static Bool running = True; static Bool topbar = True; static DC dc; static Display *dpy; @@ -87,15 +85,15 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsetsh(void) { - unsigned int w; + unsigned int x; - w = promptw + cmdw + (2 * spaceitem); + x = promptw + cmdw + (2 * spaceitem); for(next = curr; next; next = next->right) - if((w += MIN(textw(&dc, next->text), mw / 3)) > mw) + if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) break; - w = promptw + cmdw + (2 * spaceitem); + x = promptw + cmdw + (2 * spaceitem); for(prev = curr; prev && prev->left; prev = prev->left) - if((w += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) + if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) break; } @@ -146,6 +144,7 @@ cleanup(void) { cleanupdraw(&dc); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); + XCloseDisplay(dpy); } void @@ -182,7 +181,6 @@ drawmenu(void) { else if(curr) drawmenuh(); XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); - XFlush(dpy); } void @@ -219,7 +217,7 @@ drawmenuv(void) { XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); } -Bool +void grabkeyboard(void) { unsigned int len; @@ -229,7 +227,8 @@ grabkeyboard(void) { break; usleep(1000); } - return len > 0; + if(!len) + exit(EXIT_FAILURE); } void @@ -326,9 +325,7 @@ kpress(XKeyEvent *e) { sel = sel->right; break; case XK_Escape: - ret = 1; - running = False; - return; + exit(EXIT_FAILURE); case XK_Home: sel = curr = item; calcoffsets(); @@ -360,8 +357,7 @@ kpress(XKeyEvent *e) { dinput(); fprintf(stdout, "%s", sel ? sel->text : text); fflush(stdout); - running = False; - return; + exit(EXIT_SUCCESS); case XK_Right: case XK_Down: if(!sel || !sel->right) @@ -454,7 +450,8 @@ run(void) { XEvent ev; /* main event loop */ - while(running && !XNextEvent(dpy, &ev)) + XSync(dpy, False); + while(!XNextEvent(dpy, &ev)) switch(ev.type) { case KeyPress: kpress(&ev.xkey); @@ -464,10 +461,11 @@ run(void) { drawmenu(); break; case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) + if(ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); break; } + exit(EXIT_FAILURE); } void @@ -586,13 +584,15 @@ main(int argc, char *argv[]) { } else { fputs("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>]\n" - " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); + " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); exit(EXIT_FAILURE); } if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "dmenu: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) eprint("cannot open display\n"); + if(atexit(&cleanup) != 0) + eprint("cannot register cleanup\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); if(!(argp = malloc(sizeof *argp * (argc+2)))) @@ -600,13 +600,8 @@ main(int argc, char *argv[]) { memcpy(argp + 2, argv + 1, sizeof *argp * argc); readstdin(); - running = grabkeyboard(); - + grabkeyboard(); setup(); - drawmenu(); - XSync(dpy, False); run(); - cleanup(); - XCloseDisplay(dpy); - return ret; + return 0; } From 67a0ba405222e629351b1efbbec8596ad5993fd8 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 2 Jul 2010 05:50:19 +0100 Subject: [PATCH 336/590] updated to new libdraw --- dmenubar/dinput.c | 31 ++++++++++--------------------- dmenubar/dmenu.c | 21 ++++++++++----------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 4c90cd7..0d0adeb 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -21,9 +21,8 @@ /* forward declarations */ static void cleanup(void); -static void drawcursor(void); static void drawinput(void); -static Bool grabkeyboard(void); +static void grabkeyboard(void); static void kpress(XKeyEvent *e); static void run(void); static void setup(void); @@ -35,7 +34,7 @@ static char *prompt = NULL; static char text[4096]; static int promptw = 0; static int screen; -static unsigned int cursor = 0; +static size_t cursor = 0; static unsigned int numlockmask = 0; static unsigned int mw, mh; static unsigned long normcol[ColLast]; @@ -53,16 +52,6 @@ cleanup(void) { XCloseDisplay(dpy); } -void -drawcursor(void) { - XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; - - r.x += textnw(&dc, text, cursor) + dc.font.height / 2; - - XSetForeground(dpy, dc.gc, normcol[ColFG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); -} - void drawinput(void) { @@ -70,30 +59,30 @@ drawinput(void) dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, normcol, False); + drawtext(&dc, NULL, normcol); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, selcol, False); + drawtext(&dc, prompt, selcol); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(&dc, *text ? text : NULL, normcol, False); - drawcursor(); - XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); + drawtext(&dc, text, normcol); + drawcursor(&dc, text, cursor, normcol); + commitdraw(&dc, win); } -Bool +void grabkeyboard(void) { unsigned int len; for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) - break; + return; usleep(1000); } - return len > 0; + exit(EXIT_FAILURE); } void diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2cc2cad..c612dbe 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -162,25 +162,25 @@ drawmenu(void) { dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, normcol, False); + drawtext(&dc, NULL, normcol); dc.h = dc.font.height + 2; dc.y = topbar ? 0 : mh - dc.h; /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, selcol, False); + drawtext(&dc, prompt, selcol); dc.x += dc.w; } dc.w = mw - dc.x; /* print command */ if(cmdw && item && lines == 0) dc.w = cmdw; - drawtext(&dc, *text ? text : NULL, normcol, False); + drawtext(&dc, text, normcol); if(lines > 0) drawmenuv(); else if(curr) drawmenuh(); - XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); + commitdraw(&dc, win); } void @@ -189,16 +189,16 @@ drawmenuh(void) { dc.x += cmdw; dc.w = spaceitem; - drawtext(&dc, curr->left ? "<" : NULL, normcol, False); + drawtext(&dc, curr->left ? "<" : NULL, normcol); dc.x += dc.w; for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); - drawtext(&dc, i->text, (sel == i) ? selcol : normcol, False); + drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.x += dc.w; } dc.w = spaceitem; dc.x = mw - dc.w; - drawtext(&dc, next ? ">" : NULL, normcol, False); + drawtext(&dc, next ? ">" : NULL, normcol); } void @@ -209,7 +209,7 @@ drawmenuv(void) { dc.y = topbar ? dc.h : 0; dc.w = mw - dc.x; for(i = curr; i != next; i = i->right) { - drawtext(&dc, i->text, (sel == i) ? selcol : normcol, False); + drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.y += dc.h; } if(!XGetWindowAttributes(dpy, win, &wa)) @@ -224,11 +224,10 @@ grabkeyboard(void) { for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) - break; + return; usleep(1000); } - if(!len) - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } void From 933abed1fdf3d58b31eaf9b01f1d3df469c29e5f Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 2 Jul 2010 06:49:05 +0100 Subject: [PATCH 337/590] added dmenu.h, common.c --- dmenubar/Makefile | 10 ++- dmenubar/common.c | 129 +++++++++++++++++++++++++++++ dmenubar/config.def.h | 11 ++- dmenubar/dinput.c | 150 ++------------------------------- dmenubar/dmenu.c | 188 ++++++------------------------------------ dmenubar/dmenu.h | 30 +++++++ 6 files changed, 204 insertions(+), 314 deletions(-) create mode 100644 dmenubar/common.c create mode 100644 dmenubar/dmenu.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 0f29652..7274923 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = dinput.c dmenu.c +SRC = dinput.c dmenu.c common.c OBJ = ${SRC:.c=.o} all: options dinput dmenu @@ -24,9 +24,13 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -.o: +dinput: dinput.o common.o @echo CC -o $@ - @${CC} -o $@ $< ${LDFLAGS} + @${CC} -o $@ $+ ${LDFLAGS} + +dmenu: dmenu.o common.o + @echo CC -o $@ + @${CC} -o $@ $+ ${LDFLAGS} clean: @echo cleaning diff --git a/dmenubar/common.c b/dmenubar/common.c new file mode 100644 index 0000000..2d19aee --- /dev/null +++ b/dmenubar/common.c @@ -0,0 +1,129 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <X11/keysym.h> +#ifdef XINERAMA +#include <X11/extensions/Xinerama.h> +#endif +#include "dmenu.h" + +/* variables */ +char *prompt = NULL; +char text[4096] = ""; +int promptw = 0; +int screen; +unsigned int numlockmask = 0; +unsigned int mw, mh; +unsigned long normcol[ColLast]; +unsigned long selcol[ColLast]; +Bool topbar = True; +DC dc; +Display *dpy; +Window win, root; + +void +grabkeyboard(void) { + unsigned int len; + + for(len = 1000; len; len--) { + if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) + == GrabSuccess) + return; + usleep(1000); + } + exit(EXIT_FAILURE); +} + +void +run(void) { + XEvent ev; + + /* main event loop */ + XSync(dpy, False); + while(!XNextEvent(dpy, &ev)) + switch(ev.type) { + case KeyPress: + kpress(&ev.xkey); + break; + case Expose: + if(ev.xexpose.count == 0) + drawbar(); + break; + case VisibilityNotify: + if(ev.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(dpy, win); + break; + } + exit(EXIT_FAILURE); +} + +void +setup(unsigned int lines) { + int i, j, x, y; +#if XINERAMA + int n; + XineramaScreenInfo *info = NULL; +#endif + XModifierKeymap *modmap; + XSetWindowAttributes wa; + + /* 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); + + dc.dpy = dpy; + normcol[ColBG] = getcolor(&dc, normbgcolor); + normcol[ColFG] = getcolor(&dc, normfgcolor); + selcol[ColBG] = getcolor(&dc, selbgcolor); + selcol[ColFG] = getcolor(&dc, selfgcolor); + initfont(&dc, font); + + /* input window */ + wa.override_redirect = True; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + + /* input window geometry */ + mh = (dc.font.height + 2) * (lines + 1); +#if XINERAMA + if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + i = 0; + if(n > 1) { + int di; + unsigned int dui; + Window dummy; + if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) + for(i = 0; i < n; i++) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + break; + } + x = info[i].x_org; + y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; + mw = info[i].width; + XFree(info); + } + else +#endif + { + x = 0; + y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; + mw = DisplayWidth(dpy, screen); + } + + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + + setupdraw(&dc, win); + if(prompt) + promptw = MIN(textw(&dc, prompt), mw / 5); + XMapRaised(dpy, win); +} diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index cda3b2a..eae3f08 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -1,9 +1,8 @@ /* See LICENSE file for copyright and license details. */ /* appearance */ -const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; -const char *normbgcolor = "#cccccc"; -const char *normfgcolor = "#000000"; -const char *selbgcolor = "#0066ff"; -const char *selfgcolor = "#ffffff"; -unsigned int spaceitem = 30; /* px between menu items */ +static const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; +static const char *normbgcolor = "#cccccc"; +static const char *normfgcolor = "#000000"; +static const char *selbgcolor = "#0066ff"; +static const char *selfgcolor = "#ffffff"; diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index 0d0adeb..e22bc35 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -4,45 +4,16 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include <X11/keysym.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#ifdef XINERAMA -#include <X11/extensions/Xinerama.h> -#endif -#include <draw.h> - -/* macros */ -#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) +#include "dmenu.h" /* forward declarations */ static void cleanup(void); -static void drawinput(void); -static void grabkeyboard(void); -static void kpress(XKeyEvent *e); -static void run(void); -static void setup(void); - -#include "config.h" /* variables */ -static char *prompt = NULL; -static char text[4096]; -static int promptw = 0; -static int screen; static size_t cursor = 0; -static unsigned int numlockmask = 0; -static unsigned int mw, mh; -static unsigned long normcol[ColLast]; -static unsigned long selcol[ColLast]; -static Bool topbar = True; -static DC dc; -static Display *dpy; -static Window win, root; void cleanup(void) { @@ -53,7 +24,7 @@ cleanup(void) { } void -drawinput(void) +drawbar(void) { dc.x = 0; dc.y = 0; @@ -72,19 +43,6 @@ drawinput(void) commitdraw(&dc, win); } -void -grabkeyboard(void) { - unsigned int len; - - for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) - == GrabSuccess) - return; - usleep(1000); - } - exit(EXIT_FAILURE); -} - void kpress(XKeyEvent *e) { char buf[sizeof text]; @@ -207,101 +165,7 @@ kpress(XKeyEvent *e) { while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); break; } - drawinput(); -} - -void -run(void) { - XEvent ev; - - /* main event loop */ - XSync(dpy, False); - while(!XNextEvent(dpy, &ev)) - switch(ev.type) { - case KeyPress: - kpress(&ev.xkey); - break; - case Expose: - if(ev.xexpose.count == 0) - drawinput(); - break; - case VisibilityNotify: - if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - exit(EXIT_FAILURE); -} - -void -setup(void) { - int i, j, x, y; -#if XINERAMA - int n; - XineramaScreenInfo *info = NULL; -#endif - XModifierKeymap *modmap; - XSetWindowAttributes wa; - - /* 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); - - dc.dpy = dpy; - normcol[ColBG] = getcolor(&dc, normbgcolor); - normcol[ColFG] = getcolor(&dc, normfgcolor); - selcol[ColBG] = getcolor(&dc, selbgcolor); - selcol[ColFG] = getcolor(&dc, selfgcolor); - initfont(&dc, font); - - /* input window */ - wa.override_redirect = True; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - - /* input window geometry */ - mh = dc.font.height + 2; -#if XINERAMA - if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { - i = 0; - if(n > 1) { - int di; - unsigned int dui; - Window dummy; - if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) - for(i = 0; i < n; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) - break; - } - x = info[i].x_org; - y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; - mw = info[i].width; - XFree(info); - } - else -#endif - { - x = 0; - y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; - mw = DisplayWidth(dpy, screen); - } - - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - - setupdraw(&dc, win); - if(prompt) - promptw = MIN(textw(&dc, prompt), mw / 5); - cursor = strlen(text); - XMapRaised(dpy, win); + drawbar(); } int @@ -336,11 +200,13 @@ main(int argc, char *argv[]) { if(++i < argc) selfgcolor = argv[i]; } else if(!strcmp(argv[i], "-v")) { - printf("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n"); + printf("dinput-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); exit(EXIT_SUCCESS); } - else if(!*text) + else if(!*text) { strncpy(text, argv[i], sizeof text); + cursor = strlen(text); + } else { fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr); @@ -356,7 +222,7 @@ main(int argc, char *argv[]) { root = RootWindow(dpy, screen); grabkeyboard(); - setup(); + setup(0); run(); return 0; } diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c612dbe..6fc414c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -8,16 +8,7 @@ #include <X11/keysym.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#ifdef XINERAMA -#include <X11/extensions/Xinerama.h> -#endif -#include <draw.h> - -/* macros */ -#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) +#include "dmenu.h" typedef struct Item Item; struct Item { @@ -33,41 +24,22 @@ static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); static void dinput(void); -static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); -static void grabkeyboard(void); -static void kpress(XKeyEvent *e); -static void match(char *pattern); +static void match(void); static void readstdin(void); -static void run(void); -static void setup(void); - -#include "config.h" /* variables */ static char **argp = NULL; static char *maxname = NULL; -static char *prompt = NULL; -static char text[4096]; -static int cmdw = 0; -static int promptw = 0; -static int screen; +static unsigned int cmdw = 0; static unsigned int lines = 0; -static unsigned int numlockmask = 0; -static unsigned int mw, mh; -static unsigned long normcol[ColLast]; -static unsigned long selcol[ColLast]; -static Bool topbar = True; -static DC dc; -static Display *dpy; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; -static Window win, root; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static void (*calcoffsets)(void) = calcoffsetsh; @@ -85,14 +57,13 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsetsh(void) { - unsigned int x; + unsigned int w, x; - x = promptw + cmdw + (2 * spaceitem); - for(next = curr; next; next = next->right) + w = promptw + cmdw + textw(&dc, "<") + textw(&dc, ">"); + for(x = w, next = curr; next; next = next->right) if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) break; - x = promptw + cmdw + (2 * spaceitem); - for(prev = curr; prev && prev->left; prev = prev->left) + for(x = w, prev = curr; prev && prev->left; prev = prev->left) if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) break; } @@ -157,7 +128,7 @@ dinput(void) { } void -drawmenu(void) { +drawbar(void) { dc.x = 0; dc.y = 0; dc.w = mw; @@ -188,7 +159,7 @@ drawmenuh(void) { Item *i; dc.x += cmdw; - dc.w = spaceitem; + dc.w = textw(&dc, "<"); drawtext(&dc, curr->left ? "<" : NULL, normcol); dc.x += dc.w; for(i = curr; i != next; i = i->right) { @@ -196,7 +167,7 @@ drawmenuh(void) { drawtext(&dc, i->text, (sel == i) ? selcol : normcol); dc.x += dc.w; } - dc.w = spaceitem; + dc.w = textw(&dc, ">"); dc.x = mw - dc.w; drawtext(&dc, next ? ">" : NULL, normcol); } @@ -217,19 +188,6 @@ drawmenuv(void) { XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); } -void -grabkeyboard(void) { - unsigned int len; - - for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) - == GrabSuccess) - return; - usleep(1000); - } - exit(EXIT_FAILURE); -} - void kpress(XKeyEvent *e) { char buf[sizeof text]; @@ -285,7 +243,7 @@ kpress(XKeyEvent *e) { break; case XK_u: text[0] = '\0'; - match(text); + match(); break; case XK_w: if(len == 0) @@ -294,7 +252,7 @@ kpress(XKeyEvent *e) { while(i-- > 0 && text[i] == ' '); while(i-- > 0 && text[i] != ' '); text[++i] = '\0'; - match(text); + match(); break; } } @@ -304,7 +262,7 @@ kpress(XKeyEvent *e) { if(num && !iscntrl((int) buf[0])) { memcpy(text + len, buf, num + 1); len += num; - match(text); + match(); } break; case XK_BackSpace: @@ -313,7 +271,7 @@ kpress(XKeyEvent *e) { for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[len - i]); i++); len -= i; text[len] = '\0'; - match(text); + match(); break; case XK_End: while(next) { @@ -373,24 +331,22 @@ kpress(XKeyEvent *e) { dinput(); break; } - drawmenu(); + drawbar(); } void -match(char *pattern) { - unsigned int plen; +match(void) { + unsigned int len; Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - if(!pattern) - return; - plen = strlen(pattern); + len = strlen(text); item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; for(i = allitems; i; i = i->next) - if(!fstrncmp(pattern, i->text, plen + 1)) + if(!fstrncmp(text, i->text, len + 1)) appenditem(i, &lexact, &exactend); - else if(!fstrncmp(pattern, i->text, plen)) + else if(!fstrncmp(text, i->text, len)) appenditem(i, &lprefix, &prefixend); - else if(fstrstr(i->text, pattern)) + else if(fstrstr(i->text, text)) appenditem(i, &lsubstr, &substrend); if(lexact) { item = lexact; @@ -444,103 +400,6 @@ readstdin(void) { } } -void -run(void) { - XEvent ev; - - /* main event loop */ - XSync(dpy, False); - while(!XNextEvent(dpy, &ev)) - switch(ev.type) { - case KeyPress: - kpress(&ev.xkey); - break; - case Expose: - if(ev.xexpose.count == 0) - drawmenu(); - break; - case VisibilityNotify: - if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - exit(EXIT_FAILURE); -} - -void -setup(void) { - int i, j, x, y; -#if XINERAMA - int n; - XineramaScreenInfo *info = NULL; -#endif - XModifierKeymap *modmap; - XSetWindowAttributes wa; - - /* 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); - - dc.dpy = dpy; - normcol[ColBG] = getcolor(&dc, normbgcolor); - normcol[ColFG] = getcolor(&dc, normfgcolor); - selcol[ColBG] = getcolor(&dc, selbgcolor); - selcol[ColFG] = getcolor(&dc, selfgcolor); - initfont(&dc, font); - - /* menu window */ - wa.override_redirect = True; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - - /* menu window geometry */ - mh = (dc.font.height + 2) * (lines + 1); -#if XINERAMA - if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { - i = 0; - if(n > 1) { - int di; - unsigned int dui; - Window dummy; - if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) - for(i = 0; i < n; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) - break; - } - x = info[i].x_org; - y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; - mw = info[i].width; - XFree(info); - } - else -#endif - { - x = 0; - y = topbar ? 0 : mh - DisplayHeight(dpy, screen); - mw = DisplayWidth(dpy, screen); - } - - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - - setupdraw(&dc, win); - if(maxname) - cmdw = MIN(textw(&dc, maxname), mw / 3); - if(prompt) - promptw = MIN(textw(&dc, prompt), mw / 5); - text[0] = '\0'; - match(text); - XMapRaised(dpy, win); -} - int main(int argc, char *argv[]) { unsigned int i; @@ -600,7 +459,10 @@ main(int argc, char *argv[]) { readstdin(); grabkeyboard(); - setup(); + setup(lines); + if(maxname) + cmdw = MIN(textw(&dc, maxname), mw / 3); + match(); run(); return 0; } diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h new file mode 100644 index 0000000..4cc13f4 --- /dev/null +++ b/dmenubar/dmenu.h @@ -0,0 +1,30 @@ +#include <X11/Xlib.h> +#include <draw.h> +#include "config.h" + +/* macros */ +#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) + +/* forward declarations */ +void drawbar(void); +void grabkeyboard(void); +void kpress(XKeyEvent *e); +void run(void); +void setup(unsigned int lines); + +/* variables */ +extern char *prompt; +extern char text[4096]; +extern int promptw; +extern int screen; +extern unsigned int numlockmask; +extern unsigned int mw, mh; +extern unsigned long normcol[ColLast]; +extern unsigned long selcol[ColLast]; +extern Bool topbar; +extern DC dc; +extern Display *dpy; +extern Window win, root; From b636201651a8feb746199cb529507cb82e0b61c7 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 27 Jul 2010 13:40:32 +0100 Subject: [PATCH 338/590] updated to libdraw tip --- dmenubar/dinput.c | 2 +- dmenubar/dmenu.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index e22bc35..e861afc 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -30,7 +30,7 @@ drawbar(void) dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, normcol); + drawbox(&dc, normcol); /* print prompt? */ if(prompt) { dc.w = promptw; diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6fc414c..b460701 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -133,7 +133,7 @@ drawbar(void) { dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, normcol); + drawbox(&dc, normcol); dc.h = dc.font.height + 2; dc.y = topbar ? 0 : mh - dc.h; /* print prompt? */ @@ -156,6 +156,7 @@ drawbar(void) { void drawmenuh(void) { + unsigned long *col; Item *i; dc.x += cmdw; @@ -164,7 +165,9 @@ drawmenuh(void) { dc.x += dc.w; for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); - drawtext(&dc, i->text, (sel == i) ? selcol : normcol); + col = (sel == i) ? selcol : normcol; + drawbox(&dc, col); + drawtext(&dc, i->text, col); dc.x += dc.w; } dc.w = textw(&dc, ">"); From 1499ee8c991eda3c9f1fb150b2148ea659f51065 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 30 Jul 2010 09:18:35 +0100 Subject: [PATCH 339/590] fixed vlist select --- dmenubar/dmenu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b460701..2c1867c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -24,6 +24,7 @@ static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); static void dinput(void); +static void drawitem(char *s, unsigned long col[ColLast]); static void drawmenuh(void); static void drawmenuv(void); static void match(void); @@ -154,9 +155,14 @@ drawbar(void) { commitdraw(&dc, win); } +void +drawitem(char *s, unsigned long col[ColLast]) { + drawbox(&dc, col); + drawtext(&dc, s, col); +} + void drawmenuh(void) { - unsigned long *col; Item *i; dc.x += cmdw; @@ -165,9 +171,7 @@ drawmenuh(void) { dc.x += dc.w; for(i = curr; i != next; i = i->right) { dc.w = MIN(textw(&dc, i->text), mw / 3); - col = (sel == i) ? selcol : normcol; - drawbox(&dc, col); - drawtext(&dc, i->text, col); + drawitem(i->text, (sel == i) ? selcol : normcol); dc.x += dc.w; } dc.w = textw(&dc, ">"); @@ -183,7 +187,7 @@ drawmenuv(void) { dc.y = topbar ? dc.h : 0; dc.w = mw - dc.x; for(i = curr; i != next; i = i->right) { - drawtext(&dc, i->text, (sel == i) ? selcol : normcol); + drawitem(i->text, (sel == i) ? selcol : normcol); dc.y += dc.h; } if(!XGetWindowAttributes(dpy, win, &wa)) From c92a4fd624ff9c0e923e51f3d45d43f7e3451c75 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 30 Jul 2010 10:25:55 +0100 Subject: [PATCH 340/590] new libdraw --- dmenubar/dinput.c | 4 +++- dmenubar/dmenu.c | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c index e861afc..4bbc7bc 100644 --- a/dmenubar/dinput.c +++ b/dmenubar/dinput.c @@ -34,12 +34,14 @@ drawbar(void) /* print prompt? */ if(prompt) { dc.w = promptw; + drawbox(&dc, selcol); drawtext(&dc, prompt, selcol); dc.x += dc.w; } dc.w = mw - dc.x; drawtext(&dc, text, normcol); - drawcursor(&dc, text, cursor, normcol); + drawline(&dc, textnw(&dc, text, cursor) + dc.font.height/2, 2, 1, + dc.font.height-2, normcol); commitdraw(&dc, win); } diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2c1867c..076cffe 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -24,7 +24,7 @@ static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); static void dinput(void); -static void drawitem(char *s, unsigned long col[ColLast]); +static void drawitem(const char *s, unsigned long col[ColLast]); static void drawmenuh(void); static void drawmenuv(void); static void match(void); @@ -140,6 +140,7 @@ drawbar(void) { /* print prompt? */ if(prompt) { dc.w = promptw; + drawbox(&dc, selcol); drawtext(&dc, prompt, selcol); dc.x += dc.w; } @@ -156,7 +157,7 @@ drawbar(void) { } void -drawitem(char *s, unsigned long col[ColLast]) { +drawitem(const char *s, unsigned long col[ColLast]) { drawbox(&dc, col); drawtext(&dc, s, col); } From f32666ef340d3c4e6e729591c5ce3bed0c9462dd Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 30 Jul 2010 10:26:12 +0100 Subject: [PATCH 341/590] underline match --- dmenubar/dmenu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 076cffe..9386e06 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -158,8 +158,13 @@ drawbar(void) { void drawitem(const char *s, unsigned long col[ColLast]) { + const char *p; + unsigned int w = textnw(&dc, text, strlen(text)); + drawbox(&dc, col); drawtext(&dc, s, col); + for(p = fstrstr(s, text); *text && (p = fstrstr(p, text)); p++) + drawline(&dc, textnw(&dc, s, p-s) + dc.h/2 - 1, dc.h-2, w, 1, col); } void From 61cb1c320e36a446e151c0201a7d35521f159a32 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 30 Jul 2010 13:40:56 +0100 Subject: [PATCH 342/590] merged dmenu & dinput (clunky interface) --- dmenubar/Makefile | 15 +-- dmenubar/common.c | 129 ------------------------ dmenubar/dinput.c | 230 ------------------------------------------ dmenubar/dmenu.c | 251 ++++++++++++++++++++++++++++++++++++++-------- dmenubar/dmenu.h | 30 ------ 5 files changed, 215 insertions(+), 440 deletions(-) delete mode 100644 dmenubar/common.c delete mode 100644 dmenubar/dinput.c delete mode 100644 dmenubar/dmenu.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 7274923..0d16e38 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = dinput.c dmenu.c common.c +SRC = dmenu.c OBJ = ${SRC:.c=.o} all: options dinput dmenu @@ -24,17 +24,13 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -dinput: dinput.o common.o - @echo CC -o $@ - @${CC} -o $@ $+ ${LDFLAGS} - -dmenu: dmenu.o common.o +dmenu: ${OBJ} @echo CC -o $@ @${CC} -o $@ $+ ${LDFLAGS} clean: @echo cleaning - @rm -f dinput dmenu ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @@ -47,8 +43,7 @@ dist: clean install: all @echo installing executable file to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dinput dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/dinput + @cp -f dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run @@ -60,7 +55,7 @@ install: all uninstall: @echo removing executable file from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_path - @rm -f ${DESTDIR}${PREFIX}/bin/dinput ${DESTDIR}${PREFIX}/bin/dmenu_run + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 diff --git a/dmenubar/common.c b/dmenubar/common.c deleted file mode 100644 index 2d19aee..0000000 --- a/dmenubar/common.c +++ /dev/null @@ -1,129 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <X11/keysym.h> -#ifdef XINERAMA -#include <X11/extensions/Xinerama.h> -#endif -#include "dmenu.h" - -/* variables */ -char *prompt = NULL; -char text[4096] = ""; -int promptw = 0; -int screen; -unsigned int numlockmask = 0; -unsigned int mw, mh; -unsigned long normcol[ColLast]; -unsigned long selcol[ColLast]; -Bool topbar = True; -DC dc; -Display *dpy; -Window win, root; - -void -grabkeyboard(void) { - unsigned int len; - - for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) - == GrabSuccess) - return; - usleep(1000); - } - exit(EXIT_FAILURE); -} - -void -run(void) { - XEvent ev; - - /* main event loop */ - XSync(dpy, False); - while(!XNextEvent(dpy, &ev)) - switch(ev.type) { - case KeyPress: - kpress(&ev.xkey); - break; - case Expose: - if(ev.xexpose.count == 0) - drawbar(); - break; - case VisibilityNotify: - if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - exit(EXIT_FAILURE); -} - -void -setup(unsigned int lines) { - int i, j, x, y; -#if XINERAMA - int n; - XineramaScreenInfo *info = NULL; -#endif - XModifierKeymap *modmap; - XSetWindowAttributes wa; - - /* 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); - - dc.dpy = dpy; - normcol[ColBG] = getcolor(&dc, normbgcolor); - normcol[ColFG] = getcolor(&dc, normfgcolor); - selcol[ColBG] = getcolor(&dc, selbgcolor); - selcol[ColFG] = getcolor(&dc, selfgcolor); - initfont(&dc, font); - - /* input window */ - wa.override_redirect = True; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - - /* input window geometry */ - mh = (dc.font.height + 2) * (lines + 1); -#if XINERAMA - if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { - i = 0; - if(n > 1) { - int di; - unsigned int dui; - Window dummy; - if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) - for(i = 0; i < n; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) - break; - } - x = info[i].x_org; - y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; - mw = info[i].width; - XFree(info); - } - else -#endif - { - x = 0; - y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; - mw = DisplayWidth(dpy, screen); - } - - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - - setupdraw(&dc, win); - if(prompt) - promptw = MIN(textw(&dc, prompt), mw / 5); - XMapRaised(dpy, win); -} diff --git a/dmenubar/dinput.c b/dmenubar/dinput.c deleted file mode 100644 index 4bbc7bc..0000000 --- a/dmenubar/dinput.c +++ /dev/null @@ -1,230 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <ctype.h> -#include <locale.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <X11/keysym.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include "dmenu.h" - -/* forward declarations */ -static void cleanup(void); - -/* variables */ -static size_t cursor = 0; - -void -cleanup(void) { - cleanupdraw(&dc); - XDestroyWindow(dpy, win); - XUngrabKeyboard(dpy, CurrentTime); - XCloseDisplay(dpy); -} - -void -drawbar(void) -{ - dc.x = 0; - dc.y = 0; - dc.w = mw; - dc.h = mh; - drawbox(&dc, normcol); - /* print prompt? */ - if(prompt) { - dc.w = promptw; - drawbox(&dc, selcol); - drawtext(&dc, prompt, selcol); - dc.x += dc.w; - } - dc.w = mw - dc.x; - drawtext(&dc, text, normcol); - drawline(&dc, textnw(&dc, text, cursor) + dc.font.height/2, 2, 1, - dc.font.height-2, normcol); - commitdraw(&dc, win); -} - -void -kpress(XKeyEvent *e) { - char buf[sizeof text]; - int num; - unsigned int i, len; - KeySym ksym; - - len = strlen(text); - num = XLookupString(e, buf, sizeof buf, &ksym, NULL); - if(ksym == XK_KP_Enter) - ksym = XK_Return; - else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) - ksym = (ksym - XK_KP_0) + XK_0; - else if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) - || IsPrivateKeypadKey(ksym)) - return; - /* first check if a control mask is omitted */ - if(e->state & ControlMask) { - switch(tolower(ksym)) { - default: - return; - case XK_a: - ksym = XK_Home; - break; - case XK_b: - ksym = XK_Left; - break; - case XK_c: - ksym = XK_Escape; - break; - case XK_e: - ksym = XK_End; - break; - case XK_f: - ksym = XK_Right; - break; - case XK_h: - ksym = XK_BackSpace; - break; - case XK_j: - case XK_m: - ksym = XK_Return; - break; - case XK_k: - text[cursor] = '\0'; - break; - case XK_u: - memmove(text, text + cursor, sizeof text - cursor + 1); - cursor = 0; - break; - case XK_w: - if(cursor > 0) { - i = cursor; - while(i-- > 0 && text[i] == ' '); - while(i-- > 0 && text[i] != ' '); - memmove(text + i + 1, text + cursor, sizeof text - cursor + 1); - cursor = i + 1; - } - break; - case XK_y: - { - FILE *fp; - char *s; - if(!(fp = popen("sselp", "r"))) - eprint("cannot popen sselp\n"); - s = fgets(buf, sizeof buf, fp); - pclose(fp); - if(s == NULL) - return; - } - num = strlen(buf); - if(num && buf[num-1] == '\n') - buf[--num] = '\0'; - break; - } - } - switch(ksym) { - default: - num = MIN(num, sizeof text - cursor); - if(num && !iscntrl((int) buf[0])) { - memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); - memcpy(text + cursor, buf, num); - cursor += num; - } - break; - case XK_BackSpace: - if(cursor == 0) - return; - for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); - memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); - cursor -= i; - break; - case XK_Delete: - if(cursor == len) - return; - for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); - memmove(text + cursor, text + cursor + i, sizeof text - cursor); - break; - case XK_End: - cursor = len; - break; - case XK_Escape: - exit(EXIT_FAILURE); - case XK_Home: - cursor = 0; - break; - case XK_Left: - if(cursor == 0) - return; - while(cursor-- > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); - break; - case XK_Return: - fprintf(stdout, "%s", text); - fflush(stdout); - exit(EXIT_SUCCESS); - case XK_Right: - if(cursor == len) - return; - while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); - break; - } - drawbar(); -} - -int -main(int argc, char *argv[]) { - unsigned int i; - - /* command line args */ - progname = "dinput"; - for(i = 1; i < argc; i++) - if(!strcmp(argv[i], "-i")) - ; /* ignore flag */ - else if(!strcmp(argv[i], "-b")) - topbar = False; - else if(!strcmp(argv[i], "-l")) - i++; /* ignore flag */ - else if(!strcmp(argv[i], "-fn")) { - if(++i < argc) font = argv[i]; - } - else if(!strcmp(argv[i], "-nb")) { - if(++i < argc) normbgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-nf")) { - if(++i < argc) normfgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-p")) { - if(++i < argc) prompt = argv[i]; - } - else if(!strcmp(argv[i], "-sb")) { - if(++i < argc) selbgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-v")) { - printf("dinput-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); - exit(EXIT_SUCCESS); - } - else if(!*text) { - strncpy(text, argv[i], sizeof text); - cursor = strlen(text); - } - else { - fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr); - exit(EXIT_FAILURE); - } - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "dinput: warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) - eprint("cannot open display\n"); - if(atexit(&cleanup) != 0) - eprint("cannot register cleanup\n"); - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - - grabkeyboard(); - setup(0); - run(); - return 0; -} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9386e06..1fdf7f5 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -8,7 +8,16 @@ #include <X11/keysym.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#include "dmenu.h" +#ifdef XINERAMA +#include <X11/extensions/Xinerama.h> +#endif +#include <draw.h> +#include "config.h" + +#define INRECT(x,y,rx,ry,rw,rh) ((rx) < (x) && (x) < (rx)+(rw) && (ry) < (y) && (y) < (ry)+(rh)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define IS_UTF8_1ST_CHAR(c) (((c) & 0xc0) == 0xc0 || ((c) & 0x80) == 0x00) typedef struct Item Item; struct Item { @@ -17,30 +26,46 @@ struct Item { Item *left, *right; /* traverses items matching current search pattern */ }; -/* forward declarations */ static void appenditem(Item *i, Item **list, Item **last); static void calcoffsetsh(void); static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); -static void dinput(void); static void drawitem(const char *s, unsigned long col[ColLast]); +static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); +static void grabkeyboard(void); +static void keypress(XKeyEvent *e); static void match(void); static void readstdin(void); +static void run(void); +static void setup(void); -/* variables */ static char **argp = NULL; static char *maxname = NULL; +static char *prompt; +static char text[4096]; +static int promptw; +static int screen; +static size_t cur = 0; static unsigned int cmdw = 0; static unsigned int lines = 0; +static unsigned int numlockmask; +static unsigned int mw, mh; +static unsigned long normcol[ColLast]; +static unsigned long selcol[ColLast]; +static Bool topbar = True; +static DC dc; +static Display *dpy; static Item *allitems = NULL; /* first of all items */ static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; static Item *curr = NULL; +static Window win, root; + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static void (*calcoffsets)(void) = calcoffsetsh; @@ -120,16 +145,18 @@ cleanup(void) { } void -dinput(void) { - cleanup(); - argp[0] = "dinput"; - argp[1] = text; - execvp("dinput", argp); - eprint("cannot exec dinput\n"); +drawitem(const char *s, unsigned long col[ColLast]) { + const char *p; + unsigned int w = textnw(&dc, text, strlen(text)); + + drawbox(&dc, col); + drawtext(&dc, s, col); + for(p = fstrstr(s, text); *text && (p = fstrstr(p, text)); p++) + drawline(&dc, textnw(&dc, s, p-s) + dc.h/2 - 1, dc.h-2, w, 1, col); } void -drawbar(void) { +drawmenu(void) { dc.x = 0; dc.y = 0; dc.w = mw; @@ -149,6 +176,7 @@ drawbar(void) { if(cmdw && item && lines == 0) dc.w = cmdw; drawtext(&dc, text, normcol); + drawline(&dc, textnw(&dc, text, cur) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); if(lines > 0) drawmenuv(); else if(curr) @@ -156,17 +184,6 @@ drawbar(void) { commitdraw(&dc, win); } -void -drawitem(const char *s, unsigned long col[ColLast]) { - const char *p; - unsigned int w = textnw(&dc, text, strlen(text)); - - drawbox(&dc, col); - drawtext(&dc, s, col); - for(p = fstrstr(s, text); *text && (p = fstrstr(p, text)); p++) - drawline(&dc, textnw(&dc, s, p-s) + dc.h/2 - 1, dc.h-2, w, 1, col); -} - void drawmenuh(void) { Item *i; @@ -202,7 +219,19 @@ drawmenuv(void) { } void -kpress(XKeyEvent *e) { +grabkeyboard(void) { + unsigned int n; + + for(n = 0; n < 1000; n++) { + if(!XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) + return; + usleep(1000); + } + exit(EXIT_FAILURE); +} + +void +keypress(XKeyEvent *e) { char buf[sizeof text]; int num; unsigned int i, len; @@ -248,6 +277,9 @@ kpress(XKeyEvent *e) { case XK_m: ksym = XK_Return; break; + case XK_k: + text[cur] = '\0'; + break; case XK_n: ksym = XK_Down; break; @@ -255,38 +287,67 @@ kpress(XKeyEvent *e) { ksym = XK_Up; break; case XK_u: - text[0] = '\0'; + memmove(text, text + cur, sizeof text - cur + 1); + cur = 0; match(); break; case XK_w: - if(len == 0) + if(cur == 0) return; - i = len; + i = cur; while(i-- > 0 && text[i] == ' '); while(i-- > 0 && text[i] != ' '); - text[++i] = '\0'; + memmove(text + i + 1, text + cur, sizeof text - cur + 1); + cur = i + 1; match(); break; + case XK_y: + { + FILE *fp; + char *s; + if(!(fp = fopen("sselp", "r"))) + eprint("cannot popen sselp\n"); + s = fgets(buf, sizeof buf, fp); + fclose(fp); + if(!s) + return; + } + num = strlen(buf); + if(num && buf[num-1] == '\n') + buf[--num] = '\0'; + break; } } switch(ksym) { default: num = MIN(num, sizeof text); if(num && !iscntrl((int) buf[0])) { - memcpy(text + len, buf, num + 1); - len += num; + memmove(text + cur + num, text + cur, sizeof text - cur - num); + memcpy(text + cur, buf, num); + cur += num; match(); } break; case XK_BackSpace: - if(len == 0) + if(cur == 0) return; - for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[len - i]); i++); - len -= i; - text[len] = '\0'; + for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[cur - i]); i++); + memmove(text + cur - i, text + cur, sizeof text - cur + i); + cur -= i; + match(); + break; + case XK_Delete: + if(cur == len) + return; + for(i = 1; cur + i < len && !IS_UTF8_1ST_CHAR(text[cur + i]); i++); + memmove(text + cur, text + cur + i, sizeof text - cur); match(); break; case XK_End: + if(cur < len) { + cur = len; + break; + } while(next) { sel = curr = next; calcoffsets(); @@ -297,10 +358,20 @@ kpress(XKeyEvent *e) { case XK_Escape: exit(EXIT_FAILURE); case XK_Home: + if(sel == item) { + cur = 0; + break; + } sel = curr = item; calcoffsets(); break; case XK_Left: + if(cur > 0 && (!sel || !sel->left || lines > 0)) { + while(cur-- > 0 && !IS_UTF8_1ST_CHAR(text[cur])); + break; + } + if(lines > 0) + return; case XK_Up: if(!sel || !sel->left) return; @@ -323,12 +394,16 @@ kpress(XKeyEvent *e) { calcoffsets(); break; case XK_Return: - if(e->state & ShiftMask) - dinput(); - fprintf(stdout, "%s", sel ? sel->text : text); + fprintf(stdout, "%s", ((e->state & ShiftMask) || sel) ? sel->text : text); fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: + if(cur < len) { + while(cur++ < len && !IS_UTF8_1ST_CHAR(text[cur])); + break; + } + if(lines > 0) + return; case XK_Down: if(!sel || !sel->right) return; @@ -339,12 +414,14 @@ kpress(XKeyEvent *e) { } break; case XK_Tab: - if(sel) - strncpy(text, sel->text, sizeof text); - dinput(); + if(!sel) + return; + strncpy(text, sel->text, sizeof text); + cur = strlen(text); + match(); break; } - drawbar(); + drawmenu(); } void @@ -413,6 +490,98 @@ readstdin(void) { } } +void +run(void) { + XEvent ev; + + XSync(dpy, False); + while(!XNextEvent(dpy, &ev)) + switch(ev.type) { + case Expose: + if(ev.xexpose.count == 0) + drawmenu(); + break; + case KeyPress: + keypress(&ev.xkey); + break; + case VisibilityNotify: + if(ev.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(dpy, win); + break; + } + exit(EXIT_FAILURE); +} + +void +setup(void) { + int i, j, x, y; +#if XINERAMA + int n; + XineramaScreenInfo *info = NULL; +#endif + XModifierKeymap *modmap; + XSetWindowAttributes wa; + + /* 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); + + dc.dpy = dpy; + normcol[ColBG] = getcolor(&dc, normbgcolor); + normcol[ColFG] = getcolor(&dc, normfgcolor); + selcol[ColBG] = getcolor(&dc, selbgcolor); + selcol[ColFG] = getcolor(&dc, selfgcolor); + initfont(&dc, font); + + /* input window */ + wa.override_redirect = True; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + + /* input window geometry */ + mh = (dc.font.height + 2) * (lines + 1); +#if XINERAMA + if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + i = 0; + if(n > 1) { + int di; + unsigned int dui; + Window dummy; + if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) + for(i = 0; i < n; i++) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + break; + } + x = info[i].x_org; + y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; + mw = info[i].width; + XFree(info); + } + else +#endif + { + x = 0; + y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; + mw = DisplayWidth(dpy, screen); + } + + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + + setupdraw(&dc, win); + if(prompt) + promptw = MIN(textw(&dc, prompt), mw / 5); + XMapRaised(dpy, win); +} + int main(int argc, char *argv[]) { unsigned int i; @@ -472,7 +641,7 @@ main(int argc, char *argv[]) { readstdin(); grabkeyboard(); - setup(lines); + setup(); if(maxname) cmdw = MIN(textw(&dc, maxname), mw / 3); match(); diff --git a/dmenubar/dmenu.h b/dmenubar/dmenu.h deleted file mode 100644 index 4cc13f4..0000000 --- a/dmenubar/dmenu.h +++ /dev/null @@ -1,30 +0,0 @@ -#include <X11/Xlib.h> -#include <draw.h> -#include "config.h" - -/* macros */ -#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) - -/* forward declarations */ -void drawbar(void); -void grabkeyboard(void); -void kpress(XKeyEvent *e); -void run(void); -void setup(unsigned int lines); - -/* variables */ -extern char *prompt; -extern char text[4096]; -extern int promptw; -extern int screen; -extern unsigned int numlockmask; -extern unsigned int mw, mh; -extern unsigned long normcol[ColLast]; -extern unsigned long selcol[ColLast]; -extern Bool topbar; -extern DC dc; -extern Display *dpy; -extern Window win, root; From 19b745f9b148d707f4adabe10bacbaf613bbb3a5 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 31 Jul 2010 14:56:27 +0100 Subject: [PATCH 343/590] updated manpage, added paste, cleaned up, new libdraw --- dmenubar/Makefile | 2 +- dmenubar/README | 6 +- dmenubar/dmenu.1 | 102 +++++----- dmenubar/dmenu.c | 490 +++++++++++++++++++++------------------------- 4 files changed, 276 insertions(+), 324 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 0d16e38..269bc27 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -6,7 +6,7 @@ include config.mk SRC = dmenu.c OBJ = ${SRC:.c=.o} -all: options dinput dmenu +all: options dmenu options: @echo dmenu build options: diff --git a/dmenubar/README b/dmenubar/README index 3706ef1..9f0583a 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -8,13 +8,11 @@ Requirements In order to build dmenu you need the Xlib header files. You also need libdraw, available from http://hg.suckless.org/libdraw -Pasting the X selection to dmenu requires the sselp utility at runtime. - Installation ------------ -Edit config.mk to match your local setup (dmenu is installed into -the /usr/local namespace by default). +Edit config.mk to match your local setup (dmenu is installed into the +/usr/local namespace by default). Afterwards enter the following command to build and install dmenu (if necessary as root): diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index f0c45f4..2d8bc20 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,99 +3,103 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-i ] .RB [ \-b ] -.RB [ \-e " <xid>]" +.RB [ \-i ] .RB [ \-l " <lines>]" +.RB [ \-p " <prompt>]" .RB [ \-fn " <font>]" .RB [ \-nb " <color>]" .RB [ \-nf " <color>]" -.RB [ \-p " <prompt>]" .RB [ \-sb " <color>]" .RB [ \-sf " <color>]" .RB [ \-v ] .B dmenu_run -[<options...>] +.RB [ \-b ] +.RB [ \-i ] +.RB [ \-l " <lines>]" +.RB [ \-p " <prompt>]" +.RB [ \-fn " <font>]" +.RB [ \-nb " <color>]" +.RB [ \-nf " <color>]" +.RB [ \-sb " <color>]" +.RB [ \-sf " <color>]" +.RB [ \-v ] .B dmenu_path .SH DESCRIPTION .SS Overview -dmenu is a generic menu for X, originally designed for +.B dmenu +is a generic menu for X, originally designed for .BR dwm (1). -It manages huge amounts (up to 10.000 and more) of user defined menu items -efficiently. - -dmenu_run is a dmenu script used by dwm which lists executables in the user's PATH -and executes the selected item. - -dmenu_path is a script used by dmenu_run to find and cache a list of executables. +It manages huge amounts (10000 and more) of user defined menu items efficiently. +.P +.B dmenu_run +is a dmenu script which lists programs in the user's PATH and executes +the selected item. +.P +.B dmenu_path +is a script used by +.I dmenu_run +to find and cache a list of programs. .SS Options .TP -.B \-i -makes dmenu match menu entries case insensitively. -.TP .B \-b -defines that dmenu appears at the bottom. +dmenu appears at the bottom of the screen. .TP -.B \-e <xid> -reparents dmenu to the window specified by xid. +.B \-i +dmenu matches menu entries case insensitively. .TP .B \-l <lines> -activates vertical list mode. -The given number of lines will be displayed. Window height will be adjusted. -.TP -.B \-fn <font> -defines the font. -.TP -.B \-nb <color> -defines the normal background color (#RGB, #RRGGBB, and color names are supported). -.TP -.B \-nf <color> -defines the normal foreground color (#RGB, #RRGGBB, and color names are supported). +dmenu lists items vertically, with the given number of lines. .TP .B \-p <prompt> -defines a prompt to be displayed before the input area. +sets the prompt to be displayed to the left of the input area. +.TP +.B \-fn <font> +sets the font. +.TP +.B \-nb <color> +sets the background color (#RGB, #RRGGBB, and color names are supported). +.TP +.B \-nf <color> +sets the foreground color (#RGB, #RRGGBB, and color names are supported). .TP .B \-sb <color> -defines the selected background color (#RGB, #RRGGBB, and color names are supported). +sets the background color of selected items (#RGB, #RRGGBB, and color names are +supported). .TP .B \-sf <color> -defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). +sets the foreground color of selected items (#RGB, #RRGGBB, and color names are +supported). .TP .B \-v prints version information to standard output, then exits. .SH USAGE dmenu reads a list of newline-separated items from standard input and creates a -menu. When the user selects an item or enters any text and presses Return, his/her -choice is printed to standard output and dmenu terminates. +menu. When the user selects an item or enters any text and presses Return, +their choice is printed to standard output and dmenu terminates. .P -dmenu is completely controlled by the keyboard. Besides standard Unix line editing, -and item selection (Up/Down or Left/Right, PageUp/PageDown, Home/End), the following -keys are recognized: +dmenu is completely controlled by the keyboard. Besides standard Unix line +editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the +following keys are recognized: .TP .B Tab (Control\-i) Copy the selected item to the input field. .TP .B Return (Control\-j) -Confirm selection and quit (print the selected item to standard output). Returns -.B 0 -on termination. +Confirm selection. Prints the selected item to standard output and exits, +returning success. .TP .B Shift\-Return (Control\-Shift\-j) -Confirm input and quit (print the text in the input field to standard output). -Returns -.B 0 -on termination. +Confirm input. Prints the input text to standard output and exits, returning +success. .TP .B Escape (Control\-c) -Quit without selecting an item. Returns -.B 1 -on termination. +Quit without selecting an item, returning failure. .TP .B Control\-y -Pastes the X selection into the input field. This requires -.BR sselp (1). +Paste the current X selection into the input field. .SH SEE ALSO .BR dwm (1), .BR wmii (1). diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1fdf7f5..12902ac 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -6,6 +6,7 @@ #include <string.h> #include <unistd.h> #include <X11/keysym.h> +#include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef XINERAMA @@ -14,78 +15,72 @@ #include <draw.h> #include "config.h" -#define INRECT(x,y,rx,ry,rw,rh) ((rx) < (x) && (x) < (rx)+(rw) && (ry) < (y) && (y) < (ry)+(rh)) +#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define IS_UTF8_1ST_CHAR(c) (((c) & 0xc0) == 0xc0 || ((c) & 0x80) == 0x00) +#define UTF8_CODEPOINT(c) (((c) & 0xc0) != 0x80) typedef struct Item Item; struct Item { char *text; - Item *next; /* traverses all items */ - Item *left, *right; /* traverses items matching current search pattern */ + Item *next; /* traverses all items */ + Item *left, *right; /* traverses matching items */ }; -static void appenditem(Item *i, Item **list, Item **last); +static void appenditem(Item *item, Item **list, Item **last); static void calcoffsetsh(void); static void calcoffsetsv(void); static char *cistrstr(const char *s, const char *sub); -static void cleanup(void); -static void drawitem(const char *s, unsigned long col[ColLast]); static void drawmenu(void); static void drawmenuh(void); static void drawmenuv(void); static void grabkeyboard(void); +static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *e); static void match(void); +static void paste(Atom atom); static void readstdin(void); static void run(void); static void setup(void); +static void usage(void); -static char **argp = NULL; -static char *maxname = NULL; static char *prompt; static char text[4096]; -static int promptw; static int screen; -static size_t cur = 0; -static unsigned int cmdw = 0; +static size_t cursor = 0; +static unsigned int inputw = 0; static unsigned int lines = 0; -static unsigned int numlockmask; static unsigned int mw, mh; +static unsigned int promptw = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; +static Atom utf8; static Bool topbar = True; static DC dc; -static Display *dpy; -static Item *allitems = NULL; /* first of all items */ -static Item *item = NULL; /* first of pattern matching items */ -static Item *sel = NULL; -static Item *next = NULL; -static Item *prev = NULL; -static Item *curr = NULL; -static Window win, root; +static Item *allitems, *matches; +static Item *curr, *prev, *next, *sel; +static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static void (*calcoffsets)(void) = calcoffsetsh; void -appenditem(Item *i, Item **list, Item **last) { +appenditem(Item *item, Item **list, Item **last) { if(!(*last)) - *list = i; + *list = item; else - (*last)->right = i; - i->left = *last; - i->right = NULL; - *last = i; + (*last)->right = item; + item->left = *last; + item->right = NULL; + *last = item; } void calcoffsetsh(void) { unsigned int w, x; - w = promptw + cmdw + textw(&dc, "<") + textw(&dc, ">"); + w = promptw + inputw + textw(&dc, "<") + textw(&dc, ">"); for(x = w, next = curr; next; next = next->right) if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) break; @@ -128,33 +123,6 @@ cistrstr(const char *s, const char *sub) { return (char *)s; } -void -cleanup(void) { - Item *itm; - - while(allitems) { - itm = allitems->next; - free(allitems->text); - free(allitems); - allitems = itm; - } - cleanupdraw(&dc); - XDestroyWindow(dpy, win); - XUngrabKeyboard(dpy, CurrentTime); - XCloseDisplay(dpy); -} - -void -drawitem(const char *s, unsigned long col[ColLast]) { - const char *p; - unsigned int w = textnw(&dc, text, strlen(text)); - - drawbox(&dc, col); - drawtext(&dc, s, col); - for(p = fstrstr(s, text); *text && (p = fstrstr(p, text)); p++) - drawline(&dc, textnw(&dc, s, p-s) + dc.h/2 - 1, dc.h-2, w, 1, col); -} - void drawmenu(void) { dc.x = 0; @@ -172,82 +140,89 @@ drawmenu(void) { dc.x += dc.w; } dc.w = mw - dc.x; - /* print command */ - if(cmdw && item && lines == 0) - dc.w = cmdw; + /* print input area */ + if(matches && lines == 0 && textw(&dc, text) <= inputw) + dc.w = inputw; drawtext(&dc, text, normcol); - drawline(&dc, textnw(&dc, text, cur) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); + drawline(&dc, textnw(&dc, text, cursor) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); if(lines > 0) drawmenuv(); - else if(curr) + else if(curr && (dc.w == inputw || curr->next)) drawmenuh(); commitdraw(&dc, win); } void drawmenuh(void) { - Item *i; + Item *item; - dc.x += cmdw; + dc.x += inputw; dc.w = textw(&dc, "<"); - drawtext(&dc, curr->left ? "<" : NULL, normcol); + if(curr->left) + drawtext(&dc, "<", normcol); dc.x += dc.w; - for(i = curr; i != next; i = i->right) { - dc.w = MIN(textw(&dc, i->text), mw / 3); - drawitem(i->text, (sel == i) ? selcol : normcol); + for(item = curr; item != next; item = item->right) { + dc.w = MIN(textw(&dc, item->text), mw / 3); + if(item == sel) + drawbox(&dc, selcol); + drawtext(&dc, item->text, (item == sel) ? selcol : normcol); dc.x += dc.w; } dc.w = textw(&dc, ">"); dc.x = mw - dc.w; - drawtext(&dc, next ? ">" : NULL, normcol); + if(next) + drawtext(&dc, ">", normcol); } void drawmenuv(void) { - Item *i; + Item *item; XWindowAttributes wa; dc.y = topbar ? dc.h : 0; dc.w = mw - dc.x; - for(i = curr; i != next; i = i->right) { - drawitem(i->text, (sel == i) ? selcol : normcol); + for(item = curr; item != next; item = item->right) { + if(item == sel) + drawbox(&dc, selcol); + drawtext(&dc, item->text, (item == sel) ? selcol : normcol); dc.y += dc.h; } - if(!XGetWindowAttributes(dpy, win, &wa)) - eprint("cannot get window attributes"); - XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); + if(!XGetWindowAttributes(dc.dpy, win, &wa)) + eprintf("cannot get window attributes\n"); + if(wa.height != mh) + XMoveResizeWindow(dc.dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); } void grabkeyboard(void) { - unsigned int n; + int i; - for(n = 0; n < 1000; n++) { - if(!XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) + for(i = 0; i < 1000; i++) { + if(!XGrabKeyboard(dc.dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) return; usleep(1000); } - exit(EXIT_FAILURE); + eprintf("cannot grab keyboard\n"); +} + +void +insert(const char *s, ssize_t n) { + memmove(text + cursor + n, text + cursor, sizeof text - cursor - n); + if(n > 0) + memcpy(text + cursor, s, n); + cursor += n; + match(); } void keypress(XKeyEvent *e) { char buf[sizeof text]; - int num; - unsigned int i, len; + int n; + size_t len; KeySym ksym; len = strlen(text); - num = XLookupString(e, buf, sizeof buf, &ksym, NULL); - if(ksym == XK_KP_Enter) - ksym = XK_Return; - else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) - ksym = (ksym - XK_KP_0) + XK_0; - else if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) - || IsPrivateKeypadKey(ksym)) - return; - /* first check if a control mask is omitted */ + XLookupString(e, buf, sizeof buf, &ksym, NULL); if(e->state & ControlMask) { switch(tolower(ksym)) { default: @@ -277,8 +252,8 @@ keypress(XKeyEvent *e) { case XK_m: ksym = XK_Return; break; - case XK_k: - text[cur] = '\0'; + case XK_k: /* delete right */ + text[cursor] = '\0'; break; case XK_n: ksym = XK_Down; @@ -286,66 +261,44 @@ keypress(XKeyEvent *e) { case XK_p: ksym = XK_Up; break; - case XK_u: - memmove(text, text + cur, sizeof text - cur + 1); - cur = 0; - match(); + case XK_u: /* delete left */ + insert(NULL, -cursor); break; - case XK_w: - if(cur == 0) + case XK_w: /* delete word */ + if(cursor == 0) return; - i = cur; - while(i-- > 0 && text[i] == ' '); - while(i-- > 0 && text[i] != ' '); - memmove(text + i + 1, text + cur, sizeof text - cur + 1); - cur = i + 1; - match(); - break; - case XK_y: - { - FILE *fp; - char *s; - if(!(fp = fopen("sselp", "r"))) - eprint("cannot popen sselp\n"); - s = fgets(buf, sizeof buf, fp); - fclose(fp); - if(!s) - return; - } - num = strlen(buf); - if(num && buf[num-1] == '\n') - buf[--num] = '\0'; + n = 0; + while(cursor - n++ > 0 && text[cursor - n] == ' '); + while(cursor - n++ > 0 && text[cursor - n] != ' '); + insert(NULL, -(--n)); break; + case XK_y: /* paste selection */ + XConvertSelection(dc.dpy, XA_PRIMARY, utf8, None, win, CurrentTime); + /* causes SelectionNotify event */ + return; } } switch(ksym) { default: - num = MIN(num, sizeof text); - if(num && !iscntrl((int) buf[0])) { - memmove(text + cur + num, text + cur, sizeof text - cur - num); - memcpy(text + cur, buf, num); - cur += num; - match(); - } + if(!iscntrl((int)*buf)) + insert(buf, MIN(strlen(buf), sizeof text - cursor)); break; case XK_BackSpace: - if(cur == 0) + if(cursor == 0) return; - for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[cur - i]); i++); - memmove(text + cur - i, text + cur, sizeof text - cur + i); - cur -= i; - match(); + for(n = 1; cursor - n > 0 && !UTF8_CODEPOINT(text[cursor - n]); n++); + insert(NULL, -n); break; case XK_Delete: - if(cur == len) + if(cursor == len) return; - for(i = 1; cur + i < len && !IS_UTF8_1ST_CHAR(text[cur + i]); i++); - memmove(text + cur, text + cur + i, sizeof text - cur); - match(); + for(n = 1; cursor + n < len && !UTF8_CODEPOINT(text[cursor + n]); n++); + cursor += n; + insert(NULL, -n); break; case XK_End: - if(cur < len) { - cur = len; + if(cursor < len) { + cursor = len; break; } while(next) { @@ -358,19 +311,19 @@ keypress(XKeyEvent *e) { case XK_Escape: exit(EXIT_FAILURE); case XK_Home: - if(sel == item) { - cur = 0; + if(sel == matches) { + cursor = 0; break; } - sel = curr = item; + sel = curr = matches; calcoffsets(); break; case XK_Left: - if(cur > 0 && (!sel || !sel->left || lines > 0)) { - while(cur-- > 0 && !IS_UTF8_1ST_CHAR(text[cur])); + if(cursor > 0 && (!sel || !sel->left || lines > 0)) { + while(cursor-- > 0 && !UTF8_CODEPOINT(text[cursor])); break; } - if(lines > 0) + else if(lines > 0) return; case XK_Up: if(!sel || !sel->left) @@ -394,15 +347,16 @@ keypress(XKeyEvent *e) { calcoffsets(); break; case XK_Return: - fprintf(stdout, "%s", ((e->state & ShiftMask) || sel) ? sel->text : text); + case XK_KP_Enter: + fputs(((e->state & ShiftMask) || sel) ? sel->text : text, stdout); fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: - if(cur < len) { - while(cur++ < len && !IS_UTF8_1ST_CHAR(text[cur])); + if(cursor < len) { + while(cursor++ < len && !UTF8_CODEPOINT(text[cursor])); break; } - if(lines > 0) + else if(lines > 0) return; case XK_Down: if(!sel || !sel->right) @@ -417,7 +371,7 @@ keypress(XKeyEvent *e) { if(!sel) return; strncpy(text, sel->text, sizeof text); - cur = strlen(text); + cursor = strlen(text); match(); break; } @@ -427,19 +381,19 @@ keypress(XKeyEvent *e) { void match(void) { unsigned int len; - Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; + Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; len = strlen(text); - item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; - for(i = allitems; i; i = i->next) - if(!fstrncmp(text, i->text, len + 1)) - appenditem(i, &lexact, &exactend); - else if(!fstrncmp(text, i->text, len)) - appenditem(i, &lprefix, &prefixend); - else if(fstrstr(i->text, text)) - appenditem(i, &lsubstr, &substrend); + matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; + for(item = allitems; item; item = item->next) + if(!fstrncmp(text, item->text, len + 1)) + appenditem(item, &lexact, &exactend); + else if(!fstrncmp(text, item->text, len)) + appenditem(item, &lprefix, &prefixend); + else if(fstrstr(item->text, text)) + appenditem(item, &lsubstr, &substrend); if(lexact) { - item = lexact; + matches = lexact; itemend = exactend; } if(lprefix) { @@ -448,7 +402,7 @@ match(void) { lprefix->left = itemend; } else - item = lprefix; + matches = lprefix; itemend = prefixend; } if(lsubstr) { @@ -457,36 +411,48 @@ match(void) { lsubstr->left = itemend; } else - item = lsubstr; + matches = lsubstr; } - curr = prev = next = sel = item; + curr = prev = next = sel = matches; calcoffsets(); } void -readstdin(void) { - char *p, buf[sizeof text]; - unsigned int len = 0, max = 0; - Item *i, *new; +paste(Atom atom) +{ + char *p, *q; + int di; + unsigned long dl; + Atom da; - i = NULL; - while(fgets(buf, sizeof buf, stdin)) { + XGetWindowProperty(dc.dpy, win, atom, 0, sizeof text - cursor, True, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p); + insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); + XFree(p); + drawmenu(); +} + +void +readstdin(void) { + char buf[sizeof text]; + size_t len; + Item *item, *new; + + allitems = NULL; + for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) { len = strlen(buf); if(buf[len-1] == '\n') buf[--len] = '\0'; - if(!(p = strdup(buf))) - eprint("cannot strdup %u bytes\n", len); - if((max = MAX(max, len)) == len) - maxname = p; if(!(new = malloc(sizeof *new))) - eprint("cannot malloc %u bytes\n", sizeof *new); + eprintf("cannot malloc %u bytes\n", sizeof *new); + if(!(new->text = strdup(buf))) + eprintf("cannot strdup %u bytes\n", len); + inputw = MAX(inputw, textw(&dc, new->text)); new->next = new->left = new->right = NULL; - new->text = p; - if(!i) - allitems = new; + if(item) + item->next = new; else - i->next = new; - i = new; + allitems = new; } } @@ -494,8 +460,7 @@ void run(void) { XEvent ev; - XSync(dpy, False); - while(!XNextEvent(dpy, &ev)) + while(!XNextEvent(dc.dpy, &ev)) switch(ev.type) { case Expose: if(ev.xexpose.count == 0) @@ -504,62 +469,45 @@ run(void) { case KeyPress: keypress(&ev.xkey); break; + case SelectionNotify: + if(ev.xselection.property != None) + paste(ev.xselection.property); + break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); + XRaiseWindow(dc.dpy, win); break; } - exit(EXIT_FAILURE); } void setup(void) { - int i, j, x, y; -#if XINERAMA - int n; - XineramaScreenInfo *info = NULL; + int x, y; +#ifdef XINERAMA + int i, n; + XineramaScreenInfo *info; #endif - XModifierKeymap *modmap; XSetWindowAttributes wa; - /* 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); - - dc.dpy = dpy; normcol[ColBG] = getcolor(&dc, normbgcolor); normcol[ColFG] = getcolor(&dc, normfgcolor); selcol[ColBG] = getcolor(&dc, selbgcolor); selcol[ColFG] = getcolor(&dc, selfgcolor); - initfont(&dc, font); - - /* input window */ - wa.override_redirect = True; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; /* input window geometry */ mh = (dc.font.height + 2) * (lines + 1); -#if XINERAMA - if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { - i = 0; - if(n > 1) { - int di; - unsigned int dui; - Window dummy; - if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) - for(i = 0; i < n; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) - break; - } +#ifdef XINERAMA + if((info = XineramaQueryScreens(dc.dpy, &n))) { + int di; + unsigned int du; + Window dw; + + XQueryPointer(dc.dpy, root, &dw, &dw, &x, &y, &di, &di, &du); + for(i = 0; i < n; i++) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + break; x = info[i].x_org; - y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; XFree(info); } @@ -567,84 +515,86 @@ setup(void) { #endif { x = 0; - y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; - mw = DisplayWidth(dpy, screen); + y = topbar ? 0 : DisplayHeight(dc.dpy, screen) - mh; + mw = DisplayWidth(dc.dpy, screen); } - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), + /* input window */ + wa.override_redirect = True; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + win = XCreateWindow(dc.dpy, root, x, y, mw, mh, 0, + DefaultDepth(dc.dpy, screen), CopyFromParent, + DefaultVisual(dc.dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + match(); + grabkeyboard(); setupdraw(&dc, win); - if(prompt) - promptw = MIN(textw(&dc, prompt), mw / 5); - XMapRaised(dpy, win); + inputw = MIN(inputw, mw / 3); + utf8 = XInternAtom(dc.dpy, "UTF8_STRING", False); + XMapRaised(dc.dpy, win); +} + +void +usage(void) { + fputs("usage: dmenu [-b] [-i] [-l <lines>] [-p <prompt>] [-fn <font>] [-nb <color>]\n" + " [-nf <color>] [-sb <color>] [-sf <color>] [-v]\n", stderr); + exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { - unsigned int i; + int i; - /* command line args */ progname = "dmenu"; for(i = 1; i < argc; i++) - if(!strcmp(argv[i], "-i")) { - fstrncmp = strncasecmp; - fstrstr = cistrstr; + /* 1-arg flags */ + if(!strcmp(argv[i], "-v")) { + fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); + exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) topbar = False; + else if(!strcmp(argv[i], "-i")) { + fstrncmp = strncasecmp; + fstrstr = cistrstr; + } + else if(i == argc-1) + usage(); + /* 2-arg flags */ else if(!strcmp(argv[i], "-l")) { - if(++i < argc) lines = atoi(argv[i]); - if(lines > 0) + if((lines = atoi(argv[++i])) > 0) calcoffsets = calcoffsetsv; } - else if(!strcmp(argv[i], "-fn")) { - if(++i < argc) font = argv[i]; - } - else if(!strcmp(argv[i], "-nb")) { - if(++i < argc) normbgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-nf")) { - if(++i < argc) normfgcolor = argv[i]; - } else if(!strcmp(argv[i], "-p")) { - if(++i < argc) prompt = argv[i]; - } - else if(!strcmp(argv[i], "-sb")) { - if(++i < argc) selbgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } - else if(!strcmp(argv[i], "-v")) { - printf("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); - exit(EXIT_SUCCESS); - } - else { - fputs("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>]\n" - " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); - exit(EXIT_FAILURE); + prompt = argv[++i]; + promptw = MIN(textw(&dc, prompt), mw/5); } + else if(!strcmp(argv[i], "-fn")) + font = argv[++i]; + else if(!strcmp(argv[i], "-nb")) + normbgcolor = argv[++i]; + else if(!strcmp(argv[i], "-nf")) + normfgcolor = argv[++i]; + else if(!strcmp(argv[i], "-sb")) + selbgcolor = argv[++i]; + else if(!strcmp(argv[i], "-sf")) + selfgcolor = argv[++i]; + else + usage(); + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "dmenu: warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) - eprint("cannot open display\n"); - if(atexit(&cleanup) != 0) - eprint("cannot register cleanup\n"); - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - if(!(argp = malloc(sizeof *argp * (argc+2)))) - eprint("cannot malloc %u bytes\n", sizeof *argp * (argc+2)); - memcpy(argp + 2, argv + 1, sizeof *argp * argc); + fputs("dmenu: warning: no locale support\n", stderr); + if(!(dc.dpy = XOpenDisplay(NULL))) + eprintf("cannot open display\n"); + screen = DefaultScreen(dc.dpy); + root = RootWindow(dc.dpy, screen); + initfont(&dc, font); readstdin(); - grabkeyboard(); setup(); - if(maxname) - cmdw = MIN(textw(&dc, maxname), mw / 3); - match(); run(); - return 0; + + return EXIT_FAILURE; /* should not reach */ } From 71ac5902aeaaecaa4fe0da6299445779d6389dc6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 2 Aug 2010 14:22:54 +0100 Subject: [PATCH 344/590] fixed bugs, no more config.h, updated manpage, new libdraw --- dmenubar/Makefile | 24 ++--- dmenubar/README | 11 ++- dmenubar/config.def.h | 8 -- dmenubar/config.mk | 17 ++-- dmenubar/dmenu.1 | 98 +++++++++---------- dmenubar/dmenu.c | 222 ++++++++++++++++++------------------------ dmenubar/dmenu_path | 2 +- 7 files changed, 162 insertions(+), 220 deletions(-) delete mode 100644 dmenubar/config.def.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 269bc27..7b21a25 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,9 +3,6 @@ include config.mk -SRC = dmenu.c -OBJ = ${SRC:.c=.o} - all: options dmenu options: @@ -14,34 +11,28 @@ options: @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" -.c.o: +dmenu.o: dmenu.c config.mk @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk - -config.h: - @echo creating $@ from config.def.h - @cp config.def.h $@ - -dmenu: ${OBJ} +dmenu: dmenu.o @echo CC -o $@ @${CC} -o $@ $+ ${LDFLAGS} clean: @echo cleaning - @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dmenu dmenu.o dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} install: all - @echo installing executable file to ${DESTDIR}${PREFIX}/bin + @echo installing executables to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin @cp -f dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @@ -53,8 +44,9 @@ install: all @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 uninstall: - @echo removing executable file from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_path + @echo removing executables from ${DESTDIR}${PREFIX}/bin + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_path @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 diff --git a/dmenubar/README b/dmenubar/README index 9f0583a..98647bf 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,21 +1,22 @@ dmenu - dynamic menu ==================== -dmenu is a generic and efficient menu for X. +dmenu is an efficient dynamic menu for X. Requirements ------------ In order to build dmenu you need the Xlib header files. + You also need libdraw, available from http://hg.suckless.org/libdraw Installation ------------ -Edit config.mk to match your local setup (dmenu is installed into the -/usr/local namespace by default). +Edit config.mk to match your local setup (dmenu is installed into +the /usr/local namespace by default). -Afterwards enter the following command to build and install dmenu (if -necessary as root): +Afterwards enter the following command to build and install dmenu +(if necessary as root): make clean install diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h deleted file mode 100644 index eae3f08..0000000 --- a/dmenubar/config.def.h +++ /dev/null @@ -1,8 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; -static const char *normbgcolor = "#cccccc"; -static const char *normfgcolor = "#000000"; -static const char *selbgcolor = "#0066ff"; -static const char *selfgcolor = "#ffffff"; diff --git a/dmenubar/config.mk b/dmenubar/config.mk index c8bbdcd..d9f5a27 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.1.1 +VERSION = 4.2 # Customize below to fit your system @@ -7,25 +7,22 @@ VERSION = 4.1.1 PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man +# Xlib X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib # Xinerama, comment if you don't want it -XINERAMALIBS = -L${X11LIB} -lXinerama +XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -ldraw ${XINERAMALIBS} +INCS = -I${X11INC} +LIBS = -L${X11LIB} -ldraw -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} -LDFLAGS = -s ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} +CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +LDFLAGS = -s ${LIBS} # compiler and linker CC = cc diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 2d8bc20..e1f8393 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -5,81 +5,76 @@ dmenu \- dynamic menu .B dmenu .RB [ \-b ] .RB [ \-i ] -.RB [ \-l " <lines>]" -.RB [ \-p " <prompt>]" -.RB [ \-fn " <font>]" -.RB [ \-nb " <color>]" -.RB [ \-nf " <color>]" -.RB [ \-sb " <color>]" -.RB [ \-sf " <color>]" +.RB [ \-l +.IR lines ] +.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 [ \-v ] - -.B dmenu_run -.RB [ \-b ] -.RB [ \-i ] -.RB [ \-l " <lines>]" -.RB [ \-p " <prompt>]" -.RB [ \-fn " <font>]" -.RB [ \-nb " <color>]" -.RB [ \-nf " <color>]" -.RB [ \-sb " <color>]" -.RB [ \-sf " <color>]" -.RB [ \-v ] - +.P +.BR dmenu_run " ..." +.P .B dmenu_path .SH DESCRIPTION -.SS Overview .B dmenu -is a generic menu for X, originally designed for +is a dynamic menu for X, originally designed for .BR dwm (1). -It manages huge amounts (10000 and more) of user defined menu items efficiently. +It manages huge numbers of user-defined menu items efficiently. +.P +dmenu reads a list of newline-separated items from standard input and creates a +menu. When the user selects an item or enters any text and presses Return, +their choice is printed to standard output and dmenu terminates. .P .B dmenu_run -is a dmenu script which lists programs in the user's PATH and executes -the selected item. +is a dmenu script used by dwm which lists programs in the user's PATH and +executes the selected item. .P .B dmenu_path -is a script used by -.I dmenu_run -to find and cache a list of programs. -.SS Options +is a script used by dmenu_run to find and cache a list of programs. +.SH OPTIONS .TP .B \-b dmenu appears at the bottom of the screen. .TP .B \-i -dmenu matches menu entries case insensitively. +dmenu matches menu items case insensitively. .TP -.B \-l <lines> +.BI \-l " lines" dmenu lists items vertically, with the given number of lines. .TP -.B \-p <prompt> -sets the prompt to be displayed to the left of the input area. +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input area. .TP -.B \-fn <font> -sets the font. +.BI \-fn " font" +defines the font set used. .TP -.B \-nb <color> -sets the background color (#RGB, #RRGGBB, and color names are supported). +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and color names are supported. .TP -.B \-nf <color> -sets the foreground color (#RGB, #RRGGBB, and color names are supported). +.BI \-nf " color" +defines the normal foreground color. .TP -.B \-sb <color> -sets the background color of selected items (#RGB, #RRGGBB, and color names are -supported). +.BI \-sb " color" +defines the selected background color. .TP -.B \-sf <color> -sets the foreground color of selected items (#RGB, #RRGGBB, and color names are -supported). +.BI \-sf " color" +defines the selected foreground color. .TP .B \-v prints version information to standard output, then exits. .SH USAGE -dmenu reads a list of newline-separated items from standard input and creates a -menu. When the user selects an item or enters any text and presses Return, -their choice is printed to standard output and dmenu terminates. -.P dmenu is completely controlled by the keyboard. Besides standard Unix line editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the following keys are recognized: @@ -96,10 +91,9 @@ Confirm input. Prints the input text to standard output and exits, returning success. .TP .B Escape (Control\-c) -Quit without selecting an item, returning failure. +Exit without selecting an item, returning failure. .TP .B Control\-y Paste the current X selection into the input field. .SH SEE ALSO -.BR dwm (1), -.BR wmii (1). +.BR dwm (1) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 12902ac..7dfc2d3 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,11 +1,9 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> -#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <X11/keysym.h> #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -13,7 +11,6 @@ #include <X11/extensions/Xinerama.h> #endif #include <draw.h> -#include "config.h" #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -38,25 +35,27 @@ static void grabkeyboard(void); static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *e); static void match(void); -static void paste(Atom atom); +static void paste(void); static void readstdin(void); static void run(void); static void setup(void); static void usage(void); -static char *prompt; static char text[4096]; -static int screen; static size_t cursor = 0; +static const char *prompt = NULL; +static const char *normbgcolor = "#cccccc"; +static const char *normfgcolor = "#000000"; +static const char *selbgcolor = "#0066ff"; +static const char *selfgcolor = "#ffffff"; static unsigned int inputw = 0; static unsigned int lines = 0; static unsigned int mw, mh; -static unsigned int promptw = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; static Bool topbar = True; -static DC dc; +static DC *dc; static Item *allitems, *matches; static Item *curr, *prev, *next, *sel; static Window root, win; @@ -67,7 +66,7 @@ static void (*calcoffsets)(void) = calcoffsetsh; void appenditem(Item *item, Item **list, Item **last) { - if(!(*last)) + if(!*last) *list = item; else (*last)->right = item; @@ -80,12 +79,12 @@ void calcoffsetsh(void) { unsigned int w, x; - w = promptw + inputw + textw(&dc, "<") + textw(&dc, ">"); + w = (prompt ? textw(dc, prompt) : 0) + inputw + textw(dc, "<") + textw(dc, ">"); for(x = w, next = curr; next; next = next->right) - if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) + if((x += MIN(textw(dc, next->text), mw / 3)) > mw) break; for(x = w, prev = curr; prev && prev->left; prev = prev->left) - if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) + if((x += MIN(textw(dc, prev->left->text), mw / 3)) > mw) break; } @@ -96,101 +95,75 @@ calcoffsetsv(void) { next = prev = curr; for(i = 0; i < lines && next; i++) next = next->right; - mh = (dc.font.height + 2) * (i + 1); for(i = 0; i < lines && prev && prev->left; i++) prev = prev->left; } char * cistrstr(const char *s, const char *sub) { - int c, csub; - unsigned int len; + size_t len; - if(!sub) - return (char *)s; - if((c = tolower(*sub++)) != '\0') { - len = strlen(sub); - do { - do { - if((csub = *s++) == '\0') - return NULL; - } - while(tolower(csub) != c); - } - while(strncasecmp(s, sub, len) != 0); - s--; - } - return (char *)s; + for(len = strlen(sub); *s; s++) + if(!strncasecmp(s, sub, len)) + return (char *)s; + return NULL; } void drawmenu(void) { - dc.x = 0; - dc.y = 0; - dc.w = mw; - dc.h = mh; - drawbox(&dc, normcol); - dc.h = dc.font.height + 2; - dc.y = topbar ? 0 : mh - dc.h; + dc->x = 0; + dc->y = 0; + drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); + dc->h = dc->font.height + 2; + dc->y = topbar ? 0 : mh - dc->h; /* print prompt? */ if(prompt) { - dc.w = promptw; - drawbox(&dc, selcol); - drawtext(&dc, prompt, selcol); - dc.x += dc.w; + dc->w = textw(dc, prompt); + drawtext(dc, prompt, selcol); + dc->x = dc->w; } - dc.w = mw - dc.x; + dc->w = mw - dc->x; /* print input area */ - if(matches && lines == 0 && textw(&dc, text) <= inputw) - dc.w = inputw; - drawtext(&dc, text, normcol); - drawline(&dc, textnw(&dc, text, cursor) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); + if(matches && lines == 0 && textw(dc, text) <= inputw) + dc->w = inputw; + drawtext(dc, text, normcol); + drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); if(lines > 0) drawmenuv(); - else if(curr && (dc.w == inputw || curr->next)) + else if(curr && (dc->w == inputw || curr->next)) drawmenuh(); - commitdraw(&dc, win); + commitdraw(dc, win); } void drawmenuh(void) { Item *item; - dc.x += inputw; - dc.w = textw(&dc, "<"); + dc->x += inputw; + dc->w = textw(dc, "<"); if(curr->left) - drawtext(&dc, "<", normcol); - dc.x += dc.w; + drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { - dc.w = MIN(textw(&dc, item->text), mw / 3); - if(item == sel) - drawbox(&dc, selcol); - drawtext(&dc, item->text, (item == sel) ? selcol : normcol); - dc.x += dc.w; + dc->x += dc->w; + dc->w = MIN(textw(dc, item->text), mw / 3); + drawtext(dc, item->text, (item == sel) ? selcol : normcol); } - dc.w = textw(&dc, ">"); - dc.x = mw - dc.w; + dc->w = textw(dc, ">"); + dc->x = mw - dc->w; if(next) - drawtext(&dc, ">", normcol); + drawtext(dc, ">", normcol); } void drawmenuv(void) { Item *item; - XWindowAttributes wa; - dc.y = topbar ? dc.h : 0; - dc.w = mw - dc.x; + dc->y = topbar ? dc->h : 0; + dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { - if(item == sel) - drawbox(&dc, selcol); - drawtext(&dc, item->text, (item == sel) ? selcol : normcol); - dc.y += dc.h; + drawtext(dc, item->text, (item == sel) ? selcol : normcol); + dc->y += dc->h; } - if(!XGetWindowAttributes(dc.dpy, win, &wa)) - eprintf("cannot get window attributes\n"); - if(wa.height != mh) - XMoveResizeWindow(dc.dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); } void @@ -198,7 +171,7 @@ grabkeyboard(void) { int i; for(i = 0; i < 1000; i++) { - if(!XGrabKeyboard(dc.dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) + if(!XGrabKeyboard(dc->dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) return; usleep(1000); } @@ -254,6 +227,7 @@ keypress(XKeyEvent *e) { break; case XK_k: /* delete right */ text[cursor] = '\0'; + match(); break; case XK_n: ksym = XK_Down; @@ -270,10 +244,10 @@ keypress(XKeyEvent *e) { n = 0; while(cursor - n++ > 0 && text[cursor - n] == ' '); while(cursor - n++ > 0 && text[cursor - n] != ' '); - insert(NULL, -(--n)); + insert(NULL, 1-n); break; case XK_y: /* paste selection */ - XConvertSelection(dc.dpy, XA_PRIMARY, utf8, None, win, CurrentTime); + XConvertSelection(dc->dpy, XA_PRIMARY, utf8, None, win, CurrentTime); /* causes SelectionNotify event */ return; } @@ -348,7 +322,7 @@ keypress(XKeyEvent *e) { break; case XK_Return: case XK_KP_Enter: - fputs(((e->state & ShiftMask) || sel) ? sel->text : text, stdout); + fputs((sel && !(e->state & ShiftMask)) ? sel->text : text, stdout); fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: @@ -418,15 +392,14 @@ match(void) { } void -paste(Atom atom) -{ +paste(void) { char *p, *q; int di; unsigned long dl; Atom da; - XGetWindowProperty(dc.dpy, win, atom, 0, sizeof text - cursor, True, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p); + XGetWindowProperty(dc->dpy, win, utf8, 0, sizeof text - cursor, True, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p); insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); XFree(p); drawmenu(); @@ -434,24 +407,22 @@ paste(Atom atom) void readstdin(void) { - char buf[sizeof text]; - size_t len; + char buf[sizeof text], *p; Item *item, *new; allitems = NULL; for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) { - len = strlen(buf); - if(buf[len-1] == '\n') - buf[--len] = '\0'; + if((p = strchr(buf, '\n'))) + *p = '\0'; if(!(new = malloc(sizeof *new))) eprintf("cannot malloc %u bytes\n", sizeof *new); if(!(new->text = strdup(buf))) - eprintf("cannot strdup %u bytes\n", len); - inputw = MAX(inputw, textw(&dc, new->text)); + eprintf("cannot strdup %u bytes\n", strlen(buf)); + inputw = MAX(inputw, textw(dc, new->text)); new->next = new->left = new->right = NULL; if(item) item->next = new; - else + else allitems = new; } } @@ -460,7 +431,7 @@ void run(void) { XEvent ev; - while(!XNextEvent(dc.dpy, &ev)) + while(!XNextEvent(dc->dpy, &ev)) switch(ev.type) { case Expose: if(ev.xexpose.count == 0) @@ -470,39 +441,43 @@ run(void) { keypress(&ev.xkey); break; case SelectionNotify: - if(ev.xselection.property != None) - paste(ev.xselection.property); + if(ev.xselection.property == utf8) + paste(); break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dc.dpy, win); + XRaiseWindow(dc->dpy, win); break; } } void setup(void) { - int x, y; + int x, y, screen; + XSetWindowAttributes wa; #ifdef XINERAMA - int i, n; + int n; XineramaScreenInfo *info; #endif - XSetWindowAttributes wa; - normcol[ColBG] = getcolor(&dc, normbgcolor); - normcol[ColFG] = getcolor(&dc, normfgcolor); - selcol[ColBG] = getcolor(&dc, selbgcolor); - selcol[ColFG] = getcolor(&dc, selfgcolor); + screen = DefaultScreen(dc->dpy); + root = RootWindow(dc->dpy, screen); + utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); + + normcol[ColBG] = getcolor(dc, normbgcolor); + normcol[ColFG] = getcolor(dc, normfgcolor); + selcol[ColBG] = getcolor(dc, selbgcolor); + selcol[ColFG] = getcolor(dc, selfgcolor); /* input window geometry */ - mh = (dc.font.height + 2) * (lines + 1); + mh = (dc->font.height + 2) * (lines + 1); #ifdef XINERAMA - if((info = XineramaQueryScreens(dc.dpy, &n))) { - int di; + if((info = XineramaQueryScreens(dc->dpy, &n))) { + int i, di; unsigned int du; Window dw; - XQueryPointer(dc.dpy, root, &dw, &dw, &x, &y, &di, &di, &du); + XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n; i++) if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; @@ -515,31 +490,30 @@ setup(void) { #endif { x = 0; - y = topbar ? 0 : DisplayHeight(dc.dpy, screen) - mh; - mw = DisplayWidth(dc.dpy, screen); + y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; + mw = DisplayWidth(dc->dpy, screen); } /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc.dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc.dpy, screen), CopyFromParent, - DefaultVisual(dc.dpy, screen), + win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, + DefaultDepth(dc->dpy, screen), CopyFromParent, + DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - match(); grabkeyboard(); - setupdraw(&dc, win); - inputw = MIN(inputw, mw / 3); - utf8 = XInternAtom(dc.dpy, "UTF8_STRING", False); - XMapRaised(dc.dpy, win); + setcanvas(dc, win, mw, mh); + inputw = MIN(inputw, mw/3); + XMapRaised(dc->dpy, win); + match(); } void usage(void) { - fputs("usage: dmenu [-b] [-i] [-l <lines>] [-p <prompt>] [-fn <font>] [-nb <color>]\n" - " [-nf <color>] [-sb <color>] [-sf <color>] [-v]\n", stderr); + fputs("usage: dmenu [-b] [-i] [-l lines] [-p prompt] [-fn font] [-nb color]\n" + " [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); } @@ -548,8 +522,10 @@ main(int argc, char *argv[]) { int i; progname = "dmenu"; + dc = initdraw(); + for(i = 1; i < argc; i++) - /* 1-arg flags */ + /* single flags */ if(!strcmp(argv[i], "-v")) { fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); exit(EXIT_SUCCESS); @@ -562,17 +538,15 @@ main(int argc, char *argv[]) { } else if(i == argc-1) usage(); - /* 2-arg flags */ + /* double flags */ else if(!strcmp(argv[i], "-l")) { if((lines = atoi(argv[++i])) > 0) calcoffsets = calcoffsetsv; } - else if(!strcmp(argv[i], "-p")) { + else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; - promptw = MIN(textw(&dc, prompt), mw/5); - } else if(!strcmp(argv[i], "-fn")) - font = argv[++i]; + initfont(dc, argv[i++]); else if(!strcmp(argv[i], "-nb")) normbgcolor = argv[++i]; else if(!strcmp(argv[i], "-nf")) @@ -584,14 +558,6 @@ main(int argc, char *argv[]) { else usage(); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("dmenu: warning: no locale support\n", stderr); - if(!(dc.dpy = XOpenDisplay(NULL))) - eprintf("cannot open display\n"); - screen = DefaultScreen(dc.dpy); - root = RootWindow(dc.dpy, screen); - initfont(&dc, font); - readstdin(); setup(); run(); diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 7896a9e..a9ddd47 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -19,7 +19,7 @@ then do test -x "$file" && echo "$file" done - done | sort | uniq > "$CACHE".$$ && + done | sort -u > "$CACHE".$$ && mv "$CACHE".$$ "$CACHE" fi From 0315fef5416d263fcca1d68bffa877d516d3f5fc Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 2 Aug 2010 14:49:14 +0100 Subject: [PATCH 345/590] replaced promptw --- dmenubar/Makefile | 2 +- dmenubar/dmenu.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 7b21a25..1082697 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -26,7 +26,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path dmenu_run dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 7dfc2d3..608023d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -42,6 +42,7 @@ static void setup(void); static void usage(void); static char text[4096]; +static int promptw; static size_t cursor = 0; static const char *prompt = NULL; static const char *normbgcolor = "#cccccc"; @@ -79,7 +80,7 @@ void calcoffsetsh(void) { unsigned int w, x; - w = (prompt ? textw(dc, prompt) : 0) + inputw + textw(dc, "<") + textw(dc, ">"); + w = promptw + inputw + textw(dc, "<") + textw(dc, ">"); for(x = w, next = curr; next; next = next->right) if((x += MIN(textw(dc, next->text), mw / 3)) > mw) break; @@ -118,7 +119,7 @@ drawmenu(void) { dc->y = topbar ? 0 : mh - dc->h; /* print prompt? */ if(prompt) { - dc->w = textw(dc, prompt); + dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; } @@ -506,7 +507,9 @@ setup(void) { grabkeyboard(); setcanvas(dc, win, mw, mh); inputw = MIN(inputw, mw/3); + promptw = prompt ? MIN(textw(dc, prompt), mw/5) : 0; XMapRaised(dc->dpy, win); + text[0] = '\0'; match(); } From 300e237de8fb0a3a405e1432f79f792845677db8 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 2 Aug 2010 15:13:33 +0100 Subject: [PATCH 346/590] retyped promptw --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 608023d..175cbdc 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -42,7 +42,6 @@ static void setup(void); static void usage(void); static char text[4096]; -static int promptw; static size_t cursor = 0; static const char *prompt = NULL; static const char *normbgcolor = "#cccccc"; @@ -52,6 +51,7 @@ static const char *selfgcolor = "#ffffff"; static unsigned int inputw = 0; static unsigned int lines = 0; static unsigned int mw, mh; +static unsigned int promptw; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; From a1c61b49f9e8f4a68498a534bab84bb318b53346 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 3 Aug 2010 17:10:29 +0100 Subject: [PATCH 347/590] merged *{h,v} functions --- dmenubar/dmenu.c | 103 +++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 61 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 175cbdc..f19e798 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -25,12 +25,9 @@ struct Item { }; static void appenditem(Item *item, Item **list, Item **last); -static void calcoffsetsh(void); -static void calcoffsetsv(void); +static void calcoffsets(void); static char *cistrstr(const char *s, const char *sub); static void drawmenu(void); -static void drawmenuh(void); -static void drawmenuv(void); static void grabkeyboard(void); static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *e); @@ -63,7 +60,6 @@ static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; -static void (*calcoffsets)(void) = calcoffsetsh; void appenditem(Item *item, Item **list, Item **last) { @@ -77,29 +73,25 @@ appenditem(Item *item, Item **list, Item **last) { } void -calcoffsetsh(void) { - unsigned int w, x; +calcoffsets(void) +{ + unsigned int h, i, n; - w = promptw + inputw + textw(dc, "<") + textw(dc, ">"); - for(x = w, next = curr; next; next = next->right) - if((x += MIN(textw(dc, next->text), mw / 3)) > mw) + h = dc->font.height+2; + if(lines > 0) + n = lines * h; + else + n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); + + prev = next = curr; + for(i = 0; next; next = next->right) + if((i += (lines > 0) ? h : MIN(textw(dc, next->text), mw/3)) > n) break; - for(x = w, prev = curr; prev && prev->left; prev = prev->left) - if((x += MIN(textw(dc, prev->left->text), mw / 3)) > mw) + for(i = 0; prev && prev->left; prev = prev->left) + if((i += (lines > 0) ? h : MIN(textw(dc, prev->left->text), mw/3)) > n) break; } -void -calcoffsetsv(void) { - unsigned int i; - - next = prev = curr; - for(i = 0; i < lines && next; i++) - next = next->right; - for(i = 0; i < lines && prev && prev->left; i++) - prev = prev->left; -} - char * cistrstr(const char *s, const char *sub) { size_t len; @@ -112,6 +104,8 @@ cistrstr(const char *s, const char *sub) { void drawmenu(void) { + Item *item; + dc->x = 0; dc->y = 0; drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); @@ -129,44 +123,33 @@ drawmenu(void) { dc->w = inputw; drawtext(dc, text, normcol); drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); - if(lines > 0) - drawmenuv(); - else if(curr && (dc->w == inputw || curr->next)) - drawmenuh(); + + if(lines > 0) { + dc->y = topbar ? dc->h : 0; + dc->w = mw - dc->x; + for(item = curr; item != next; item = item->right) { + drawtext(dc, item->text, (item == sel) ? selcol : normcol); + dc->y += dc->h; + } + } + else if(curr && (dc->w == inputw || curr->next)) { + dc->x += inputw; + dc->w = textw(dc, "<"); + if(prev) + drawtext(dc, "<", normcol); + for(item = curr; item != next; item = item->right) { + dc->x += dc->w; + dc->w = MIN(textw(dc, item->text), mw/3); + drawtext(dc, item->text, (item == sel) ? selcol : normcol); + } + dc->w = textw(dc, ">"); + dc->x = mw - dc->w; + if(next) + drawtext(dc, ">", normcol); + } commitdraw(dc, win); } -void -drawmenuh(void) { - Item *item; - - dc->x += inputw; - dc->w = textw(dc, "<"); - if(curr->left) - drawtext(dc, "<", normcol); - for(item = curr; item != next; item = item->right) { - dc->x += dc->w; - dc->w = MIN(textw(dc, item->text), mw / 3); - drawtext(dc, item->text, (item == sel) ? selcol : normcol); - } - dc->w = textw(dc, ">"); - dc->x = mw - dc->w; - if(next) - drawtext(dc, ">", normcol); -} - -void -drawmenuv(void) { - Item *item; - - dc->y = topbar ? dc->h : 0; - dc->w = mw - dc->x; - for(item = curr; item != next; item = item->right) { - drawtext(dc, item->text, (item == sel) ? selcol : normcol); - dc->y += dc->h; - } -} - void grabkeyboard(void) { int i; @@ -494,7 +477,6 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } - /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; @@ -543,8 +525,7 @@ main(int argc, char *argv[]) { usage(); /* double flags */ else if(!strcmp(argv[i], "-l")) { - if((lines = atoi(argv[++i])) > 0) - calcoffsets = calcoffsetsv; + lines = atoi(argv[++i]); } else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; From af5b9b37d1a27fbf319abb58950f50ce2f0a5c6c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 3 Aug 2010 17:18:24 +0100 Subject: [PATCH 348/590] cleaned up --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f19e798..227648c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -109,6 +109,7 @@ drawmenu(void) { dc->x = 0; dc->y = 0; drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); + dc->h = dc->font.height + 2; dc->y = topbar ? 0 : mh - dc->h; /* print prompt? */ @@ -524,9 +525,8 @@ main(int argc, char *argv[]) { else if(i == argc-1) usage(); /* double flags */ - else if(!strcmp(argv[i], "-l")) { + else if(!strcmp(argv[i], "-l")) lines = atoi(argv[++i]); - } else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) From 3aa17dee49d06865da8f4094a1dada1227714c2b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 3 Aug 2010 17:29:53 +0100 Subject: [PATCH 349/590] typo fix --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 227648c..b82ff59 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -136,7 +136,7 @@ drawmenu(void) { else if(curr && (dc->w == inputw || curr->next)) { dc->x += inputw; dc->w = textw(dc, "<"); - if(prev) + if(curr->left) drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; From 656ccd2f910322c4e2fc09924addddb618882b98 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 3 Aug 2010 18:19:59 +0100 Subject: [PATCH 350/590] another typo fix (thanks, Gene Auyeung) --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b82ff59..c367645 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -530,7 +530,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) - initfont(dc, argv[i++]); + initfont(dc, argv[++i]); else if(!strcmp(argv[i], "-nb")) normbgcolor = argv[++i]; else if(!strcmp(argv[i], "-nf")) From b91588489704aa10b8880b0aa175e994419e9035 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 5 Aug 2010 15:41:56 +0100 Subject: [PATCH 351/590] new libdraw, typo fixes --- dmenubar/dmenu.1 | 2 +- dmenubar/dmenu.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index e1f8393..a1ec695 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -52,7 +52,7 @@ dmenu matches menu items case insensitively. dmenu lists items vertically, with the given number of lines. .TP .BI \-p " prompt" -defines the prompt to be displayed to the left of the input area. +defines the prompt to be displayed to the left of the input field. .TP .BI \-fn " font" defines the font set used. diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c367645..f5d2bd1 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -119,7 +119,7 @@ drawmenu(void) { dc->x = dc->w; } dc->w = mw - dc->x; - /* print input area */ + /* print input field */ if(matches && lines == 0 && textw(dc, text) <= inputw) dc->w = inputw; drawtext(dc, text, normcol); @@ -339,7 +339,7 @@ keypress(XKeyEvent *e) { void match(void) { - unsigned int len; + size_t len; Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; len = strlen(text); @@ -454,7 +454,7 @@ setup(void) { selcol[ColBG] = getcolor(dc, selbgcolor); selcol[ColFG] = getcolor(dc, selfgcolor); - /* input window geometry */ + /* menu geometry */ mh = (dc->font.height + 2) * (lines + 1); #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { @@ -478,7 +478,7 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } - /* input window */ + /* menu window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; @@ -488,7 +488,7 @@ setup(void) { CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); grabkeyboard(); - setcanvas(dc, win, mw, mh); + setcanvas(dc, mw, mh); inputw = MIN(inputw, mw/3); promptw = prompt ? MIN(textw(dc, prompt), mw/5) : 0; XMapRaised(dc->dpy, win); From 7e6df3fa20349a87229fbbaa785f409ce00b7710 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 6 Aug 2010 14:16:08 +0100 Subject: [PATCH 352/590] added ^D, removed ^M --- dmenubar/dmenu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f5d2bd1..a1d0ed2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -194,6 +194,9 @@ keypress(XKeyEvent *e) { case XK_c: ksym = XK_Escape; break; + case XK_d: + ksym = XK_Delete; + break; case XK_e: ksym = XK_End; break; @@ -207,7 +210,6 @@ keypress(XKeyEvent *e) { ksym = XK_Tab; break; case XK_j: - case XK_m: ksym = XK_Return; break; case XK_k: /* delete right */ From 334364a6340e943276f6f2d4fe8e89d60044fd3f Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 9 Aug 2010 11:54:46 +0100 Subject: [PATCH 353/590] cursor fix + style --- dmenubar/dmenu.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a1d0ed2..fa37f49 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -30,7 +30,7 @@ static char *cistrstr(const char *s, const char *sub); static void drawmenu(void); static void grabkeyboard(void); static void insert(const char *s, ssize_t n); -static void keypress(XKeyEvent *e); +static void keypress(XKeyEvent *ev); static void match(void); static void paste(void); static void readstdin(void); @@ -73,8 +73,7 @@ appenditem(Item *item, Item **list, Item **last) { } void -calcoffsets(void) -{ +calcoffsets(void) { unsigned int h, i, n; h = dc->font.height+2; @@ -104,26 +103,24 @@ cistrstr(const char *s, const char *sub) { void drawmenu(void) { + int curpos; Item *item; dc->x = 0; dc->y = 0; drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); - dc->h = dc->font.height + 2; dc->y = topbar ? 0 : mh - dc->h; - /* print prompt? */ + if(prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; } - dc->w = mw - dc->x; - /* print input field */ - if(matches && lines == 0 && textw(dc, text) <= inputw) - dc->w = inputw; + dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; drawtext(dc, text, normcol); - drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); + if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) + drawrect(dc, curpos, 2, 1, dc->h - 4, FG(dc, normcol)); if(lines > 0) { dc->y = topbar ? dc->h : 0; @@ -133,7 +130,7 @@ drawmenu(void) { dc->y += dc->h; } } - else if(curr && (dc->w == inputw || curr->next)) { + else if(matches) { dc->x += inputw; dc->w = textw(dc, "<"); if(curr->left) @@ -173,15 +170,15 @@ insert(const char *s, ssize_t n) { } void -keypress(XKeyEvent *e) { - char buf[sizeof text]; +keypress(XKeyEvent *ev) { + char buf[32]; int n; size_t len; KeySym ksym; len = strlen(text); - XLookupString(e, buf, sizeof buf, &ksym, NULL); - if(e->state & ControlMask) { + XLookupString(ev, buf, sizeof buf, &ksym, NULL); + if(ev->state & ControlMask) { switch(tolower(ksym)) { default: return; @@ -235,7 +232,6 @@ keypress(XKeyEvent *e) { break; case XK_y: /* paste selection */ XConvertSelection(dc->dpy, XA_PRIMARY, utf8, None, win, CurrentTime); - /* causes SelectionNotify event */ return; } } @@ -289,8 +285,7 @@ keypress(XKeyEvent *e) { case XK_Up: if(!sel || !sel->left) return; - sel = sel->left; - if(sel->right == curr) { + if((sel = sel->left)->right == curr) { curr = prev; calcoffsets(); } @@ -309,7 +304,7 @@ keypress(XKeyEvent *e) { break; case XK_Return: case XK_KP_Enter: - fputs((sel && !(e->state & ShiftMask)) ? sel->text : text, stdout); + fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: @@ -322,8 +317,7 @@ keypress(XKeyEvent *e) { case XK_Down: if(!sel || !sel->right) return; - sel = sel->right; - if(sel == next) { + if((sel = sel->right) == next) { curr = next; calcoffsets(); } @@ -404,7 +398,7 @@ readstdin(void) { if(!(new = malloc(sizeof *new))) eprintf("cannot malloc %u bytes\n", sizeof *new); if(!(new->text = strdup(buf))) - eprintf("cannot strdup %u bytes\n", strlen(buf)); + eprintf("cannot strdup %u bytes\n", strlen(buf)+1); inputw = MAX(inputw, textw(dc, new->text)); new->next = new->left = new->right = NULL; if(item) @@ -485,9 +479,9 @@ setup(void) { wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, - DefaultVisual(dc->dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + DefaultDepth(dc->dpy, screen), CopyFromParent, + DefaultVisual(dc->dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); grabkeyboard(); setcanvas(dc, mw, mh); From 4fed1cd136bd1da0839f1240caa8923358d2a657 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 10 Aug 2010 13:38:49 +0100 Subject: [PATCH 354/590] simplifications --- dmenubar/config.mk | 1 - dmenubar/dmenu.c | 32 ++++++++++++++------------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index d9f5a27..03212d5 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -7,7 +7,6 @@ VERSION = 4.2 PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man -# Xlib X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fa37f49..384def6 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -4,8 +4,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <X11/Xatom.h> #include <X11/Xlib.h> +#include <X11/Xatom.h> #include <X11/Xutil.h> #ifdef XINERAMA #include <X11/extensions/Xinerama.h> @@ -13,6 +13,7 @@ #include <draw.h> #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) +#define LINEH (dc->font.height + 2) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define UTF8_CODEPOINT(c) (((c) & 0xc0) != 0x80) @@ -38,7 +39,7 @@ static void run(void); static void setup(void); static void usage(void); -static char text[4096]; +static char text[BUFSIZ]; static size_t cursor = 0; static const char *prompt = NULL; static const char *normbgcolor = "#cccccc"; @@ -74,21 +75,18 @@ appenditem(Item *item, Item **list, Item **last) { void calcoffsets(void) { - unsigned int h, i, n; + unsigned int i, n; - h = dc->font.height+2; if(lines > 0) - n = lines * h; + n = lines * LINEH; else n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); - prev = next = curr; - for(i = 0; next; next = next->right) - if((i += (lines > 0) ? h : MIN(textw(dc, next->text), mw/3)) > n) - break; - for(i = 0; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? h : MIN(textw(dc, prev->left->text), mw/3)) > n) - break; + for(i = 0, next = curr; i <= n && next; next = next->right) + i += (lines > 0) ? LINEH : MIN(textw(dc, next->text), mw/3); + + for(i = 0, prev = curr; i <= n && prev && prev->left; prev = prev->left) + i += (lines > 0) ? LINEH : MIN(textw(dc, prev->left->text), mw/3); } char * @@ -108,9 +106,8 @@ drawmenu(void) { dc->x = 0; dc->y = 0; + dc->h = LINEH; drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); - dc->h = dc->font.height + 2; - dc->y = topbar ? 0 : mh - dc->h; if(prompt) { dc->w = promptw; @@ -123,11 +120,10 @@ drawmenu(void) { drawrect(dc, curpos, 2, 1, dc->h - 4, FG(dc, normcol)); if(lines > 0) { - dc->y = topbar ? dc->h : 0; dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { - drawtext(dc, item->text, (item == sel) ? selcol : normcol); dc->y += dc->h; + drawtext(dc, item->text, (item == sel) ? selcol : normcol); } } else if(matches) { @@ -237,7 +233,7 @@ keypress(XKeyEvent *ev) { } switch(ksym) { default: - if(!iscntrl((int)*buf)) + if(isprint(*buf)) insert(buf, MIN(strlen(buf), sizeof text - cursor)); break; case XK_BackSpace: @@ -451,7 +447,7 @@ setup(void) { selcol[ColFG] = getcolor(dc, selfgcolor); /* menu geometry */ - mh = (dc->font.height + 2) * (lines + 1); + mh = (lines + 1) * LINEH; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { int i, di; From 05d3effadb8c415af356126681375f02fd5e6790 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 10 Aug 2010 14:14:37 +0100 Subject: [PATCH 355/590] reverted calcoffsets --- dmenubar/dmenu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 384def6..8384bc2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -82,11 +82,12 @@ calcoffsets(void) { else n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); - for(i = 0, next = curr; i <= n && next; next = next->right) - i += (lines > 0) ? LINEH : MIN(textw(dc, next->text), mw/3); - - for(i = 0, prev = curr; i <= n && prev && prev->left; prev = prev->left) - i += (lines > 0) ? LINEH : MIN(textw(dc, prev->left->text), mw/3); + for(i = 0, next = curr; next; next = next->right) + if((i += (lines > 0) ? LINEH : MIN(textw(dc, next->text), mw/3)) > n) + break; + for(i = 0, prev = curr; prev && prev->left; prev = prev->left) + if((i += (lines > 0) ? LINEH : MIN(textw(dc, prev->left->text), mw/3)) > n) + break; } char * From 9b2ec1cb4d0e4dc1474216e0be33f3c7dc40b130 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 10 Aug 2010 18:09:02 +0100 Subject: [PATCH 356/590] more efficient initfont --- dmenubar/dmenu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8384bc2..a8bdcb9 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -41,6 +41,7 @@ static void usage(void); static char text[BUFSIZ]; static size_t cursor = 0; +static const char *font = NULL; static const char *prompt = NULL; static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; @@ -501,8 +502,6 @@ main(int argc, char *argv[]) { int i; progname = "dmenu"; - dc = initdraw(); - for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { @@ -523,7 +522,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) - initfont(dc, argv[++i]); + font = argv[++i]; else if(!strcmp(argv[i], "-nb")) normbgcolor = argv[++i]; else if(!strcmp(argv[i], "-nf")) @@ -535,6 +534,8 @@ main(int argc, char *argv[]) { else usage(); + dc = initdraw(); + initfont(dc, font); readstdin(); setup(); run(); From ec1bc69b42ca9452ed60619c92a237f08cdcde9c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 11 Aug 2010 14:24:25 +0100 Subject: [PATCH 357/590] new libdraw, replaced cistrstr with fstrstr, simpler readstdin --- dmenubar/dmenu.c | 74 ++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a8bdcb9..42022e9 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -13,7 +13,6 @@ #include <draw.h> #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) -#define LINEH (dc->font.height + 2) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define UTF8_CODEPOINT(c) (((c) & 0xc0) != 0x80) @@ -27,8 +26,8 @@ struct Item { static void appenditem(Item *item, Item **list, Item **last); static void calcoffsets(void); -static char *cistrstr(const char *s, const char *sub); static void drawmenu(void); +static char *fstrstr(const char *s, const char *sub); static void grabkeyboard(void); static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *ev); @@ -47,21 +46,21 @@ static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; +static unsigned int bh, mw, mh; static unsigned int inputw = 0; static unsigned int lines = 0; -static unsigned int mw, mh; static unsigned int promptw; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; static Bool topbar = True; static DC *dc; -static Item *allitems, *matches; -static Item *curr, *prev, *next, *sel; +static Item *items = NULL; +static Item *matches, *sel; +static Item *prev, *curr, *next; static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -static char *(*fstrstr)(const char *, const char *) = strstr; void appenditem(Item *item, Item **list, Item **last) { @@ -79,28 +78,18 @@ calcoffsets(void) { unsigned int i, n; if(lines > 0) - n = lines * LINEH; + n = lines * bh; else n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? LINEH : MIN(textw(dc, next->text), mw/3)) > n) + if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), mw/3)) > n) break; for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? LINEH : MIN(textw(dc, prev->left->text), mw/3)) > n) + if((i += (lines > 0) ? bh : MIN(textw(dc, prev->left->text), mw/3)) > n) break; } -char * -cistrstr(const char *s, const char *sub) { - size_t len; - - for(len = strlen(sub); *s; s++) - if(!strncasecmp(s, sub, len)) - return (char *)s; - return NULL; -} - void drawmenu(void) { int curpos; @@ -108,8 +97,8 @@ drawmenu(void) { dc->x = 0; dc->y = 0; - dc->h = LINEH; - drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); + dc->h = bh; + drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); if(prompt) { dc->w = promptw; @@ -119,7 +108,7 @@ drawmenu(void) { dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; drawtext(dc, text, normcol); if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) - drawrect(dc, curpos, 2, 1, dc->h - 4, FG(dc, normcol)); + drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); if(lines > 0) { dc->w = mw - dc->x; @@ -143,7 +132,17 @@ drawmenu(void) { if(next) drawtext(dc, ">", normcol); } - commitdraw(dc, win); + commitdraw(dc, win, mw, mh); +} + +char * +fstrstr(const char *s, const char *sub) { + size_t len; + + for(len = strlen(sub); *s; s++) + if(!fstrncmp(s, sub, len)) + return (char *)s; + return NULL; } void @@ -338,13 +337,14 @@ match(void) { len = strlen(text); matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; - for(item = allitems; item; item = item->next) + for(item = items; item; item = item->next) if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); else if(!fstrncmp(text, item->text, len)) appenditem(item, &lprefix, &prefixend); else if(fstrstr(item->text, text)) appenditem(item, &lsubstr, &substrend); + if(lexact) { matches = lexact; itemend = exactend; @@ -387,22 +387,17 @@ paste(void) { void readstdin(void) { char buf[sizeof text], *p; - Item *item, *new; + Item *item, **end; - allitems = NULL; - for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) { + for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { if((p = strchr(buf, '\n'))) *p = '\0'; - if(!(new = malloc(sizeof *new))) - eprintf("cannot malloc %u bytes\n", sizeof *new); - if(!(new->text = strdup(buf))) + if(!(item = malloc(sizeof *item))) + eprintf("cannot malloc %u bytes\n", sizeof *item); + if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); - inputw = MAX(inputw, textw(dc, new->text)); - new->next = new->left = new->right = NULL; - if(item) - item->next = new; - else - allitems = new; + inputw = MAX(inputw, textw(dc, item->text)); + item->next = item->left = item->right = NULL; } } @@ -449,7 +444,8 @@ setup(void) { selcol[ColFG] = getcolor(dc, selfgcolor); /* menu geometry */ - mh = (lines + 1) * LINEH; + bh = dc->font.height + 2; + mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { int i, di; @@ -510,10 +506,8 @@ main(int argc, char *argv[]) { } else if(!strcmp(argv[i], "-b")) topbar = False; - else if(!strcmp(argv[i], "-i")) { + else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; - fstrstr = cistrstr; - } else if(i == argc-1) usage(); /* double flags */ From ee095612ea69d4084e09a827dcb45f800193d4c4 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 11 Aug 2010 15:02:03 +0100 Subject: [PATCH 358/590] fixed paste --- dmenubar/dmenu.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 42022e9..f16249c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -32,7 +32,7 @@ static void grabkeyboard(void); static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *ev); static void match(void); -static void paste(void); +static void paste(Atom atom); static void readstdin(void); static void run(void); static void setup(void); @@ -52,7 +52,7 @@ static unsigned int lines = 0; static unsigned int promptw; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; -static Atom utf8; +static Atom clip, utf8; static Bool topbar = True; static DC *dc; static Item *items = NULL; @@ -228,7 +228,7 @@ keypress(XKeyEvent *ev) { insert(NULL, 1-n); break; case XK_y: /* paste selection */ - XConvertSelection(dc->dpy, XA_PRIMARY, utf8, None, win, CurrentTime); + XConvertSelection(dc->dpy, XA_PRIMARY, utf8, clip, win, CurrentTime); return; } } @@ -371,13 +371,13 @@ match(void) { } void -paste(void) { +paste(Atom atom) { char *p, *q; int di; unsigned long dl; Atom da; - XGetWindowProperty(dc->dpy, win, utf8, 0, sizeof text - cursor, True, + XGetWindowProperty(dc->dpy, win, atom, 0, sizeof text - cursor, False, utf8, &da, &di, &dl, &dl, (unsigned char **)&p); insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); XFree(p); @@ -415,8 +415,8 @@ run(void) { keypress(&ev.xkey); break; case SelectionNotify: - if(ev.xselection.property == utf8) - paste(); + if(ev.xselection.property != None) + paste(ev.xselection.property); break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) @@ -437,6 +437,7 @@ setup(void) { screen = DefaultScreen(dc->dpy); root = RootWindow(dc->dpy, screen); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); + clip = XInternAtom(dc->dpy, "_DMENU_STRING", False); normcol[ColBG] = getcolor(dc, normbgcolor); normcol[ColFG] = getcolor(dc, normfgcolor); From a102ca9daeb0da25c149db3cebd959ac72568816 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 12 Aug 2010 15:35:51 +0100 Subject: [PATCH 359/590] fixed insert segfault, added nextrune --- dmenubar/dmenu.c | 72 +++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f16249c..9b6a382 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -15,7 +15,6 @@ #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define UTF8_CODEPOINT(c) (((c) & 0xc0) != 0x80) typedef struct Item Item; struct Item { @@ -32,7 +31,8 @@ static void grabkeyboard(void); static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *ev); static void match(void); -static void paste(Atom atom); +static size_t nextrune(int incr); +static void paste(void); static void readstdin(void); static void run(void); static void setup(void); @@ -52,7 +52,7 @@ static unsigned int lines = 0; static unsigned int promptw; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; -static Atom clip, utf8; +static Atom utf8; static Bool topbar = True; static DC *dc; static Item *items = NULL; @@ -159,7 +159,9 @@ grabkeyboard(void) { void insert(const char *s, ssize_t n) { - memmove(text + cursor + n, text + cursor, sizeof text - cursor - n); + if(strlen(text) + n > sizeof text - 1) + return; + memmove(text + cursor + n, text + cursor, sizeof text - cursor - MAX(n, 0)); if(n > 0) memcpy(text + cursor, s, n); cursor += n; @@ -169,7 +171,6 @@ insert(const char *s, ssize_t n) { void keypress(XKeyEvent *ev) { char buf[32]; - int n; size_t len; KeySym ksym; @@ -217,38 +218,31 @@ keypress(XKeyEvent *ev) { ksym = XK_Up; break; case XK_u: /* delete left */ - insert(NULL, -cursor); + insert(NULL, 0 - cursor); break; case XK_w: /* delete word */ - if(cursor == 0) - return; - n = 0; - while(cursor - n++ > 0 && text[cursor - n] == ' '); - while(cursor - n++ > 0 && text[cursor - n] != ' '); - insert(NULL, 1-n); + while(cursor > 0 && text[nextrune(-1)] == ' ') + insert(NULL, nextrune(-1) - cursor); + while(cursor > 0 && text[nextrune(-1)] != ' ') + insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ - XConvertSelection(dc->dpy, XA_PRIMARY, utf8, clip, win, CurrentTime); + XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); return; } } switch(ksym) { default: if(isprint(*buf)) - insert(buf, MIN(strlen(buf), sizeof text - cursor)); - break; - case XK_BackSpace: - if(cursor == 0) - return; - for(n = 1; cursor - n > 0 && !UTF8_CODEPOINT(text[cursor - n]); n++); - insert(NULL, -n); + insert(buf, strlen(buf)); break; case XK_Delete: if(cursor == len) return; - for(n = 1; cursor + n < len && !UTF8_CODEPOINT(text[cursor + n]); n++); - cursor += n; - insert(NULL, -n); + cursor = nextrune(+1); + case XK_BackSpace: + if(cursor > 0) + insert(NULL, nextrune(-1) - cursor); break; case XK_End: if(cursor < len) { @@ -274,15 +268,13 @@ keypress(XKeyEvent *ev) { break; case XK_Left: if(cursor > 0 && (!sel || !sel->left || lines > 0)) { - while(cursor-- > 0 && !UTF8_CODEPOINT(text[cursor])); + cursor = nextrune(-1); break; } else if(lines > 0) return; case XK_Up: - if(!sel || !sel->left) - return; - if((sel = sel->left)->right == curr) { + if(sel && sel->left && (sel = sel->left)->right == curr) { curr = prev; calcoffsets(); } @@ -306,15 +298,13 @@ keypress(XKeyEvent *ev) { exit(EXIT_SUCCESS); case XK_Right: if(cursor < len) { - while(cursor++ < len && !UTF8_CODEPOINT(text[cursor])); + cursor = nextrune(+1); break; } else if(lines > 0) return; case XK_Down: - if(!sel || !sel->right) - return; - if((sel = sel->right) == next) { + if(sel && sel->right && (sel = sel->right) == next) { curr = next; calcoffsets(); } @@ -370,14 +360,23 @@ match(void) { calcoffsets(); } +size_t +nextrune(int incr) { + size_t n, len; + + len = strlen(text); + for(n = cursor + incr; n >= 0 && n < len && (text[n] & 0xc0) == 0x80; n += incr); + return n; +} + void -paste(Atom atom) { +paste(void) { char *p, *q; int di; unsigned long dl; Atom da; - XGetWindowProperty(dc->dpy, win, atom, 0, sizeof text - cursor, False, + XGetWindowProperty(dc->dpy, win, utf8, 0, (sizeof text / 4) + 1, False, utf8, &da, &di, &dl, &dl, (unsigned char **)&p); insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); XFree(p); @@ -396,8 +395,8 @@ readstdin(void) { eprintf("cannot malloc %u bytes\n", sizeof *item); if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); - inputw = MAX(inputw, textw(dc, item->text)); item->next = item->left = item->right = NULL; + inputw = MAX(inputw, textw(dc, item->text)); } } @@ -415,8 +414,8 @@ run(void) { keypress(&ev.xkey); break; case SelectionNotify: - if(ev.xselection.property != None) - paste(ev.xselection.property); + if(ev.xselection.property == utf8) + paste(); break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) @@ -437,7 +436,6 @@ setup(void) { screen = DefaultScreen(dc->dpy); root = RootWindow(dc->dpy, screen); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - clip = XInternAtom(dc->dpy, "_DMENU_STRING", False); normcol[ColBG] = getcolor(dc, normbgcolor); normcol[ColFG] = getcolor(dc, normfgcolor); From bad83c9903c0d0fe38618fd8a38ae4c87275b092 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 Aug 2010 17:33:34 +0100 Subject: [PATCH 360/590] signed ints, ignore negative -l value --- dmenubar/dmenu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9b6a382..a5a4cdd 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -39,6 +39,10 @@ static void setup(void); static void usage(void); static char text[BUFSIZ]; +static int bh, mw, mh; +static int inputw = 0; +static int promptw; +static int lines = 0; static size_t cursor = 0; static const char *font = NULL; static const char *prompt = NULL; @@ -46,10 +50,6 @@ static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; -static unsigned int bh, mw, mh; -static unsigned int inputw = 0; -static unsigned int lines = 0; -static unsigned int promptw; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; @@ -444,6 +444,7 @@ setup(void) { /* menu geometry */ bh = dc->font.height + 2; + lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { From 5c7cb0ea42cb29b14c9879d61435a5dade859036 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 Aug 2010 17:35:23 +0100 Subject: [PATCH 361/590] resorted globals --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a5a4cdd..f743be8 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -41,8 +41,8 @@ static void usage(void); static char text[BUFSIZ]; static int bh, mw, mh; static int inputw = 0; -static int promptw; static int lines = 0; +static int promptw; static size_t cursor = 0; static const char *font = NULL; static const char *prompt = NULL; From 72022e7271bdc7f26b9bc8067ac90a653fc05666 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 19 Aug 2010 16:17:57 +0100 Subject: [PATCH 362/590] new libdraw --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f743be8..f6e6931 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -132,7 +132,7 @@ drawmenu(void) { if(next) drawtext(dc, ">", normcol); } - commitdraw(dc, win, mw, mh); + mapdraw(dc, win, mw, mh); } char * @@ -478,7 +478,7 @@ setup(void) { CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); grabkeyboard(); - setcanvas(dc, mw, mh); + resizedraw(dc, mw, mh); inputw = MIN(inputw, mw/3); promptw = prompt ? MIN(textw(dc, prompt), mw/5) : 0; XMapRaised(dc->dpy, win); From 760739bb2d721e96258c2dc9a4100d222c8f70a5 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 19 Aug 2010 16:43:39 +0100 Subject: [PATCH 363/590] new libdraw --- dmenubar/dmenu.c | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f6e6931..22fbfed 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -80,13 +80,13 @@ calcoffsets(void) { if(lines > 0) n = lines * bh; else - n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); + n = mw - (promptw + inputw + dc_textw(dc, "<") + dc_textw(dc, ">")); for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), mw/3)) > n) + if((i += (lines > 0) ? bh : MIN(dc_textw(dc, next->text), mw/3)) > n) break; for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? bh : MIN(textw(dc, prev->left->text), mw/3)) > n) + if((i += (lines > 0) ? bh : MIN(dc_textw(dc, prev->left->text), mw/3)) > n) break; } @@ -98,41 +98,41 @@ drawmenu(void) { dc->x = 0; dc->y = 0; dc->h = bh; - drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); + dc_drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); if(prompt) { dc->w = promptw; - drawtext(dc, prompt, selcol); + dc_drawtext(dc, prompt, selcol); dc->x = dc->w; } dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) - drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); + dc_drawtext(dc, text, normcol); + if((curpos = dc_textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) + dc_drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); if(lines > 0) { dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; - drawtext(dc, item->text, (item == sel) ? selcol : normcol); + dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); } } else if(matches) { dc->x += inputw; - dc->w = textw(dc, "<"); + dc->w = dc_textw(dc, "<"); if(curr->left) - drawtext(dc, "<", normcol); + dc_drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; - dc->w = MIN(textw(dc, item->text), mw/3); - drawtext(dc, item->text, (item == sel) ? selcol : normcol); + dc->w = MIN(dc_textw(dc, item->text), mw/3); + dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); } - dc->w = textw(dc, ">"); + dc->w = dc_textw(dc, ">"); dc->x = mw - dc->w; if(next) - drawtext(dc, ">", normcol); + dc_drawtext(dc, ">", normcol); } - mapdraw(dc, win, mw, mh); + dc_map(dc, win, mw, mh); } char * @@ -396,7 +396,7 @@ readstdin(void) { if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); item->next = item->left = item->right = NULL; - inputw = MAX(inputw, textw(dc, item->text)); + inputw = MAX(inputw, dc_textw(dc, item->text)); } } @@ -437,10 +437,10 @@ setup(void) { root = RootWindow(dc->dpy, screen); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - normcol[ColBG] = getcolor(dc, normbgcolor); - normcol[ColFG] = getcolor(dc, normfgcolor); - selcol[ColBG] = getcolor(dc, selbgcolor); - selcol[ColFG] = getcolor(dc, selfgcolor); + normcol[ColBG] = dc_color(dc, normbgcolor); + normcol[ColFG] = dc_color(dc, normfgcolor); + selcol[ColBG] = dc_color(dc, selbgcolor); + selcol[ColFG] = dc_color(dc, selfgcolor); /* menu geometry */ bh = dc->font.height + 2; @@ -478,9 +478,9 @@ setup(void) { CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); grabkeyboard(); - resizedraw(dc, mw, mh); + dc_resize(dc, mw, mh); inputw = MIN(inputw, mw/3); - promptw = prompt ? MIN(textw(dc, prompt), mw/5) : 0; + promptw = prompt ? MIN(dc_textw(dc, prompt), mw/5) : 0; XMapRaised(dc->dpy, win); text[0] = '\0'; match(); @@ -528,8 +528,8 @@ main(int argc, char *argv[]) { else usage(); - dc = initdraw(); - initfont(dc, font); + dc = dc_init(); + dc_font(dc, font); readstdin(); setup(); run(); From 2f8054552a41eb4088fe874d6cad72b8e9859bfe Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 20 Aug 2010 13:50:44 +0100 Subject: [PATCH 364/590] rebound paste, removed useless max widths --- dmenubar/dmenu.1 | 4 ++-- dmenubar/dmenu.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index a1ec695..45f9cf1 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -55,7 +55,7 @@ dmenu lists items vertically, with the given number of lines. defines the prompt to be displayed to the left of the input field. .TP .BI \-fn " font" -defines the font set used. +defines the font or font set used. .TP .BI \-nb " color" defines the normal background color. @@ -93,7 +93,7 @@ success. .B Escape (Control\-c) Exit without selecting an item, returning failure. .TP -.B Control\-y +.B Shift\-Insert Paste the current X selection into the input field. .SH SEE ALSO .BR dwm (1) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 22fbfed..2596b56 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -83,10 +83,10 @@ calcoffsets(void) { n = mw - (promptw + inputw + dc_textw(dc, "<") + dc_textw(dc, ">")); for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? bh : MIN(dc_textw(dc, next->text), mw/3)) > n) + if((i += (lines > 0) ? bh : dc_textw(dc, next->text)) > n) break; for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? bh : MIN(dc_textw(dc, prev->left->text), mw/3)) > n) + if((i += (lines > 0) ? bh : dc_textw(dc, prev->left->text)) > n) break; } @@ -124,7 +124,7 @@ drawmenu(void) { dc_drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; - dc->w = MIN(dc_textw(dc, item->text), mw/3); + dc->w = dc_textw(dc, item->text); dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); } dc->w = dc_textw(dc, ">"); @@ -226,9 +226,6 @@ keypress(XKeyEvent *ev) { while(cursor > 0 && text[nextrune(-1)] != ' ') insert(NULL, nextrune(-1) - cursor); break; - case XK_y: /* paste selection */ - XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); - return; } } switch(ksym) { @@ -266,6 +263,10 @@ keypress(XKeyEvent *ev) { sel = curr = matches; calcoffsets(); break; + case XK_Insert: /* paste selection */ + if(ev->state & ShiftMask) + XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); + return; case XK_Left: if(cursor > 0 && (!sel || !sel->left || lines > 0)) { cursor = nextrune(-1); @@ -480,7 +481,7 @@ setup(void) { grabkeyboard(); dc_resize(dc, mw, mh); inputw = MIN(inputw, mw/3); - promptw = prompt ? MIN(dc_textw(dc, prompt), mw/5) : 0; + promptw = prompt ? dc_textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); text[0] = '\0'; match(); From 15a373ec56374c9f0017017f54172c07a85100c5 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 20 Aug 2010 19:42:58 +0100 Subject: [PATCH 365/590] fixed width bug --- dmenubar/dmenu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2596b56..5ae611f 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -83,10 +83,10 @@ calcoffsets(void) { n = mw - (promptw + inputw + dc_textw(dc, "<") + dc_textw(dc, ">")); for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? bh : dc_textw(dc, next->text)) > n) + if((i += (lines > 0) ? bh : MIN(dc_textw(dc, next->text), n)) > n) break; for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? bh : dc_textw(dc, prev->left->text)) > n) + if((i += (lines > 0) ? bh : MIN(dc_textw(dc, prev->left->text), n)) > n) break; } @@ -124,7 +124,7 @@ drawmenu(void) { dc_drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; - dc->w = dc_textw(dc, item->text); + dc->w = MIN(dc_textw(dc, item->text), mw - dc->x); dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); } dc->w = dc_textw(dc, ">"); From f8d31b453c840449ca6fa0adc4f8cc4c16103a7d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 20 Aug 2010 19:57:13 +0100 Subject: [PATCH 366/590] arrow offset --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5ae611f..9dd0363 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -124,7 +124,7 @@ drawmenu(void) { dc_drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; - dc->w = MIN(dc_textw(dc, item->text), mw - dc->x); + dc->w = MIN(dc_textw(dc, item->text), mw - dc->x - dc_textw(dc, ">")); dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); } dc->w = dc_textw(dc, ">"); From c2507f82aebcddaa1c3e877cdda421f9f4b50c9b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 11 Sep 2010 13:37:01 +0100 Subject: [PATCH 367/590] update to libdc, fixed utf8 bug --- dmenubar/README | 2 +- dmenubar/dmenu.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/README b/dmenubar/README index 98647bf..840e677 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -7,7 +7,7 @@ Requirements ------------ In order to build dmenu you need the Xlib header files. -You also need libdraw, available from http://hg.suckless.org/libdraw +You also need libdc, available from http://hg.suckless.org/libdraw Installation diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9dd0363..908f548 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -10,7 +10,7 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif -#include <draw.h> +#include <dc.h> #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -230,7 +230,7 @@ keypress(XKeyEvent *ev) { } switch(ksym) { default: - if(isprint(*buf)) + if(!iscntrl(*buf)) insert(buf, strlen(buf)); break; case XK_Delete: From 3ce8f8de3fec402ae8b2a3a3c4d4fc58aa069b50 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 11 Sep 2010 19:48:10 +0100 Subject: [PATCH 368/590] simplification --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 908f548..0d01cbc 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -230,7 +230,7 @@ keypress(XKeyEvent *ev) { } switch(ksym) { default: - if(!iscntrl(*buf)) + if(*buf) insert(buf, strlen(buf)); break; case XK_Delete: From 42b9a031686fac8bc380d4107c3fa7bbc9af490c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 13 Sep 2010 14:22:02 +0100 Subject: [PATCH 369/590] fixed linking bug (thanks Jacob Nixdorf) & iscntrl corner case --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 03212d5..6e1b95f 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -16,7 +16,7 @@ XINERAMAFLAGS = -DXINERAMA # includes and libs INCS = -I${X11INC} -LIBS = -L${X11LIB} -ldraw -lX11 ${XINERAMALIBS} +LIBS = -L${X11LIB} -ldc -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0d01cbc..908f548 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -230,7 +230,7 @@ keypress(XKeyEvent *ev) { } switch(ksym) { default: - if(*buf) + if(!iscntrl(*buf)) insert(buf, strlen(buf)); break; case XK_Delete: From 50045e52cecbc461c3cf915cabc215275fa6175d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 8 Oct 2010 23:24:22 +0100 Subject: [PATCH 370/590] dmenu_path.c (shell is a bottleneck) --- dmenubar/Makefile | 15 +++---- dmenubar/dmenu_path | 26 ----------- dmenubar/dmenu_path.c | 101 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 34 deletions(-) delete mode 100755 dmenubar/dmenu_path create mode 100644 dmenubar/dmenu_path.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 1082697..c183779 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -all: options dmenu +all: options dmenu dmenu_path options: @echo dmenu build options: @@ -11,22 +11,21 @@ options: @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" -dmenu.o: dmenu.c config.mk - @echo CC $< - @${CC} -c ${CFLAGS} $< +dmenu: dmenu.c config.mk +dmenu_path: dmenu_path.c -dmenu: dmenu.o +dmenu dmenu_path: @echo CC -o $@ - @${CC} -o $@ $+ ${LDFLAGS} + @${CC} -o $@ $< ${CFLAGS} ${LDFLAGS} clean: @echo cleaning - @rm -f dmenu dmenu.o dmenu-${VERSION}.tar.gz + @rm -f dmenu dmenu_path dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path dmenu_run dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path.c dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path deleted file mode 100755 index a9ddd47..0000000 --- a/dmenubar/dmenu_path +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -CACHE=$HOME/.dmenu_cache -IFS=: - -uptodate() { - test -f "$CACHE" && - for dir in $PATH - do - test ! $dir -nt "$CACHE" || return 1 - done -} - -if ! uptodate -then - for dir in $PATH - do - cd "$dir" && - for file in * - do - test -x "$file" && echo "$file" - done - done | sort -u > "$CACHE".$$ && - mv "$CACHE".$$ "$CACHE" -fi - -cat "$CACHE" diff --git a/dmenubar/dmenu_path.c b/dmenubar/dmenu_path.c new file mode 100644 index 0000000..1575f1d --- /dev/null +++ b/dmenubar/dmenu_path.c @@ -0,0 +1,101 @@ +/* See LICENSE file for copyright and license details. */ +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +#define CACHE ".dmenu_cache" + +static int qstrcmp(const void *a, const void *b); +static void die(const char *s); +static void scan(void); +static int uptodate(void); + +static char **items = NULL; +static const char *Home, *Path; +static size_t count = 0; + +int +main(void) { + if(!(Home = getenv("HOME"))) + die("no $HOME"); + if(!(Path = getenv("PATH"))) + die("no $PATH"); + if(chdir(Home) < 0) + die("chdir failed"); + if(uptodate()) { + execlp("cat", "cat", CACHE, NULL); + die("exec failed"); + } + scan(); + return EXIT_SUCCESS; +} + +void +die(const char *s) { + fprintf(stderr, "dmenu_path: %s\n", s); + exit(EXIT_FAILURE); +} + +int +qstrcmp(const void *a, const void *b) { + return strcmp(*(const char **)a, *(const char **)b); +} + +void +scan(void) { + char buf[PATH_MAX]; + char *dir, *path; + size_t i; + struct dirent *ent; + DIR *dp; + FILE *cache; + + if(!(path = strdup(Path))) + die("strdup failed"); + for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) { + if(!(dp = opendir(dir))) + continue; + while((ent = readdir(dp))) { + snprintf(buf, sizeof buf, "%s/%s", dir, ent->d_name); + if(ent->d_name[0] == '.' || access(buf, X_OK) < 0) + continue; + if(!(items = realloc(items, ++count * sizeof *items))) + die("malloc failed"); + if(!(items[count-1] = strdup(ent->d_name))) + die("strdup failed"); + } + closedir(dp); + } + qsort(items, count, sizeof *items, qstrcmp); + if(!(cache = fopen(CACHE, "w"))) + die("open failed"); + for(i = 0; i < count; i++) { + if(i > 0 && !strcmp(items[i], items[i-1])) + continue; + fprintf(cache, "%s\n", items[i]); + fprintf(stdout, "%s\n", items[i]); + } + fclose(cache); + free(path); +} + +int +uptodate(void) { + char *dir, *path; + time_t mtime; + struct stat st; + + if(stat(CACHE, &st) < 0) + return 0; + mtime = st.st_mtime; + if(!(path = strdup(Path))) + die("strdup failed"); + for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) + if(!stat(dir, &st) && st.st_mtime > mtime) + return 0; + free(path); + return 1; +} From 08800be724df9ecde72591201dc4f19b973a6658 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 8 Oct 2010 23:36:45 +0100 Subject: [PATCH 371/590] cleaned up --- dmenubar/dmenu_path.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/dmenubar/dmenu_path.c b/dmenubar/dmenu_path.c index 1575f1d..15d0da0 100644 --- a/dmenubar/dmenu_path.c +++ b/dmenubar/dmenu_path.c @@ -8,22 +8,21 @@ #define CACHE ".dmenu_cache" -static int qstrcmp(const void *a, const void *b); static void die(const char *s); +static int qstrcmp(const void *a, const void *b); static void scan(void); static int uptodate(void); static char **items = NULL; -static const char *Home, *Path; -static size_t count = 0; +static const char *home, *path; int main(void) { - if(!(Home = getenv("HOME"))) + if(!(home = getenv("HOME"))) die("no $HOME"); - if(!(Path = getenv("PATH"))) + if(!(path = getenv("PATH"))) die("no $PATH"); - if(chdir(Home) < 0) + if(chdir(home) < 0) die("chdir failed"); if(uptodate()) { execlp("cat", "cat", CACHE, NULL); @@ -47,15 +46,16 @@ qstrcmp(const void *a, const void *b) { void scan(void) { char buf[PATH_MAX]; - char *dir, *path; - size_t i; + char *dir, *p; + size_t i, count; struct dirent *ent; DIR *dp; FILE *cache; - if(!(path = strdup(Path))) + count = 0; + if(!(p = strdup(path))) die("strdup failed"); - for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) { + for(dir = strtok(p, ":"); dir; dir = strtok(NULL, ":")) { if(!(dp = opendir(dir))) continue; while((ent = readdir(dp))) { @@ -79,23 +79,23 @@ scan(void) { fprintf(stdout, "%s\n", items[i]); } fclose(cache); - free(path); + free(p); } int uptodate(void) { - char *dir, *path; + char *dir, *p; time_t mtime; struct stat st; if(stat(CACHE, &st) < 0) return 0; mtime = st.st_mtime; - if(!(path = strdup(Path))) + if(!(p = strdup(path))) die("strdup failed"); - for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) + for(dir = strtok(p, ":"); dir; dir = strtok(NULL, ":")) if(!stat(dir, &st) && st.st_mtime > mtime) return 0; - free(path); + free(p); return 1; } From 36c09b5909281a75469378312d2c83ef2d89b454 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 8 Oct 2010 23:40:11 +0100 Subject: [PATCH 372/590] updated manpage --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 45f9cf1..cff2214 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -39,7 +39,7 @@ is a dmenu script used by dwm which lists programs in the user's PATH and executes the selected item. .P .B dmenu_path -is a script used by dmenu_run to find and cache a list of programs. +is a program used by dmenu_run to find and cache a list of executables. .SH OPTIONS .TP .B \-b From 847a519409a5f8f681de5640fe962aeadfb10b17 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 2 Nov 2010 12:15:15 +0000 Subject: [PATCH 373/590] -m flag to fix dwm selmon bug --- dmenubar/dmenu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 908f548..f0be02a 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -42,6 +42,7 @@ static char text[BUFSIZ]; static int bh, mw, mh; static int inputw = 0; static int lines = 0; +static int monitor = -1; static int promptw; static size_t cursor = 0; static const char *font = NULL; @@ -455,7 +456,8 @@ setup(void) { XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + if((monitor == info[i].screen_number) + || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) break; x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); @@ -514,6 +516,8 @@ main(int argc, char *argv[]) { /* double flags */ else if(!strcmp(argv[i], "-l")) lines = atoi(argv[++i]); + else if(!strcmp(argv[i], "-m")) + monitor = atoi(argv[++i]); else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) From 513f66cb318214f75f6d4836e6d93c61808ae5d8 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 11 Nov 2010 23:56:39 +0000 Subject: [PATCH 374/590] removed libdc dependence --- dmenubar/Makefile | 14 ++-- dmenubar/README | 2 - dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 52 ++++++------ dmenubar/draw.c | 196 +++++++++++++++++++++++++++++++++++++++++++++ dmenubar/draw.h | 37 +++++++++ 6 files changed, 269 insertions(+), 34 deletions(-) create mode 100644 dmenubar/draw.c create mode 100644 dmenubar/draw.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index c183779..6775a10 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -all: options dmenu dmenu_path +all: options dmenu dmenu_path config.mk options: @echo dmenu build options: @@ -11,16 +11,20 @@ options: @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" -dmenu: dmenu.c config.mk -dmenu_path: dmenu_path.c +dmenu: dmenu.o draw.o +dmenu_path: dmenu_path.o + +.c.o: + @echo CC -c $< + @${CC} -c $< ${CFLAGS} dmenu dmenu_path: @echo CC -o $@ - @${CC} -o $@ $< ${CFLAGS} ${LDFLAGS} + @${CC} -o $@ $+ ${LDFLAGS} clean: @echo cleaning - @rm -f dmenu dmenu_path dmenu-${VERSION}.tar.gz + @rm -f dmenu dmenu.o draw.o dmenu_path dmenu_path.o dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball diff --git a/dmenubar/README b/dmenubar/README index 840e677..a8fcdfe 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -7,8 +7,6 @@ Requirements ------------ In order to build dmenu you need the Xlib header files. -You also need libdc, available from http://hg.suckless.org/libdraw - Installation ------------ diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 6e1b95f..4264514 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -16,7 +16,7 @@ XINERAMAFLAGS = -DXINERAMA # includes and libs INCS = -I${X11INC} -LIBS = -L${X11LIB} -ldc -lX11 ${XINERAMALIBS} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f0be02a..9d6088b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -10,7 +10,7 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif -#include <dc.h> +#include "draw.h" #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -81,13 +81,13 @@ calcoffsets(void) { if(lines > 0) n = lines * bh; else - n = mw - (promptw + inputw + dc_textw(dc, "<") + dc_textw(dc, ">")); + n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? bh : MIN(dc_textw(dc, next->text), n)) > n) + if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), n)) > n) break; for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? bh : MIN(dc_textw(dc, prev->left->text), n)) > n) + if((i += (lines > 0) ? bh : MIN(textw(dc, prev->left->text), n)) > n) break; } @@ -99,41 +99,41 @@ drawmenu(void) { dc->x = 0; dc->y = 0; dc->h = bh; - dc_drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); + drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); if(prompt) { dc->w = promptw; - dc_drawtext(dc, prompt, selcol); + drawtext(dc, prompt, selcol); dc->x = dc->w; } dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - dc_drawtext(dc, text, normcol); - if((curpos = dc_textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) - dc_drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); + drawtext(dc, text, normcol); + if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) + drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); if(lines > 0) { dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; - dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); + drawtext(dc, item->text, (item == sel) ? selcol : normcol); } } else if(matches) { dc->x += inputw; - dc->w = dc_textw(dc, "<"); + dc->w = textw(dc, "<"); if(curr->left) - dc_drawtext(dc, "<", normcol); + drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; - dc->w = MIN(dc_textw(dc, item->text), mw - dc->x - dc_textw(dc, ">")); - dc_drawtext(dc, item->text, (item == sel) ? selcol : normcol); + dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); + drawtext(dc, item->text, (item == sel) ? selcol : normcol); } - dc->w = dc_textw(dc, ">"); + dc->w = textw(dc, ">"); dc->x = mw - dc->w; if(next) - dc_drawtext(dc, ">", normcol); + drawtext(dc, ">", normcol); } - dc_map(dc, win, mw, mh); + mapdc(dc, win, mw, mh); } char * @@ -398,7 +398,7 @@ readstdin(void) { if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); item->next = item->left = item->right = NULL; - inputw = MAX(inputw, dc_textw(dc, item->text)); + inputw = MAX(inputw, textw(dc, item->text)); } } @@ -439,10 +439,10 @@ setup(void) { root = RootWindow(dc->dpy, screen); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - normcol[ColBG] = dc_color(dc, normbgcolor); - normcol[ColFG] = dc_color(dc, normfgcolor); - selcol[ColBG] = dc_color(dc, selbgcolor); - selcol[ColFG] = dc_color(dc, selfgcolor); + normcol[ColBG] = getcolor(dc, normbgcolor); + normcol[ColFG] = getcolor(dc, normfgcolor); + selcol[ColBG] = getcolor(dc, selbgcolor); + selcol[ColFG] = getcolor(dc, selfgcolor); /* menu geometry */ bh = dc->font.height + 2; @@ -481,9 +481,9 @@ setup(void) { CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); grabkeyboard(); - dc_resize(dc, mw, mh); + resizedc(dc, mw, mh); inputw = MIN(inputw, mw/3); - promptw = prompt ? dc_textw(dc, prompt) : 0; + promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); text[0] = '\0'; match(); @@ -533,8 +533,8 @@ main(int argc, char *argv[]) { else usage(); - dc = dc_init(); - dc_font(dc, font); + dc = initdc(); + initfont(dc, font); readstdin(); setup(); run(); diff --git a/dmenubar/draw.c b/dmenubar/draw.c new file mode 100644 index 0000000..85c1279 --- /dev/null +++ b/dmenubar/draw.c @@ -0,0 +1,196 @@ +/* See LICENSE file for copyright and license details. */ +#include <locale.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xlib.h> +#include "draw.h" + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) +#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) +#define DEFFONT "fixed" + +static Bool loadfont(DC *dc, const char *fontstr); + +void +drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { + XRectangle r = { dc->x + x, dc->y + y, w, h }; + + if(!fill) { + r.width -= 1; + r.height -= 1; + } + XSetForeground(dc->dpy, dc->gc, color); + (fill ? XFillRectangles : XDrawRectangles)(dc->dpy, dc->canvas, dc->gc, &r, 1); +} + + +void +drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { + char buf[256]; + size_t n, mn; + + /* shorten text if necessary */ + n = strlen(text); + for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) > dc->w - dc->font.height/2; mn--) + if(mn == 0) + return; + memcpy(buf, text, mn); + if(mn < n) + for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); + + drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); + drawtextn(dc, buf, mn, col); +} + +void +drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { + int x, y; + + x = dc->x + dc->font.height/2; + y = dc->y + dc->font.ascent+1; + + XSetForeground(dc->dpy, dc->gc, FG(dc, col)); + if(dc->font.set) + XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); + else { + XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); + XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); + } +} + +void +eprintf(const char *fmt, ...) { + va_list ap; + + fprintf(stderr, "%s: ", progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +void +freedc(DC *dc) { + if(dc->font.set) + XFreeFontSet(dc->dpy, dc->font.set); + if(dc->font.xfont) + XFreeFont(dc->dpy, dc->font.xfont); + if(dc->canvas) + XFreePixmap(dc->dpy, dc->canvas); + XFreeGC(dc->dpy, dc->gc); + XCloseDisplay(dc->dpy); + free(dc); +} + +unsigned long +getcolor(DC *dc, const char *colstr) { + Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); + XColor color; + + if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) + eprintf("cannot allocate color '%s'\n", colstr); + return color.pixel; +} + +DC * +initdc(void) { + DC *dc; + + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + weprintf("no locale support\n"); + if(!(dc = malloc(sizeof *dc))) + eprintf("cannot malloc %u bytes\n", sizeof *dc); + if(!(dc->dpy = XOpenDisplay(NULL))) + eprintf("cannot open display\n"); + + dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL); + XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); + dc->font.xfont = NULL; + dc->font.set = NULL; + dc->canvas = None; + return dc; +} + +void +initfont(DC *dc, const char *fontstr) { + if(!loadfont(dc, fontstr ? fontstr : DEFFONT)) { + if(fontstr != NULL) + weprintf("cannot load font '%s'\n", fontstr); + if(fontstr == NULL || !loadfont(dc, DEFFONT)) + eprintf("cannot load font '%s'\n", DEFFONT); + } + dc->font.height = dc->font.ascent + dc->font.descent; +} + +Bool +loadfont(DC *dc, const char *fontstr) { + char *def, **missing; + int i, n; + + if(!*fontstr) + return False; + if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { + char **names; + XFontStruct **xfonts; + + n = XFontsOfFontSet(dc->font.set, &xfonts, &names); + for(i = dc->font.ascent = dc->font.descent = 0; i < n; i++) { + dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); + dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); + } + } + else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { + dc->font.ascent = dc->font.xfont->ascent; + dc->font.descent = dc->font.xfont->descent; + } + if(missing) + XFreeStringList(missing); + return (dc->font.set || dc->font.xfont); +} + +void +mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { + XCopyArea(dc->dpy, dc->canvas, win, dc->gc, 0, 0, w, h, 0, 0); +} + +void +resizedc(DC *dc, unsigned int w, unsigned int h) { + if(dc->canvas) + XFreePixmap(dc->dpy, dc->canvas); + dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, + DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); + dc->x = dc->y = 0; + dc->w = w; + dc->h = h; + dc->invert = False; +} + +int +textnw(DC *dc, const char *text, size_t len) { + if(dc->font.set) { + XRectangle r; + + XmbTextExtents(dc->font.set, text, len, NULL, &r); + return r.width; + } + return XTextWidth(dc->font.xfont, text, len); +} + +int +textw(DC *dc, const char *text) { + return textnw(dc, text, strlen(text)) + dc->font.height; +} + +void +weprintf(const char *fmt, ...) { + va_list ap; + + fprintf(stderr, "%s: warning: ", progname); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} diff --git a/dmenubar/draw.h b/dmenubar/draw.h new file mode 100644 index 0000000..ac3943f --- /dev/null +++ b/dmenubar/draw.h @@ -0,0 +1,37 @@ +/* See LICENSE file for copyright and license details. */ + +#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) +#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) + +enum { ColBG, ColFG, ColBorder, ColLast }; + +typedef struct { + int x, y, w, h; + Bool invert; + Display *dpy; + GC gc; + Pixmap canvas; + struct { + int ascent; + int descent; + int height; + XFontSet set; + XFontStruct *xfont; + } font; +} DC; /* draw context */ + +unsigned long getcolor(DC *dc, const char *colstr); +void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); +void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); +void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); +void initfont(DC *dc, const char *fontstr); +void freedc(DC *dc); +DC *initdc(void); +void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); +void resizedc(DC *dc, unsigned int w, unsigned int h); +int textnw(DC *dc, const char *text, size_t len); +int textw(DC *dc, const char *text); +void eprintf(const char *fmt, ...); +void weprintf(const char *fmt, ...); + +const char *progname; From 0d9f4fe91a7c27ff965f0cb3eba7027565f24e78 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 12 Nov 2010 00:00:32 +0000 Subject: [PATCH 375/590] rebound paste to ^Y --- dmenubar/dmenu.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9d6088b..5c77560 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -227,6 +227,9 @@ keypress(XKeyEvent *ev) { while(cursor > 0 && text[nextrune(-1)] != ' ') insert(NULL, nextrune(-1) - cursor); break; + case XK_y: /* paste selection */ + XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); + return; } } switch(ksym) { @@ -264,10 +267,6 @@ keypress(XKeyEvent *ev) { sel = curr = matches; calcoffsets(); break; - case XK_Insert: /* paste selection */ - if(ev->state & ShiftMask) - XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); - return; case XK_Left: if(cursor > 0 && (!sel || !sel->left || lines > 0)) { cursor = nextrune(-1); From 6f84c13efd5b3ed19e60b30d9be0e1583805af83 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 12 Nov 2010 00:01:54 +0000 Subject: [PATCH 376/590] updated manpage --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index cff2214..08d103f 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -93,7 +93,7 @@ success. .B Escape (Control\-c) Exit without selecting an item, returning failure. .TP -.B Shift\-Insert +.B Control\-y Paste the current X selection into the input field. .SH SEE ALSO .BR dwm (1) From 2e5c731005d90503ec65bc113dc94b28afdaac06 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 12 Nov 2010 00:30:03 +0000 Subject: [PATCH 377/590] fixed config.mk dep --- dmenubar/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 6775a10..8abfd0c 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -all: options dmenu dmenu_path config.mk +all: options dmenu dmenu_path options: @echo dmenu build options: @@ -14,7 +14,7 @@ options: dmenu: dmenu.o draw.o dmenu_path: dmenu_path.o -.c.o: +.c.o: config.mk @echo CC -c $< @${CC} -c $< ${CFLAGS} From 060dccdae40e0770746d5c5b2c376131cb773ca2 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 17 Nov 2010 04:33:34 +0000 Subject: [PATCH 378/590] moved main, updated args --- dmenubar/dmenu.1 | 5 +++ dmenubar/dmenu.c | 96 ++++++++++++++++++++++++------------------------ 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 08d103f..d2a93d1 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -7,6 +7,8 @@ dmenu \- dynamic menu .RB [ \-i ] .RB [ \-l .IR lines ] +.RB [ \-m +.IR monitor ] .RB [ \-p .IR prompt ] .RB [ \-fn @@ -51,6 +53,9 @@ dmenu matches menu items case insensitively. .BI \-l " lines" dmenu lists items vertically, with the given number of lines. .TP +.BI \-m " monitor" +dmenu appears on the given Xinerama screen. +.TP .BI \-p " prompt" defines the prompt to be displayed to the left of the input field. .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5c77560..a24dfe3 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -63,6 +63,52 @@ static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +int +main(int argc, char *argv[]) { + int i; + + progname = "dmenu"; + for(i = 1; i < argc; i++) + /* single flags */ + if(!strcmp(argv[i], "-v")) { + fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); + exit(EXIT_SUCCESS); + } + else if(!strcmp(argv[i], "-b")) + topbar = False; + else if(!strcmp(argv[i], "-i")) + fstrncmp = strncasecmp; + else if(i == argc-1) + usage(); + /* double flags */ + else if(!strcmp(argv[i], "-l")) + lines = atoi(argv[++i]); + else if(!strcmp(argv[i], "-m")) + monitor = atoi(argv[++i]); + else if(!strcmp(argv[i], "-p")) + prompt = argv[++i]; + else if(!strcmp(argv[i], "-fn")) + font = argv[++i]; + else if(!strcmp(argv[i], "-nb")) + normbgcolor = argv[++i]; + else if(!strcmp(argv[i], "-nf")) + normfgcolor = argv[++i]; + else if(!strcmp(argv[i], "-sb")) + selbgcolor = argv[++i]; + else if(!strcmp(argv[i], "-sf")) + selfgcolor = argv[++i]; + else + usage(); + + dc = initdc(); + initfont(dc, font); + readstdin(); + setup(); + run(); + + return EXIT_FAILURE; /* should not reach */ +} + void appenditem(Item *item, Item **list, Item **last) { if(!*last) @@ -490,53 +536,7 @@ setup(void) { void usage(void) { - fputs("usage: dmenu [-b] [-i] [-l lines] [-p prompt] [-fn font] [-nb color]\n" - " [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); } - -int -main(int argc, char *argv[]) { - int i; - - progname = "dmenu"; - for(i = 1; i < argc; i++) - /* single flags */ - if(!strcmp(argv[i], "-v")) { - fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); - exit(EXIT_SUCCESS); - } - else if(!strcmp(argv[i], "-b")) - topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; - else if(i == argc-1) - usage(); - /* double flags */ - else if(!strcmp(argv[i], "-l")) - lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-m")) - monitor = atoi(argv[++i]); - else if(!strcmp(argv[i], "-p")) - prompt = argv[++i]; - else if(!strcmp(argv[i], "-fn")) - font = argv[++i]; - else if(!strcmp(argv[i], "-nb")) - normbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-nf")) - normfgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sb")) - selbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sf")) - selfgcolor = argv[++i]; - else - usage(); - - dc = initdc(); - initfont(dc, font); - readstdin(); - setup(); - run(); - - return EXIT_FAILURE; /* should not reach */ -} From f195c95f9a83042b8212defe1ad35292ea43c3d9 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 17 Nov 2010 04:51:30 +0000 Subject: [PATCH 379/590] removed unnecessary defines --- dmenubar/draw.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 85c1279..28c658c 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -9,8 +9,6 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) -#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) #define DEFFONT "fixed" static Bool loadfont(DC *dc, const char *fontstr); From ddff9a2fd1140c6836962ef446d1941086e752e0 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Fri, 19 Nov 2010 11:51:01 +0000 Subject: [PATCH 380/590] Added tag 4.2 for changeset 379813a051f0 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index cb351fb..9256a31 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -42,3 +42,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 78f9f72cc9c6bdb022ff8908486b61ef5e242aad 4.0 844587572673cf6326c3f61737264a46b728fc0a 4.1 72749a826cab0baa805620e44a22e54486c97a4e 4.1.1 +379813a051f03a1b20bdbfdc2d2d1d2d794ace48 4.2 From 8459313aa209a9cab7ec20427897168b0bdf7fc7 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 20 Nov 2010 09:25:04 +0000 Subject: [PATCH 381/590] fixed dist target bug --- dmenubar/Makefile | 2 +- dmenubar/config.mk | 2 +- dmenubar/dmenu_path.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 8abfd0c..c3934e7 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -29,7 +29,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path.c dmenu_run dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c draw.c draw.h dmenu_path.c dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 4264514..ebaab81 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.2 +VERSION = 4.2.1 # Customize below to fit your system diff --git a/dmenubar/dmenu_path.c b/dmenubar/dmenu_path.c index 15d0da0..8df2667 100644 --- a/dmenubar/dmenu_path.c +++ b/dmenubar/dmenu_path.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <dirent.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> From 6c221731486f1b94d87f2b6a59c5ba57ad1e8792 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Sat, 20 Nov 2010 09:25:08 +0000 Subject: [PATCH 382/590] Added tag 4.2.1 for changeset abb6579a324f --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 9256a31..1462feb 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -43,3 +43,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 844587572673cf6326c3f61737264a46b728fc0a 4.1 72749a826cab0baa805620e44a22e54486c97a4e 4.1.1 379813a051f03a1b20bdbfdc2d2d1d2d794ace48 4.2 +abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1 From b0f9f87bb188b8faeecba5ecb2a1d601853277b9 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 1 Dec 2010 20:23:16 +0000 Subject: [PATCH 383/590] posix makefile --- dmenubar/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index c3934e7..c0e7856 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -12,15 +12,16 @@ options: @echo "CC = ${CC}" dmenu: dmenu.o draw.o -dmenu_path: dmenu_path.o + @echo CC -o $@ + @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} .c.o: config.mk @echo CC -c $< @${CC} -c $< ${CFLAGS} -dmenu dmenu_path: +.o: @echo CC -o $@ - @${CC} -o $@ $+ ${LDFLAGS} + @${CC} -o $@ $< ${LDFLAGS} clean: @echo cleaning From 0833a2839078cd4e74cfab096aea0e7285d5f18c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 1 Dec 2010 20:25:10 +0000 Subject: [PATCH 384/590] gmake spews --- dmenubar/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index c0e7856..dd744e1 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -15,14 +15,14 @@ dmenu: dmenu.o draw.o @echo CC -o $@ @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} +dmenu_path: dmenu_path.o + @echo CC -o $@ + @${CC} -o $@ dmenu_path.o ${LDFLAGS} + .c.o: config.mk @echo CC -c $< @${CC} -c $< ${CFLAGS} -.o: - @echo CC -o $@ - @${CC} -o $@ $< ${LDFLAGS} - clean: @echo cleaning @rm -f dmenu dmenu.o draw.o dmenu_path dmenu_path.o dmenu-${VERSION}.tar.gz From 3d7699de37ca8e46fe182281ae90d33d2cc2fe22 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 7 Jan 2011 18:54:40 +0000 Subject: [PATCH 385/590] cache option in config.mk --- dmenubar/config.mk | 6 ++++-- dmenubar/dmenu_path.c | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index ebaab81..08ea1bf 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,7 +1,9 @@ # dmenu version VERSION = 4.2.1 -# Customize below to fit your system +# dmenu_path cache (absolute or relative to $HOME) +CACHE = .dmenu_cache + # paths PREFIX = /usr/local @@ -19,7 +21,7 @@ INCS = -I${X11INC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" -DCACHE=\"${CACHE}\" ${XINERAMAFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff --git a/dmenubar/dmenu_path.c b/dmenubar/dmenu_path.c index 8df2667..407477a 100644 --- a/dmenubar/dmenu_path.c +++ b/dmenubar/dmenu_path.c @@ -7,8 +7,6 @@ #include <unistd.h> #include <sys/stat.h> -#define CACHE ".dmenu_cache" - static void die(const char *s); static int qstrcmp(const void *a, const void *b); static void scan(void); @@ -26,7 +24,7 @@ main(void) { if(chdir(home) < 0) die("chdir failed"); if(uptodate()) { - execlp("cat", "cat", CACHE, NULL); + execl("/bin/cat", "cat", CACHE, NULL); die("exec failed"); } scan(); From ac641cc331af9cbbc36fc3effa90b968afc641cc Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 7 Jan 2011 18:55:00 +0000 Subject: [PATCH 386/590] update license --- dmenubar/LICENSE | 4 ++-- dmenubar/dmenu.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index f44738e..25eb571 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License -© 2010 Connor Lane Smith <cls@lubutu.com> -© 2006-2010 Anselm R Garbe <anselm@garbe.us> +© 2010-2011 Connor Lane Smith <cls@lubutu.com> +© 2006-2011 Anselm R Garbe <anselm@garbe.us> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a24dfe3..6ed025d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -71,7 +71,7 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { - fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); + fputs("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details\n", stdout); exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) From 5d02e6020bc3754e8fe41800a5daa6cd10641989 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 5 May 2011 15:46:48 +0100 Subject: [PATCH 387/590] paring --- dmenubar/dmenu.c | 30 +++++++++++------------------- dmenubar/draw.c | 7 ++----- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6ed025d..d8ef88f 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -36,9 +36,8 @@ static void paste(void); static void readstdin(void); static void run(void); static void setup(void); -static void usage(void); -static char text[BUFSIZ]; +static char text[BUFSIZ] = ""; static int bh, mw, mh; static int inputw = 0; static int lines = 0; @@ -79,7 +78,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; else if(i == argc-1) - usage(); + goto usage; /* double flags */ else if(!strcmp(argv[i], "-l")) lines = atoi(argv[++i]); @@ -98,15 +97,19 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) selfgcolor = argv[++i]; else - usage(); + goto usage; dc = initdc(); initfont(dc, font); readstdin(); setup(); run(); + return EXIT_FAILURE; - return EXIT_FAILURE; /* should not reach */ +usage: + fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + return EXIT_FAILURE; } void @@ -223,7 +226,7 @@ keypress(XKeyEvent *ev) { len = strlen(text); XLookupString(ev, buf, sizeof buf, &ksym, NULL); - if(ev->state & ControlMask) { + if(ev->state & ControlMask) switch(tolower(ksym)) { default: return; @@ -277,7 +280,6 @@ keypress(XKeyEvent *ev) { XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); return; } - } switch(ksym) { default: if(!iscntrl(*buf)) @@ -341,7 +343,6 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); - fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: if(cursor < len) { @@ -403,7 +404,7 @@ match(void) { else matches = lsubstr; } - curr = prev = next = sel = matches; + curr = sel = matches; calcoffsets(); } @@ -438,11 +439,10 @@ readstdin(void) { for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { if((p = strchr(buf, '\n'))) *p = '\0'; - if(!(item = malloc(sizeof *item))) + if(!(item = calloc(1, sizeof *item))) eprintf("cannot malloc %u bytes\n", sizeof *item); if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); - item->next = item->left = item->right = NULL; inputw = MAX(inputw, textw(dc, item->text)); } } @@ -530,13 +530,5 @@ setup(void) { inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); - text[0] = '\0'; match(); } - -void -usage(void) { - fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); -} diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 28c658c..80a5074 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -100,16 +100,13 @@ initdc(void) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) weprintf("no locale support\n"); - if(!(dc = malloc(sizeof *dc))) + if(!(dc = calloc(1, sizeof *dc))) eprintf("cannot malloc %u bytes\n", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) eprintf("cannot open display\n"); dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL); XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); - dc->font.xfont = NULL; - dc->font.set = NULL; - dc->canvas = None; return dc; } @@ -187,7 +184,7 @@ void weprintf(const char *fmt, ...) { va_list ap; - fprintf(stderr, "%s: warning: ", progname); + fprintf(stderr, "%s: ", progname); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); From c24f2967f27d0fd994e49deb084ed3c7d88b02a3 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 6 May 2011 21:13:02 +0100 Subject: [PATCH 388/590] helpful errors --- dmenubar/dmenu.c | 4 ++-- dmenubar/draw.c | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d8ef88f..5be73f7 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -440,9 +440,9 @@ readstdin(void) { if((p = strchr(buf, '\n'))) *p = '\0'; if(!(item = calloc(1, sizeof *item))) - eprintf("cannot malloc %u bytes\n", sizeof *item); + eprintf("cannot malloc %u bytes:", sizeof *item); if(!(item->text = strdup(buf))) - eprintf("cannot strdup %u bytes\n", strlen(buf)+1); + eprintf("cannot strdup %u bytes:", strlen(buf)+1); inputw = MAX(inputw, textw(dc, item->text)); } } diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 80a5074..83ced4b 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -68,6 +68,11 @@ eprintf(const char *fmt, ...) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); + + if(fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } exit(EXIT_FAILURE); } @@ -101,7 +106,7 @@ initdc(void) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) weprintf("no locale support\n"); if(!(dc = calloc(1, sizeof *dc))) - eprintf("cannot malloc %u bytes\n", sizeof *dc); + eprintf("cannot malloc %u bytes:", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) eprintf("cannot open display\n"); From db1d970bb8b7beca4c399510a665998f52bf34fe Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 8 May 2011 15:15:24 +0100 Subject: [PATCH 389/590] fast grab patch (thanks Rob) --- dmenubar/dmenu.1 | 22 +++++++++++++--------- dmenubar/dmenu.c | 18 ++++++++++++++---- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index d2a93d1..a4fcfd9 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -4,6 +4,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu .RB [ \-b ] +.RB [ \-f ] .RB [ \-i ] .RB [ \-l .IR lines ] @@ -32,9 +33,9 @@ is a dynamic menu for X, originally designed for .BR dwm (1). It manages huge numbers of user-defined menu items efficiently. .P -dmenu reads a list of newline-separated items from standard input and creates a -menu. When the user selects an item or enters any text and presses Return, -their choice is printed to standard output and dmenu terminates. +dmenu reads a list of newline-separated items from stdin and creates a menu. +When the user selects an item or enters any text and presses Return, their +choice is printed to stdout and dmenu terminates. .P .B dmenu_run is a dmenu script used by dwm which lists programs in the user's PATH and @@ -47,6 +48,10 @@ is a program used by dmenu_run to find and cache a list of executables. .B \-b dmenu appears at the bottom of the screen. .TP +.B \-f +dmenu grabs the keyboard before reading stdin. This is faster, but may lock up +X if stdin is from a terminal. +.TP .B \-i dmenu matches menu items case insensitively. .TP @@ -66,7 +71,7 @@ defines the font or font set used. defines the normal background color. .IR #RGB , .IR #RRGGBB , -and color names are supported. +and X color names are supported. .TP .BI \-nf " color" defines the normal foreground color. @@ -78,7 +83,7 @@ defines the selected background color. defines the selected foreground color. .TP .B \-v -prints version information to standard output, then exits. +prints version information to stdout, then exits. .SH USAGE dmenu is completely controlled by the keyboard. Besides standard Unix line editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the @@ -88,12 +93,11 @@ following keys are recognized: Copy the selected item to the input field. .TP .B Return (Control\-j) -Confirm selection. Prints the selected item to standard output and exits, -returning success. +Confirm selection. Prints the selected item to stdout and exits, returning +success. .TP .B Shift\-Return (Control\-Shift\-j) -Confirm input. Prints the input text to standard output and exits, returning -success. +Confirm input. Prints the input text to stdout and exits, returning success. .TP .B Escape (Control\-c) Exit without selecting an item, returning failure. diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5be73f7..2193f82 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -64,6 +64,7 @@ static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; int main(int argc, char *argv[]) { + Bool fast = False; int i; progname = "dmenu"; @@ -77,6 +78,8 @@ main(int argc, char *argv[]) { topbar = False; else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; + else if(!strcmp(argv[i], "-f")) + fast = True; else if(i == argc-1) goto usage; /* double flags */ @@ -101,13 +104,21 @@ main(int argc, char *argv[]) { dc = initdc(); initfont(dc, font); - readstdin(); - setup(); + + if(fast) { + setup(); + readstdin(); + } + else { + readstdin(); + setup(); + } + match(); run(); return EXIT_FAILURE; usage: - fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); return EXIT_FAILURE; } @@ -530,5 +541,4 @@ setup(void) { inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); - match(); } From 45045a21129e8e03bd44101e8682fa7c7df6c7ba Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 11 May 2011 12:25:50 +0100 Subject: [PATCH 390/590] fixed -m bug (thanks Rob) --- dmenubar/dmenu.c | 18 +++++++++--------- dmenubar/draw.c | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2193f82..3c83d73 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -76,10 +76,10 @@ main(int argc, char *argv[]) { } else if(!strcmp(argv[i], "-b")) topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; else if(!strcmp(argv[i], "-f")) fast = True; + else if(!strcmp(argv[i], "-i")) + fstrncmp = strncasecmp; else if(i == argc-1) goto usage; /* double flags */ @@ -506,18 +506,18 @@ setup(void) { mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { - int i, di; + int i, m, di; unsigned int du; Window dw; XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); - for(i = 0; i < n; i++) + for(i = 0, m = -1; i < n; i++) if((monitor == info[i].screen_number) - || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) - break; - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; + || (m < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) + m = i; + x = info[m].x_org; + y = info[m].y_org + (topbar ? 0 : info[m].height - mh); + mw = info[m].width; XFree(info); } else diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 83ced4b..d35d4c2 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -7,9 +7,9 @@ #include <X11/Xlib.h> #include "draw.h" -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define DEFFONT "fixed" +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define DEFFONT "fixed" static Bool loadfont(DC *dc, const char *fontstr); From ce9295cb8e94092d58cc6f0ff31585fa3903c933 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 12 May 2011 13:17:41 +0100 Subject: [PATCH 391/590] fixed xinerama corner case --- dmenubar/dmenu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3c83d73..6d35430 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -506,18 +506,18 @@ setup(void) { mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { - int i, m, di; + int i, di; unsigned int du; Window dw; XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); - for(i = 0, m = -1; i < n; i++) + for(i = 0; i < n-1; i++) if((monitor == info[i].screen_number) - || (m < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) - m = i; - x = info[m].x_org; - y = info[m].y_org + (topbar ? 0 : info[m].height - mh); - mw = info[m].width; + || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) + break; + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; XFree(info); } else From 6f9896a5c2bf7c07e4aaed05adb79c74ebb02baf Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 17:46:20 +0100 Subject: [PATCH 392/590] use array for items --- dmenubar/dmenu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6d35430..2684c91 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,4 +1,4 @@ -/* See LICENSE file for copyright and license details. */ +/* See LICENSE file for copynext and license details. */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> @@ -19,8 +19,7 @@ typedef struct Item Item; struct Item { char *text; - Item *next; /* traverses all items */ - Item *left, *right; /* traverses matching items */ + Item *left, *right; }; static void appenditem(Item *item, Item **list, Item **last); @@ -386,7 +385,7 @@ match(void) { len = strlen(text); matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; - for(item = items; item; item = item->next) + for(item = items; item && item->text; item++) if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); else if(!fstrncmp(text, item->text, len)) @@ -445,16 +444,17 @@ paste(void) { void readstdin(void) { char buf[sizeof text], *p; - Item *item, **end; + size_t i, size = 0; - for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { + for(i = 0; fgets(buf, sizeof buf, stdin); items[++i].text = NULL) { + if(i+1 == size / sizeof *items || !items) + if(!(items = realloc(items, (size += BUFSIZ)))) + eprintf("cannot realloc %u bytes:", size); if((p = strchr(buf, '\n'))) *p = '\0'; - if(!(item = calloc(1, sizeof *item))) - eprintf("cannot malloc %u bytes:", sizeof *item); - if(!(item->text = strdup(buf))) + if(!(items[i].text = strdup(buf))) eprintf("cannot strdup %u bytes:", strlen(buf)+1); - inputw = MAX(inputw, textw(dc, item->text)); + inputw = MAX(inputw, textw(dc, items[i].text)); } } From 82d389760ca9bd074a13818ceaa819a2c97dbd45 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 17:47:12 +0100 Subject: [PATCH 393/590] fix typo --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2684c91..68fc9ff 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,4 +1,4 @@ -/* See LICENSE file for copynext and license details. */ +/* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> From 9dbbebaf1e955db425d5b5be71ae53ec96854714 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 18:39:27 +0100 Subject: [PATCH 394/590] instant ^E --- dmenubar/dmenu.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 68fc9ff..b6f1ef2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -55,8 +55,8 @@ static Atom utf8; static Bool topbar = True; static DC *dc; static Item *items = NULL; -static Item *matches, *sel; -static Item *prev, *curr, *next; +static Item *matches, *matchend; +static Item *prev, *curr, *next, *sel; static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; @@ -308,12 +308,15 @@ keypress(XKeyEvent *ev) { cursor = len; break; } - while(next) { - sel = curr = next; + if(next) { + curr = matchend; calcoffsets(); + curr = prev; + calcoffsets(); + while(next && (curr = curr->right)) + calcoffsets(); } - while(sel && sel->right) - sel = sel->right; + sel = matchend; break; case XK_Escape: exit(EXIT_FAILURE); @@ -381,10 +384,10 @@ keypress(XKeyEvent *ev) { void match(void) { size_t len; - Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; + Item *item, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; len = strlen(text); - matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; + matches = lexact = lprefix = lsubstr = matchend = exactend = prefixend = substrend = NULL; for(item = items; item && item->text; item++) if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); @@ -395,24 +398,25 @@ match(void) { if(lexact) { matches = lexact; - itemend = exactend; + matchend = exactend; } if(lprefix) { - if(itemend) { - itemend->right = lprefix; - lprefix->left = itemend; + if(matchend) { + matchend->right = lprefix; + lprefix->left = matchend; } else matches = lprefix; - itemend = prefixend; + matchend = prefixend; } if(lsubstr) { - if(itemend) { - itemend->right = lsubstr; - lsubstr->left = itemend; + if(matchend) { + matchend->right = lsubstr; + lsubstr->left = matchend; } else matches = lsubstr; + matchend = substrend; } curr = sel = matches; calcoffsets(); From 4b3052b5659503ad0f7f6aa72b39b1cee364b535 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 20:43:11 +0100 Subject: [PATCH 395/590] fast dmenu_path script --- dmenubar/Makefile | 10 ++--- dmenubar/dmenu.1 | 2 +- dmenubar/dmenu_path | 9 ++++ dmenubar/dmenu_path.c | 100 ------------------------------------------ 4 files changed, 13 insertions(+), 108 deletions(-) create mode 100755 dmenubar/dmenu_path delete mode 100644 dmenubar/dmenu_path.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index dd744e1..60e53d1 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -all: options dmenu dmenu_path +all: options dmenu options: @echo dmenu build options: @@ -15,22 +15,18 @@ dmenu: dmenu.o draw.o @echo CC -o $@ @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} -dmenu_path: dmenu_path.o - @echo CC -o $@ - @${CC} -o $@ dmenu_path.o ${LDFLAGS} - .c.o: config.mk @echo CC -c $< @${CC} -c $< ${CFLAGS} clean: @echo cleaning - @rm -f dmenu dmenu.o draw.o dmenu_path dmenu_path.o dmenu-${VERSION}.tar.gz + @rm -f dmenu dmenu.o draw.o dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c draw.c draw.h dmenu_path.c dmenu_run dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c draw.c draw.h dmenu_path dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index a4fcfd9..5f138c8 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -42,7 +42,7 @@ is a dmenu script used by dwm which lists programs in the user's PATH and executes the selected item. .P .B dmenu_path -is a program used by dmenu_run to find and cache a list of executables. +is a script used by dmenu_run to find and cache a list of executables. .SH OPTIONS .TP .B \-b diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path new file mode 100755 index 0000000..f3a4701 --- /dev/null +++ b/dmenubar/dmenu_path @@ -0,0 +1,9 @@ +#!/bin/sh +CACHE=$HOME/.dmenu_cache +IFS=: + +if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then + find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sort -u > "$CACHE" +fi + +cat "$CACHE" diff --git a/dmenubar/dmenu_path.c b/dmenubar/dmenu_path.c deleted file mode 100644 index 407477a..0000000 --- a/dmenubar/dmenu_path.c +++ /dev/null @@ -1,100 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <dirent.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> - -static void die(const char *s); -static int qstrcmp(const void *a, const void *b); -static void scan(void); -static int uptodate(void); - -static char **items = NULL; -static const char *home, *path; - -int -main(void) { - if(!(home = getenv("HOME"))) - die("no $HOME"); - if(!(path = getenv("PATH"))) - die("no $PATH"); - if(chdir(home) < 0) - die("chdir failed"); - if(uptodate()) { - execl("/bin/cat", "cat", CACHE, NULL); - die("exec failed"); - } - scan(); - return EXIT_SUCCESS; -} - -void -die(const char *s) { - fprintf(stderr, "dmenu_path: %s\n", s); - exit(EXIT_FAILURE); -} - -int -qstrcmp(const void *a, const void *b) { - return strcmp(*(const char **)a, *(const char **)b); -} - -void -scan(void) { - char buf[PATH_MAX]; - char *dir, *p; - size_t i, count; - struct dirent *ent; - DIR *dp; - FILE *cache; - - count = 0; - if(!(p = strdup(path))) - die("strdup failed"); - for(dir = strtok(p, ":"); dir; dir = strtok(NULL, ":")) { - if(!(dp = opendir(dir))) - continue; - while((ent = readdir(dp))) { - snprintf(buf, sizeof buf, "%s/%s", dir, ent->d_name); - if(ent->d_name[0] == '.' || access(buf, X_OK) < 0) - continue; - if(!(items = realloc(items, ++count * sizeof *items))) - die("malloc failed"); - if(!(items[count-1] = strdup(ent->d_name))) - die("strdup failed"); - } - closedir(dp); - } - qsort(items, count, sizeof *items, qstrcmp); - if(!(cache = fopen(CACHE, "w"))) - die("open failed"); - for(i = 0; i < count; i++) { - if(i > 0 && !strcmp(items[i], items[i-1])) - continue; - fprintf(cache, "%s\n", items[i]); - fprintf(stdout, "%s\n", items[i]); - } - fclose(cache); - free(p); -} - -int -uptodate(void) { - char *dir, *p; - time_t mtime; - struct stat st; - - if(stat(CACHE, &st) < 0) - return 0; - mtime = st.st_mtime; - if(!(p = strdup(path))) - die("strdup failed"); - for(dir = strtok(p, ":"); dir; dir = strtok(NULL, ":")) - if(!stat(dir, &st) && st.st_mtime > mtime) - return 0; - free(p); - return 1; -} From 5ba07e920fa27a65e498850b40b27336c65b785b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 22:12:28 +0100 Subject: [PATCH 396/590] whoops, wrong dmenu_path version --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index f3a4701..c1d3357 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sort -u > "$CACHE" + find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" fi cat "$CACHE" From 8fb09a7924c2874328882ed24ba25d638553d794 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 22:43:42 +0100 Subject: [PATCH 397/590] cleanup --- dmenubar/dmenu.c | 7 ++----- dmenubar/draw.c | 24 +++++------------------- dmenubar/draw.h | 9 +++------ 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b6f1ef2..40b220c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -66,7 +66,6 @@ main(int argc, char *argv[]) { Bool fast = False; int i; - progname = "dmenu"; for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { @@ -383,10 +382,9 @@ keypress(XKeyEvent *ev) { void match(void) { - size_t len; + size_t len = strlen(text); Item *item, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - len = strlen(text); matches = lexact = lprefix = lsubstr = matchend = exactend = prefixend = substrend = NULL; for(item = items; item && item->text; item++) if(!fstrncmp(text, item->text, len + 1)) @@ -424,9 +422,8 @@ match(void) { size_t nextrune(int incr) { - size_t n, len; + size_t n, len = strlen(text); - len = strlen(text); for(n = cursor + incr; n >= 0 && n < len && (text[n] & 0xc0) == 0x80; n += incr); return n; } diff --git a/dmenubar/draw.c b/dmenubar/draw.c index d35d4c2..f9b8957 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -29,10 +29,9 @@ drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign void drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { char buf[256]; - size_t n, mn; + size_t mn, n = strlen(text); /* shorten text if necessary */ - n = strlen(text); for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) > dc->w - dc->font.height/2; mn--) if(mn == 0) return; @@ -46,10 +45,8 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { - int x, y; - - x = dc->x + dc->font.height/2; - y = dc->y + dc->font.ascent+1; + int x = dc->x + dc->font.height/2; + int y = dc->y + dc->font.ascent+1; XSetForeground(dc->dpy, dc->gc, FG(dc, col)); if(dc->font.set) @@ -64,7 +61,6 @@ void eprintf(const char *fmt, ...) { va_list ap; - fprintf(stderr, "%s: ", progname); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); @@ -104,7 +100,7 @@ initdc(void) { DC *dc; if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - weprintf("no locale support\n"); + fprintf(stderr, "no locale support\n"); if(!(dc = calloc(1, sizeof *dc))) eprintf("cannot malloc %u bytes:", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) @@ -119,7 +115,7 @@ void initfont(DC *dc, const char *fontstr) { if(!loadfont(dc, fontstr ? fontstr : DEFFONT)) { if(fontstr != NULL) - weprintf("cannot load font '%s'\n", fontstr); + fprintf(stderr, "cannot load font '%s'\n", fontstr); if(fontstr == NULL || !loadfont(dc, DEFFONT)) eprintf("cannot load font '%s'\n", DEFFONT); } @@ -184,13 +180,3 @@ int textw(DC *dc, const char *text) { return textnw(dc, text, strlen(text)) + dc->font.height; } - -void -weprintf(const char *fmt, ...) { - va_list ap; - - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} diff --git a/dmenubar/draw.h b/dmenubar/draw.h index ac3943f..247c0b3 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw.h @@ -20,18 +20,15 @@ typedef struct { } font; } DC; /* draw context */ -unsigned long getcolor(DC *dc, const char *colstr); void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -void initfont(DC *dc, const char *fontstr); +void eprintf(const char *fmt, ...); void freedc(DC *dc); +unsigned long getcolor(DC *dc, const char *colstr); DC *initdc(void); +void initfont(DC *dc, const char *fontstr); void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); void resizedc(DC *dc, unsigned int w, unsigned int h); int textnw(DC *dc, const char *text, size_t len); int textw(DC *dc, const char *text); -void eprintf(const char *fmt, ...); -void weprintf(const char *fmt, ...); - -const char *progname; From a190d5e1f7991c98e40c97ae887384a07f40d1de Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 23:14:31 +0100 Subject: [PATCH 398/590] follow symlinks --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index c1d3357..59fe64d 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" + find -L $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" fi cat "$CACHE" From 2d381a46e2d74a0e98f67066643c50e7fab0fc59 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 23:21:38 +0100 Subject: [PATCH 399/590] only match links --- dmenubar/dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 59fe64d..1b1b241 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find -L $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" + find $PATH ! -type d \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" fi cat "$CACHE" From 0284f83812efdf94df67486258a0f8e9c98e34f3 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 14 May 2011 23:26:41 +0100 Subject: [PATCH 400/590] increment version --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 08ea1bf..aedd13c 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.2.1 +VERSION = 4.3 # dmenu_path cache (absolute or relative to $HOME) CACHE = .dmenu_cache From 44930a4c534eda8b1ba2fa6bdf40a2a4f1381a2b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 02:37:49 +0100 Subject: [PATCH 401/590] cleanup --- dmenubar/Makefile | 19 ++++++++++++------- dmenubar/config.mk | 6 +----- dmenubar/dmenu.1 | 4 ++-- dmenubar/draw.c | 8 +++----- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 60e53d1..5871fa7 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,6 +3,9 @@ include config.mk +SRC = dmenu.c draw.c +OBJ = ${SRC:.c=.o} + all: options dmenu options: @@ -11,22 +14,24 @@ options: @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" -dmenu: dmenu.o draw.o - @echo CC -o $@ - @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} - -.c.o: config.mk +.c.o: @echo CC -c $< @${CC} -c $< ${CFLAGS} +${OBJ}: config.mk + +dmenu: ${OBJ} + @echo CC -o $@ + @${CC} -o $@ ${OBJ} ${LDFLAGS} + clean: @echo cleaning - @rm -f dmenu dmenu.o draw.o dmenu-${VERSION}.tar.gz + @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c draw.c draw.h dmenu_path dmenu_run dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/config.mk b/dmenubar/config.mk index aedd13c..126bd79 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,10 +1,6 @@ # dmenu version VERSION = 4.3 -# dmenu_path cache (absolute or relative to $HOME) -CACHE = .dmenu_cache - - # paths PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man @@ -21,7 +17,7 @@ INCS = -I${X11INC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" -DCACHE=\"${CACHE}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 5f138c8..e5aa8cd 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -31,9 +31,9 @@ dmenu \- dynamic menu .B dmenu is a dynamic menu for X, originally designed for .BR dwm (1). -It manages huge numbers of user-defined menu items efficiently. +It manages huge numbers of user\-defined menu items efficiently. .P -dmenu reads a list of newline-separated items from stdin and creates a menu. +dmenu reads a list of newline\-separated items from stdin and creates a menu. When the user selects an item or enters any text and presses Return, their choice is printed to stdout and dmenu terminates. .P diff --git a/dmenubar/draw.c b/dmenubar/draw.c index f9b8957..95ff072 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -25,14 +25,13 @@ drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign (fill ? XFillRectangles : XDrawRectangles)(dc->dpy, dc->canvas, dc->gc, &r, 1); } - void drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - char buf[256]; + char buf[BUFSIZ]; size_t mn, n = strlen(text); /* shorten text if necessary */ - for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) > dc->w - dc->font.height/2; mn--) + for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) + dc->font.height/2 > dc->w; mn--) if(mn == 0) return; memcpy(buf, text, mn); @@ -157,12 +156,11 @@ void resizedc(DC *dc, unsigned int w, unsigned int h) { if(dc->canvas) XFreePixmap(dc->dpy, dc->canvas); + dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); - dc->x = dc->y = 0; dc->w = w; dc->h = h; - dc->invert = False; } int From 721accf82844d39355fead161bce1692ab2fa874 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 13:02:33 +0100 Subject: [PATCH 402/590] fast but inexact --- dmenubar/dmenu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 40b220c..1681a55 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -444,19 +444,22 @@ paste(void) { void readstdin(void) { - char buf[sizeof text], *p; - size_t i, size = 0; + char buf[sizeof text], *p, *maxstr = NULL; + size_t i, max = 0, size = 0; for(i = 0; fgets(buf, sizeof buf, stdin); items[++i].text = NULL) { - if(i+1 == size / sizeof *items || !items) + if(i+1 >= size / sizeof *items) if(!(items = realloc(items, (size += BUFSIZ)))) eprintf("cannot realloc %u bytes:", size); if((p = strchr(buf, '\n'))) *p = '\0'; if(!(items[i].text = strdup(buf))) eprintf("cannot strdup %u bytes:", strlen(buf)+1); - inputw = MAX(inputw, textw(dc, items[i].text)); + if(strlen(items[i].text) > max) + max = strlen(maxstr = items[i].text); } + if(maxstr) + inputw = textw(dc, maxstr); } void From f5704238b80bb5cd7cac1eb39cefaea6d89786e4 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 13:58:54 +0100 Subject: [PATCH 403/590] cleanup --- dmenubar/dmenu.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1681a55..cf5e4a6 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -38,7 +38,7 @@ static void setup(void); static char text[BUFSIZ] = ""; static int bh, mw, mh; -static int inputw = 0; +static int inputw; static int lines = 0; static int monitor = -1; static int promptw; @@ -78,7 +78,7 @@ main(int argc, char *argv[]) { fast = True; else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; - else if(i == argc-1) + else if(i+1 == argc) goto usage; /* double flags */ else if(!strcmp(argv[i], "-l")) @@ -220,9 +220,9 @@ void insert(const char *s, ssize_t n) { if(strlen(text) + n > sizeof text - 1) return; - 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) - memcpy(text + cursor, s, n); + memcpy(&text[cursor], s, n); cursor += n; match(); } @@ -458,8 +458,7 @@ readstdin(void) { if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } - if(maxstr) - inputw = textw(dc, maxstr); + inputw = maxstr ? textw(dc, maxstr) : 0; } void From 1384537af73a1e9aca7a9ab500c783bd7038e9ca Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 14:13:31 +0100 Subject: [PATCH 404/590] faster grab --- dmenubar/dmenu.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index cf5e4a6..d54b1b3 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -57,7 +57,7 @@ static DC *dc; static Item *items = NULL; static Item *matches, *matchend; static Item *prev, *curr, *next, *sel; -static Window root, win; +static Window win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; @@ -104,14 +104,14 @@ main(int argc, char *argv[]) { initfont(dc, font); if(fast) { - setup(); + grabkeyboard(); readstdin(); } else { readstdin(); - setup(); + grabkeyboard(); } - match(); + setup(); run(); return EXIT_FAILURE; @@ -209,7 +209,8 @@ grabkeyboard(void) { int i; for(i = 0; i < 1000; i++) { - if(!XGrabKeyboard(dc->dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) + if(XGrabKeyboard(dc->dpy, DefaultRootWindow(dc->dpy), True, + GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) return; usleep(1000); } @@ -487,22 +488,21 @@ run(void) { void setup(void) { - int x, y, screen; + int x, y, screen = DefaultScreen(dc->dpy); + Window root = RootWindow(dc->dpy, screen); XSetWindowAttributes wa; #ifdef XINERAMA int n; XineramaScreenInfo *info; #endif - screen = DefaultScreen(dc->dpy); - root = RootWindow(dc->dpy, screen); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - normcol[ColBG] = getcolor(dc, normbgcolor); normcol[ColFG] = getcolor(dc, normfgcolor); selcol[ColBG] = getcolor(dc, selbgcolor); selcol[ColFG] = getcolor(dc, selfgcolor); + utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); + /* menu geometry */ bh = dc->font.height + 2; lines = MAX(lines, 0); @@ -539,9 +539,10 @@ setup(void) { DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - grabkeyboard(); resizedc(dc, mw, mh); inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); + drawmenu(); + match(); } From 7bcc9b6c2cbd146edd24811d83efd6031543e3e7 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 14:21:00 +0100 Subject: [PATCH 405/590] match first --- dmenubar/dmenu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d54b1b3..d0ed966 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -530,6 +530,10 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } + inputw = MIN(inputw, mw/3); + promptw = prompt ? textw(dc, prompt) : 0; + match(); + /* menu window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; @@ -539,10 +543,7 @@ setup(void) { DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - resizedc(dc, mw, mh); - inputw = MIN(inputw, mw/3); - promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); + resizedc(dc, mw, mh); drawmenu(); - match(); } From 16fd6fcb0f314fd1f8eb6d01654a9aaaf951496c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 16:05:32 +0100 Subject: [PATCH 406/590] efficient incremental search --- dmenubar/dmenu.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d0ed966..a8a6290 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -27,9 +27,9 @@ static void calcoffsets(void); static void drawmenu(void); static char *fstrstr(const char *s, const char *sub); static void grabkeyboard(void); -static void insert(const char *s, ssize_t n); +static void insert(const char *str, ssize_t n); static void keypress(XKeyEvent *ev); -static void match(void); +static void match(Bool sub); static size_t nextrune(int incr); static void paste(void); static void readstdin(void); @@ -218,14 +218,14 @@ grabkeyboard(void) { } void -insert(const char *s, ssize_t n) { +insert(const char *str, ssize_t n) { if(strlen(text) + n > sizeof text - 1) return; memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); if(n > 0) - memcpy(&text[cursor], s, n); + memcpy(&text[cursor], str, n); cursor += n; - match(); + match(n > 0); } void @@ -269,7 +269,7 @@ keypress(XKeyEvent *ev) { break; case XK_k: /* delete right */ text[cursor] = '\0'; - match(); + match(False); break; case XK_n: ksym = XK_Down; @@ -375,30 +375,31 @@ keypress(XKeyEvent *ev) { return; strncpy(text, sel->text, sizeof text); cursor = strlen(text); - match(); + match(True); break; } drawmenu(); } void -match(void) { +match(Bool sub) { size_t len = strlen(text); - Item *item, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; + Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; + Item *item, *next = NULL; - matches = lexact = lprefix = lsubstr = matchend = exactend = prefixend = substrend = NULL; - for(item = items; item && item->text; item++) + lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL; + for(item = sub ? matches : items; item && item->text; item = next) { + next = sub ? item->right : item + 1; if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); else if(!fstrncmp(text, item->text, len)) appenditem(item, &lprefix, &prefixend); else if(fstrstr(item->text, text)) appenditem(item, &lsubstr, &substrend); - - if(lexact) { - matches = lexact; - matchend = exactend; } + matches = lexact; + matchend = exactend; + if(lprefix) { if(matchend) { matchend->right = lprefix; @@ -498,8 +499,8 @@ setup(void) { normcol[ColBG] = getcolor(dc, normbgcolor); normcol[ColFG] = getcolor(dc, normfgcolor); - selcol[ColBG] = getcolor(dc, selbgcolor); - selcol[ColFG] = getcolor(dc, selfgcolor); + selcol[ColBG] = getcolor(dc, selbgcolor); + selcol[ColFG] = getcolor(dc, selfgcolor); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); @@ -532,7 +533,7 @@ setup(void) { } inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; - match(); + match(False); /* menu window */ wa.override_redirect = True; From c5f8cd54dff59a07fda1b223b06abcb0833af7bb Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 15 May 2011 21:54:26 +0100 Subject: [PATCH 407/590] portability --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 21 ++++++++++++--------- dmenubar/draw.c | 11 ++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 126bd79..03f1670 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -18,7 +18,7 @@ LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} # compiler and linker diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a8a6290..cee73b2 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -3,6 +3,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <unistd.h> #include <X11/Xlib.h> #include <X11/Xatom.h> @@ -231,13 +232,14 @@ insert(const char *str, ssize_t n) { void keypress(XKeyEvent *ev) { char buf[32]; - size_t len; KeySym ksym; - len = strlen(text); XLookupString(ev, buf, sizeof buf, &ksym, NULL); - if(ev->state & ControlMask) - switch(tolower(ksym)) { + if(ev->state & ControlMask) { + KeySym lower, upper; + + XConvertCase(ksym, &lower, &upper); + switch(lower) { default: return; case XK_a: @@ -290,13 +292,14 @@ keypress(XKeyEvent *ev) { XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); return; } + } switch(ksym) { default: if(!iscntrl(*buf)) insert(buf, strlen(buf)); break; case XK_Delete: - if(cursor == len) + if(text[cursor] == '\0') return; cursor = nextrune(+1); case XK_BackSpace: @@ -304,8 +307,8 @@ keypress(XKeyEvent *ev) { insert(NULL, nextrune(-1) - cursor); break; case XK_End: - if(cursor < len) { - cursor = len; + if(text[cursor] != '\0') { + cursor = strlen(text); break; } if(next) { @@ -358,7 +361,7 @@ keypress(XKeyEvent *ev) { fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); exit(EXIT_SUCCESS); case XK_Right: - if(cursor < len) { + if(text[cursor] != '\0') { cursor = nextrune(+1); break; } @@ -385,7 +388,7 @@ void match(Bool sub) { size_t len = strlen(text); Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - Item *item, *next = NULL; + Item *item, *next; lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL; for(item = sub ? matches : items; item && item->text; item = next) { diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 95ff072..351a43d 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -15,12 +15,13 @@ static Bool loadfont(DC *dc, const char *fontstr); void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { - XRectangle r = { dc->x + x, dc->y + y, w, h }; + XRectangle r; + + r.x = dc->x + x; + r.y = dc->y + y; + r.width = fill ? w : w-1; + r.height = fill ? h : h-1; - if(!fill) { - r.width -= 1; - r.height -= 1; - } XSetForeground(dc->dpy, dc->gc, color); (fill ? XFillRectangles : XDrawRectangles)(dc->dpy, dc->canvas, dc->gc, &r, 1); } From 2b3763cb3b830b04578eef4d635bbaace6e268b7 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 16 May 2011 12:59:31 +0100 Subject: [PATCH 408/590] fixed extra warnings --- dmenubar/dmenu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index cee73b2..a32131c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -135,7 +135,7 @@ appenditem(Item *item, Item **list, Item **last) { void calcoffsets(void) { - unsigned int i, n; + int i, n; if(lines > 0) n = lines * bh; @@ -388,11 +388,11 @@ void match(Bool sub) { size_t len = strlen(text); Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - Item *item, *next; + Item *item, *lnext; lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL; - for(item = sub ? matches : items; item && item->text; item = next) { - next = sub ? item->right : item + 1; + for(item = sub ? matches : items; item && item->text; item = lnext) { + lnext = sub ? item->right : item + 1; if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); else if(!fstrncmp(text, item->text, len)) @@ -429,7 +429,7 @@ size_t nextrune(int incr) { size_t n, len = strlen(text); - for(n = cursor + incr; n >= 0 && n < len && (text[n] & 0xc0) == 0x80; n += incr); + for(n = cursor + incr; n < len && (text[n] & 0xc0) == 0x80; n += incr); return n; } @@ -442,7 +442,7 @@ paste(void) { XGetWindowProperty(dc->dpy, win, utf8, 0, (sizeof text / 4) + 1, False, utf8, &da, &di, &dl, &dl, (unsigned char **)&p); - insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); + insert(p, (q = strchr(p, '\n')) ? q-p : (ssize_t)strlen(p)); XFree(p); drawmenu(); } From b9ff8318d7b5f3bbeff6698bc28e34e3152cbb6d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 16 May 2011 23:35:14 +0100 Subject: [PATCH 409/590] fix possible overflow --- dmenubar/dmenu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a32131c..c4b7908 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -31,7 +31,7 @@ static void grabkeyboard(void); static void insert(const char *str, ssize_t n); static void keypress(XKeyEvent *ev); static void match(Bool sub); -static size_t nextrune(int incr); +static size_t nextrune(int inc); static void paste(void); static void readstdin(void); static void run(void); @@ -426,10 +426,10 @@ match(Bool sub) { } size_t -nextrune(int incr) { - size_t n, len = strlen(text); +nextrune(int inc) { + ssize_t n; - for(n = cursor + incr; n < len && (text[n] & 0xc0) == 0x80; n += incr); + for(n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc); return n; } From 26e51ad50d3faa1d578dd154efb198b76d4f193b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 May 2011 16:20:03 +0100 Subject: [PATCH 410/590] no -m, cleanup --- dmenubar/dmenu.1 | 17 ++++++----------- dmenubar/dmenu.c | 35 ++++++++++++++++++----------------- dmenubar/draw.c | 22 +++++++++------------- 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index e5aa8cd..8295d17 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -8,8 +8,6 @@ dmenu \- dynamic menu .RB [ \-i ] .RB [ \-l .IR lines ] -.RB [ \-m -.IR monitor ] .RB [ \-p .IR prompt ] .RB [ \-fn @@ -58,9 +56,6 @@ dmenu matches menu items case insensitively. .BI \-l " lines" dmenu lists items vertically, with the given number of lines. .TP -.BI \-m " monitor" -dmenu appears on the given Xinerama screen. -.TP .BI \-p " prompt" defines the prompt to be displayed to the left of the input field. .TP @@ -86,23 +81,23 @@ defines the selected foreground color. prints version information to stdout, then exits. .SH USAGE dmenu is completely controlled by the keyboard. Besides standard Unix line -editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the +editing and item selection (arrow keys, page up/down, home and end), the following keys are recognized: .TP -.B Tab (Control\-i) +.B Tab (Ctrl\-i) Copy the selected item to the input field. .TP -.B Return (Control\-j) +.B Return (Ctrl\-j) Confirm selection. Prints the selected item to stdout and exits, returning success. .TP -.B Shift\-Return (Control\-Shift\-j) +.B Shift\-Return (Ctrl\-Shift\-j) Confirm input. Prints the input text to stdout and exits, returning success. .TP -.B Escape (Control\-c) +.B Escape (Ctrl\-c) Exit without selecting an item, returning failure. .TP -.B Control\-y +.B Ctrl\-y Paste the current X selection into the input field. .SH SEE ALSO .BR dwm (1) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c4b7908..da62705 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -36,13 +36,12 @@ static void paste(void); static void readstdin(void); static void run(void); static void setup(void); +static void usage(void); static char text[BUFSIZ] = ""; static int bh, mw, mh; -static int inputw; +static int inputw, promptw; static int lines = 0; -static int monitor = -1; -static int promptw; static size_t cursor = 0; static const char *font = NULL; static const char *prompt = NULL; @@ -70,7 +69,7 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { - fputs("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details\n", stdout); + puts("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details"); exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) @@ -80,12 +79,10 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; else if(i+1 == argc) - goto usage; + usage(); /* double flags */ else if(!strcmp(argv[i], "-l")) lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-m")) - monitor = atoi(argv[++i]); else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) @@ -99,7 +96,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) selfgcolor = argv[++i]; else - goto usage; + usage(); dc = initdc(); initfont(dc, font); @@ -114,12 +111,8 @@ main(int argc, char *argv[]) { } setup(); run(); - return EXIT_FAILURE; -usage: - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - return EXIT_FAILURE; + return EXIT_FAILURE; /* should not reach */ } void @@ -452,7 +445,7 @@ readstdin(void) { char buf[sizeof text], *p, *maxstr = NULL; size_t i, max = 0, size = 0; - for(i = 0; fgets(buf, sizeof buf, stdin); items[++i].text = NULL) { + for(i = 0; fgets(buf, sizeof buf, stdin); i++) { if(i+1 >= size / sizeof *items) if(!(items = realloc(items, (size += BUFSIZ)))) eprintf("cannot realloc %u bytes:", size); @@ -463,6 +456,8 @@ readstdin(void) { if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } + if(items) + items[i].text = NULL; inputw = maxstr ? textw(dc, maxstr) : 0; } @@ -519,8 +514,7 @@ setup(void) { XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n-1; i++) - if((monitor == info[i].screen_number) - || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); @@ -534,8 +528,8 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } - inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; + inputw = MIN(inputw, mw/3); match(False); /* menu window */ @@ -551,3 +545,10 @@ setup(void) { resizedc(dc, mw, mh); drawmenu(); } + +void +usage(void) { + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(EXIT_FAILURE); +} diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 351a43d..f952b53 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -9,21 +9,17 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define DEFFONT "fixed" +#define DEFAULTFN "fixed" static Bool loadfont(DC *dc, const char *fontstr); void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { - XRectangle r; - - r.x = dc->x + x; - r.y = dc->y + y; - r.width = fill ? w : w-1; - r.height = fill ? h : h-1; - XSetForeground(dc->dpy, dc->gc, color); - (fill ? XFillRectangles : XDrawRectangles)(dc->dpy, dc->canvas, dc->gc, &r, 1); + if(fill) + XFillRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w, h); + else + XDrawRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w-1, h-1); } void @@ -65,7 +61,7 @@ eprintf(const char *fmt, ...) { vfprintf(stderr, fmt, ap); va_end(ap); - if(fmt[strlen(fmt)-1] == ':') { + if(fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') { fputc(' ', stderr); perror(NULL); } @@ -113,11 +109,11 @@ initdc(void) { void initfont(DC *dc, const char *fontstr) { - if(!loadfont(dc, fontstr ? fontstr : DEFFONT)) { + if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { if(fontstr != NULL) fprintf(stderr, "cannot load font '%s'\n", fontstr); - if(fontstr == NULL || !loadfont(dc, DEFFONT)) - eprintf("cannot load font '%s'\n", DEFFONT); + if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) + eprintf("cannot load font '%s'\n", DEFAULTFN); } dc->font.height = dc->font.ascent + dc->font.descent; } From a453d7f003e9966c268f76ef156e6e01948e023a Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 May 2011 16:21:45 +0100 Subject: [PATCH 411/590] Added tag 4.3 for changeset 14c79f054bdf --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index 1462feb..f8ce5c0 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -44,3 +44,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 72749a826cab0baa805620e44a22e54486c97a4e 4.1.1 379813a051f03a1b20bdbfdc2d2d1d2d794ace48 4.2 abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1 +14c79f054bdf43ff3213af8e60a783192e92a018 4.3 From c7400bfec6be6137a5b0ac9f53b994a2831f6f37 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 May 2011 17:01:44 +0100 Subject: [PATCH 412/590] bugfix --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 03f1670..70c9e36 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.3 +VERSION = 4.3.1 # paths PREFIX = /usr/local diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index da62705..8acf057 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -219,7 +219,7 @@ insert(const char *str, ssize_t n) { if(n > 0) memcpy(&text[cursor], str, n); cursor += n; - match(n > 0); + match(n > 0 && text[cursor] == '\0'); } void From f6f291f699fdf656bad0a6044170046a80493dcb Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 May 2011 17:01:59 +0100 Subject: [PATCH 413/590] Added tag 4.3.1 for changeset 34a2d77049a9 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index f8ce5c0..dcceb88 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -45,3 +45,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 379813a051f03a1b20bdbfdc2d2d1d2d794ace48 4.2 abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1 14c79f054bdf43ff3213af8e60a783192e92a018 4.3 +34a2d77049a95b02f3332a0b88f9370965ebcfad 4.3.1 From b0dc641d20d68d2f8253d8c888792fc2d0e1ae1d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 13 Jun 2011 19:25:40 +0100 Subject: [PATCH 414/590] add ^M --- dmenubar/dmenu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8acf057..d03087f 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -260,6 +260,7 @@ keypress(XKeyEvent *ev) { ksym = XK_Tab; break; case XK_j: + case XK_m: ksym = XK_Return; break; case XK_k: /* delete right */ From e152b596e6615c8b18f32e2bb5fb2d8b0d41c1f9 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 13 Jun 2011 19:28:30 +0100 Subject: [PATCH 415/590] new lsx branch --- dmenubar/Makefile | 21 +++++++++++++++------ dmenubar/dmenu_path | 2 +- dmenubar/lsx.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 dmenubar/lsx.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 5871fa7..34a05b6 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,10 +3,10 @@ include config.mk -SRC = dmenu.c draw.c +SRC = dmenu.c draw.c lsx.c OBJ = ${SRC:.c=.o} -all: options dmenu +all: options dmenu lsx options: @echo dmenu build options: @@ -20,9 +20,13 @@ options: ${OBJ}: config.mk -dmenu: ${OBJ} +dmenu: dmenu.o draw.o @echo CC -o $@ - @${CC} -o $@ ${OBJ} ${LDFLAGS} + @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} + +lsx: lsx.o + @echo CC -o $@ + @${CC} -o $@ lsx.o ${LDFLAGS} clean: @echo cleaning @@ -39,21 +43,26 @@ dist: clean install: all @echo installing executables to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin + @cp -f dmenu dmenu_path dmenu_run lsx ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run - @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 + @chmod 755 ${DESTDIR}${PREFIX}/bin/lsx + @echo installing manual pages 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" < lsx.1 > ${DESTDIR}${MANPREFIX}/man1/lsx.1 @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/lsx.1 uninstall: @echo removing executables from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_path @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run + @rm -f ${DESTDIR}${PREFIX}/bin/lsx @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 + @rm -f ${DESTDIR}${MANPREFIX}/man1/lsx.1 .PHONY: all options clean dist install uninstall diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 1b1b241..81df5ed 100755 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find $PATH ! -type d \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" + lsx $PATH | sort -u > "$CACHE" fi cat "$CACHE" diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c new file mode 100644 index 0000000..7b84acc --- /dev/null +++ b/dmenubar/lsx.c @@ -0,0 +1,43 @@ +/* See LICENSE file for copyright and license details. */ +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +static void lsx(const char *s); + +int +main(int argc, char *argv[]) { + int i; + + if(argc < 2) + lsx("."); + else if(!strcmp(argv[1], "-v")) + puts("lsx-0.2, © 2006-2011 dmenu engineers, see LICENSE for details"); + else for(i = 1; i < argc; i++) + lsx(argv[i]); + return EXIT_SUCCESS; +} + +void +lsx(const char *dir) { + char buf[PATH_MAX]; + struct dirent *d; + struct stat st; + DIR *dp; + + if(!(dp = opendir(dir))) { + perror(dir); + return; + } + while((d = readdir(dp))) { + snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name); + if(stat(buf, &st) == -1) + perror(buf); + else if(S_ISREG(st.st_mode) && access(buf, X_OK) == 0) + puts(d->d_name); + } + closedir(dp); +} From fe1bd6659c42bc518f1215a2ba1df9f5a09c33c9 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 13 Jun 2011 19:32:45 +0100 Subject: [PATCH 416/590] add lsx.1 --- dmenubar/lsx.1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 dmenubar/lsx.1 diff --git a/dmenubar/lsx.1 b/dmenubar/lsx.1 new file mode 100644 index 0000000..fbb84ea --- /dev/null +++ b/dmenubar/lsx.1 @@ -0,0 +1,15 @@ +.TH LSX 1 dmenu\-VERSION +.SH NAME +lsx \- list executables +.SH SYNOPSIS +.B lsx +.RB [ \-v ] +.RI [ directory ...] +.SH DESCRIPTION +.B lsx +lists the executables in each directory. If no directories are given the current +working directory is used. +.SH OPTIONS +.TP +.B \-v +prints version information to stdout, then exits. From f519b6c511bd593d01525cf424346bb57305dbad Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 13 Jun 2011 21:50:31 +0100 Subject: [PATCH 417/590] new dmenu_run --- dmenubar/Makefile | 6 ++---- dmenubar/dmenu.1 | 11 +++-------- dmenubar/dmenu_path | 9 --------- dmenubar/dmenu_run | 9 ++++++++- dmenubar/lsx.c | 6 ++---- 5 files changed, 15 insertions(+), 26 deletions(-) delete mode 100755 dmenubar/dmenu_path diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 34a05b6..f3f6b3d 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -35,7 +35,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} @@ -43,9 +43,8 @@ dist: clean install: all @echo installing executables to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_path dmenu_run lsx ${DESTDIR}${PREFIX}/bin + @cp -f dmenu dmenu_run lsx ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu - @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run @chmod 755 ${DESTDIR}${PREFIX}/bin/lsx @echo installing manual pages to ${DESTDIR}${MANPREFIX}/man1 @@ -58,7 +57,6 @@ install: all uninstall: @echo removing executables from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_path @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run @rm -f ${DESTDIR}${PREFIX}/bin/lsx @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 8295d17..44c953b 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -23,12 +23,10 @@ dmenu \- dynamic menu .RB [ \-v ] .P .BR dmenu_run " ..." -.P -.B dmenu_path .SH DESCRIPTION .B dmenu is a dynamic menu for X, originally designed for -.BR dwm (1). +.IR dwm (1). It manages huge numbers of user\-defined menu items efficiently. .P dmenu reads a list of newline\-separated items from stdin and creates a menu. @@ -36,11 +34,8 @@ When the user selects an item or enters any text and presses Return, their choice is printed to stdout and dmenu terminates. .P .B dmenu_run -is a dmenu script used by dwm which lists programs in the user's PATH and +is a dmenu script used by dwm which lists programs in the user's $PATH and executes the selected item. -.P -.B dmenu_path -is a script used by dmenu_run to find and cache a list of executables. .SH OPTIONS .TP .B \-b @@ -100,4 +95,4 @@ Exit without selecting an item, returning failure. .B Ctrl\-y Paste the current X selection into the input field. .SH SEE ALSO -.BR dwm (1) +.IR dwm (1) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path deleted file mode 100755 index 81df5ed..0000000 --- a/dmenubar/dmenu_path +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -CACHE=$HOME/.dmenu_cache -IFS=: - -if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - lsx $PATH | sort -u > "$CACHE" -fi - -cat "$CACHE" diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 3e1e6e4..6e96b38 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,2 +1,9 @@ #!/bin/sh -exe=`dmenu_path | dmenu ${1+"$@"}` && exec $exe +CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run +( + IFS=: + if test "`ls -dt $PATH "$CACHE" 2> /dev/null | sed 1q`" != "$CACHE"; then + mkdir -p "`dirname "$CACHE"`" && lsx $PATH | sort -u > "$CACHE" + fi +) +cmd=`dmenu "$@" < "$CACHE"` && exec $cmd diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index 7b84acc..325c508 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -6,7 +6,7 @@ #include <unistd.h> #include <sys/stat.h> -static void lsx(const char *s); +static void lsx(const char *dir); int main(int argc, char *argv[]) { @@ -34,9 +34,7 @@ lsx(const char *dir) { } while((d = readdir(dp))) { snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name); - if(stat(buf, &st) == -1) - perror(buf); - else if(S_ISREG(st.st_mode) && access(buf, X_OK) == 0) + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) puts(d->d_name); } closedir(dp); From 8afcb3f718d6dd0f3595d99ecbeb09d00336249d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 18 Jun 2011 07:50:46 +0100 Subject: [PATCH 418/590] simpler lsx --- dmenubar/dmenu.1 | 3 ++- dmenubar/lsx.1 | 10 +++------- dmenubar/lsx.c | 4 +--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 44c953b..616a2a5 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -95,4 +95,5 @@ Exit without selecting an item, returning failure. .B Ctrl\-y Paste the current X selection into the input field. .SH SEE ALSO -.IR dwm (1) +.IR dwm (1), +.IR lsx (1) diff --git a/dmenubar/lsx.1 b/dmenubar/lsx.1 index fbb84ea..1b2a15e 100644 --- a/dmenubar/lsx.1 +++ b/dmenubar/lsx.1 @@ -3,13 +3,9 @@ lsx \- list executables .SH SYNOPSIS .B lsx -.RB [ \-v ] .RI [ directory ...] .SH DESCRIPTION .B lsx -lists the executables in each directory. If no directories are given the current -working directory is used. -.SH OPTIONS -.TP -.B \-v -prints version information to stdout, then exits. +lists the executables in each +.IR directory . +If none are given the current working directory is used. diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index 325c508..fd28625 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -14,8 +14,6 @@ main(int argc, char *argv[]) { if(argc < 2) lsx("."); - else if(!strcmp(argv[1], "-v")) - puts("lsx-0.2, © 2006-2011 dmenu engineers, see LICENSE for details"); else for(i = 1; i < argc; i++) lsx(argv[i]); return EXIT_SUCCESS; @@ -34,7 +32,7 @@ lsx(const char *dir) { } while((d = readdir(dp))) { snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name); - if(stat(buf, &st) == 0 && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) + if(!stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) puts(d->d_name); } closedir(dp); From 3a23d1c57d651cf399c6eb9243b4e05dd6232931 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 18 Jun 2011 22:11:19 +0100 Subject: [PATCH 419/590] update draw.c --- dmenubar/draw.c | 27 +++++++++++++-------------- dmenubar/draw.h | 1 + 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index f952b53..2028fd9 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -120,24 +120,23 @@ initfont(DC *dc, const char *fontstr) { Bool loadfont(DC *dc, const char *fontstr) { - char *def, **missing; - int i, n; + char *def, **missing, **names; + int i, n = 1; + XFontStruct **xfonts; if(!*fontstr) return False; - if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - char **names; - XFontStruct **xfonts; - + if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = dc->font.ascent = dc->font.descent = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - } - } - else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { - dc->font.ascent = dc->font.xfont->ascent; - dc->font.descent = dc->font.xfont->descent; + else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) + xfonts = &dc->font.xfont; + else + n = 0; + + for(i = 0; i < n; i++) { + dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); + dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); + dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); } if(missing) XFreeStringList(missing); diff --git a/dmenubar/draw.h b/dmenubar/draw.h index 247c0b3..43a57bf 100644 --- a/dmenubar/draw.h +++ b/dmenubar/draw.h @@ -15,6 +15,7 @@ typedef struct { int ascent; int descent; int height; + int width; XFontSet set; XFontStruct *xfont; } font; From df31df002677bcdb105a5096f75d0da248b13548 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 23 Jun 2011 20:04:50 +0100 Subject: [PATCH 420/590] lsx: check snprintf --- dmenubar/lsx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index fd28625..e5b5c0b 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -30,10 +30,9 @@ lsx(const char *dir) { perror(dir); return; } - while((d = readdir(dp))) { - snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name); - if(!stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) + while((d = readdir(dp))) + if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < sizeof buf + && !stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) puts(d->d_name); - } closedir(dp); } From 918a4a21486e7d0d81540c9b1e9ed8ee9bce195c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 23 Jun 2011 22:39:20 +0100 Subject: [PATCH 422/590] make clean lsx --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index f3f6b3d..15a341e 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -30,7 +30,7 @@ lsx: lsx.o clean: @echo cleaning - @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dmenu lsx ${OBJ} dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball From 62c3961d3ca147f644172e26980e838d3f9c84ca Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 25 Jun 2011 17:02:14 +0100 Subject: [PATCH 423/590] include limits.h --- dmenubar/lsx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index e5b5c0b..bbe57d4 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <dirent.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> From e0b306fe87c268949d8785937b22f0bbeedffc0c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 4 Jul 2011 16:55:09 +0100 Subject: [PATCH 424/590] rebind ^N ^P --- dmenubar/config.mk | 2 +- dmenubar/dmenu.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 70c9e36..eb55470 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.3.1 +VERSION = 4.4 # paths PREFIX = /usr/local diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d03087f..9b57565 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -268,10 +268,10 @@ keypress(XKeyEvent *ev) { match(False); break; case XK_n: - ksym = XK_Down; + ksym = XK_Next; break; case XK_p: - ksym = XK_Up; + ksym = XK_Prior; break; case XK_u: /* delete left */ insert(NULL, 0 - cursor); From 4e0724a21d195addeff0bf1909b4872afa7d4f08 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 6 Jul 2011 13:40:36 +0100 Subject: [PATCH 425/590] simpler vline --- dmenubar/dmenu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9b57565..aa9254f 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -330,8 +330,7 @@ keypress(XKeyEvent *ev) { cursor = nextrune(-1); break; } - else if(lines > 0) - return; + /* fallthrough */ case XK_Up: if(sel && sel->left && (sel = sel->left)->right == curr) { curr = prev; @@ -359,8 +358,7 @@ keypress(XKeyEvent *ev) { cursor = nextrune(+1); break; } - else if(lines > 0) - return; + /* fallthrough */ case XK_Down: if(sel && sel->right && (sel = sel->right) == next) { curr = next; From ce47c914ac995a0c349c93cb4335c531777b56e7 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 14 Jul 2011 20:03:00 +0100 Subject: [PATCH 426/590] fix extra warning --- dmenubar/lsx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index bbe57d4..79b506b 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -32,7 +32,7 @@ lsx(const char *dir) { return; } while((d = readdir(dp))) - if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < sizeof buf + if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (ssize_t)sizeof buf && !stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) puts(d->d_name); closedir(dp); From 9e3a2fc2e156f991220e2127005f95a4aa84da25 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 14 Jul 2011 20:03:08 +0100 Subject: [PATCH 427/590] efficiency tweaks --- dmenubar/dmenu.c | 98 ++++++++++++++++++++---------------------------- dmenubar/draw.c | 6 +-- 2 files changed, 44 insertions(+), 60 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index aa9254f..cff3e65 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -25,8 +25,8 @@ struct Item { static void appenditem(Item *item, Item **list, Item **last); static void calcoffsets(void); +static char *cistrstr(const char *s, const char *sub); static void drawmenu(void); -static char *fstrstr(const char *s, const char *sub); static void grabkeyboard(void); static void insert(const char *str, ssize_t n); static void keypress(XKeyEvent *ev); @@ -60,6 +60,7 @@ static Item *prev, *curr, *next, *sel; static Window win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; int main(int argc, char *argv[]) { @@ -76,8 +77,10 @@ main(int argc, char *argv[]) { topbar = False; else if(!strcmp(argv[i], "-f")) fast = True; - else if(!strcmp(argv[i], "-i")) + else if(!strcmp(argv[i], "-i")) { fstrncmp = strncasecmp; + fstrstr = cistrstr; + } else if(i+1 == argc) usage(); /* double flags */ @@ -112,7 +115,7 @@ main(int argc, char *argv[]) { setup(); run(); - return EXIT_FAILURE; /* should not reach */ + return EXIT_FAILURE; /* unreachable */ } void @@ -121,6 +124,7 @@ appenditem(Item *item, Item **list, Item **last) { *list = item; else (*last)->right = item; + item->left = *last; item->right = NULL; *last = item; @@ -143,6 +147,16 @@ calcoffsets(void) { break; } +char * +cistrstr(const char *s, const char *sub) { + size_t len; + + for(len = strlen(sub); *s; s++) + if(!strncasecmp(s, sub, len)) + return (char *)s; + return NULL; +} + void drawmenu(void) { int curpos; @@ -188,16 +202,6 @@ drawmenu(void) { mapdc(dc, win, mw, mh); } -char * -fstrstr(const char *s, const char *sub) { - size_t len; - - for(len = strlen(sub); *s; s++) - if(!fstrncmp(s, sub, len)) - return (char *)s; - return NULL; -} - void grabkeyboard(void) { int i; @@ -233,58 +237,37 @@ keypress(XKeyEvent *ev) { XConvertCase(ksym, &lower, &upper); switch(lower) { - default: - return; - case XK_a: - ksym = XK_Home; - break; - case XK_b: - ksym = XK_Left; - break; - 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_h: - ksym = XK_BackSpace; - break; - case XK_i: - ksym = XK_Tab; - break; - case XK_j: - case XK_m: - ksym = XK_Return; - break; - case XK_k: /* delete right */ + case XK_a: ksym = XK_Home; break; + case XK_b: ksym = XK_Left; break; + 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_h: ksym = XK_BackSpace; break; + case XK_i: ksym = XK_Tab; break; + case XK_j: ksym = XK_Return; break; + case XK_m: ksym = XK_Return; break; + case XK_n: ksym = XK_Up; break; + case XK_p: ksym = XK_Down; break; + + case XK_k: /* delete right */ text[cursor] = '\0'; match(False); break; - case XK_n: - ksym = XK_Next; - break; - case XK_p: - ksym = XK_Prior; - break; - case XK_u: /* delete left */ + case XK_u: /* delete left */ insert(NULL, 0 - cursor); break; - case XK_w: /* delete word */ + case XK_w: /* delete word */ while(cursor > 0 && text[nextrune(-1)] == ' ') insert(NULL, nextrune(-1) - cursor); while(cursor > 0 && text[nextrune(-1)] != ' ') insert(NULL, nextrune(-1) - cursor); break; - case XK_y: /* paste selection */ + case XK_y: /* paste selection */ XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + default: + return; } } switch(ksym) { @@ -297,8 +280,9 @@ keypress(XKeyEvent *ev) { return; cursor = nextrune(+1); case XK_BackSpace: - if(cursor > 0) - insert(NULL, nextrune(-1) - cursor); + if(cursor == 0) + return; + insert(NULL, nextrune(-1) - cursor); break; case XK_End: if(text[cursor] != '\0') { @@ -351,7 +335,7 @@ keypress(XKeyEvent *ev) { break; case XK_Return: case XK_KP_Enter: - fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); exit(EXIT_SUCCESS); case XK_Right: if(text[cursor] != '\0') { @@ -468,7 +452,7 @@ run(void) { switch(ev.type) { case Expose: if(ev.xexpose.count == 0) - drawmenu(); + mapdc(dc, win, mw, mh); break; case KeyPress: keypress(&ev.xkey); diff --git a/dmenubar/draw.c b/dmenubar/draw.c index 2028fd9..d0beee8 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -96,7 +96,7 @@ initdc(void) { DC *dc; if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "no locale support\n"); + fputs("no locale support\n", stderr); if(!(dc = calloc(1, sizeof *dc))) eprintf("cannot malloc %u bytes:", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) @@ -153,10 +153,10 @@ resizedc(DC *dc, unsigned int w, unsigned int h) { if(dc->canvas) XFreePixmap(dc->dpy, dc->canvas); - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, - DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); dc->w = w; dc->h = h; + dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, + DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); } int From 7a32b27b536bc31e406db61d1d44c324143f9933 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 17 Jul 2011 14:06:53 +0100 Subject: [PATCH 428/590] tweaks --- dmenubar/dmenu.c | 1 + dmenubar/lsx.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index cff3e65..fd98d54 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -279,6 +279,7 @@ keypress(XKeyEvent *ev) { if(text[cursor] == '\0') return; cursor = nextrune(+1); + /* fallthrough */ case XK_BackSpace: if(cursor == 0) return; diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index 79b506b..f337a4a 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -3,7 +3,6 @@ #include <limits.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <unistd.h> #include <sys/stat.h> @@ -32,7 +31,7 @@ lsx(const char *dir) { return; } while((d = readdir(dp))) - if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (ssize_t)sizeof buf + if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (int)sizeof buf && !stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) puts(d->d_name); closedir(dp); From 8bcbbc9622e1241b292f38bc2409839264ee5c81 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 19 Jul 2011 21:30:09 +0100 Subject: [PATCH 429/590] add lsx.1 to dist --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 15a341e..1135d65 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -35,7 +35,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run lsx.1 ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} From 7e0953d2070cc539a6fb8c57257043629b35e325 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 19 Jul 2011 21:30:14 +0100 Subject: [PATCH 430/590] Added tag 4.4 for changeset 2b105eaae831 --- dmenubar/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags index dcceb88..c92818f 100644 --- a/dmenubar/.hgtags +++ b/dmenubar/.hgtags @@ -46,3 +46,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1 14c79f054bdf43ff3213af8e60a783192e92a018 4.3 34a2d77049a95b02f3332a0b88f9370965ebcfad 4.3.1 +2b105eaae8315b076da93056da9ecd60de5a7ac9 4.4 From 7d0843424a09f6160765baca3119b670d0f5f0e1 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 22 Jul 2011 18:16:57 +0100 Subject: [PATCH 431/590] fix loadfont --- dmenubar/draw.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/dmenubar/draw.c b/dmenubar/draw.c index d0beee8..76f0c54 100644 --- a/dmenubar/draw.c +++ b/dmenubar/draw.c @@ -121,26 +121,27 @@ initfont(DC *dc, const char *fontstr) { Bool loadfont(DC *dc, const char *fontstr) { char *def, **missing, **names; - int i, n = 1; + int i, n; XFontStruct **xfonts; if(!*fontstr) return False; - if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) + if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) - xfonts = &dc->font.xfont; - else - n = 0; - - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); + for(i = 0; i < n; i++) { + dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); + dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); + dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); + } + } + else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { + dc->font.ascent = dc->font.xfont->ascent; + dc->font.descent = dc->font.xfont->descent; + dc->font.width = dc->font.xfont->max_bounds.width; } if(missing) XFreeStringList(missing); - return (dc->font.set || dc->font.xfont); + return dc->font.set || dc->font.xfont; } void From 4ecda0a4a888d8722df68779217899311e5f3bd0 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 24 Jul 2011 20:04:58 +0100 Subject: [PATCH 432/590] dmenu_run: sh -c --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 6e96b38..2d12243 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -6,4 +6,4 @@ CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run mkdir -p "`dirname "$CACHE"`" && lsx $PATH | sort -u > "$CACHE" fi ) -cmd=`dmenu "$@" < "$CACHE"` && exec $cmd +cmd=`dmenu "$@" < "$CACHE"` && exec sh -c "$cmd" From 8ccc02c89de243272c1c3fff4019afa6422688da Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 19 Sep 2011 10:40:07 +0100 Subject: [PATCH 433/590] change version to 'hg' --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index eb55470..f66389d 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.4 +VERSION = hg # paths PREFIX = /usr/local From c35d27916adcaa88089017c067f4a1929443413f Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 19 Sep 2011 10:40:56 +0100 Subject: [PATCH 434/590] add token matching --- dmenubar/dmenu.c | 55 +++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fd98d54..2bad8d6 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -30,7 +30,7 @@ static void drawmenu(void); static void grabkeyboard(void); static void insert(const char *str, ssize_t n); static void keypress(XKeyEvent *ev); -static void match(Bool sub); +static void match(void); static size_t nextrune(int inc); static void paste(void); static void readstdin(void); @@ -120,10 +120,10 @@ main(int argc, char *argv[]) { void appenditem(Item *item, Item **list, Item **last) { - if(!*last) - *list = item; - else + if(*last) (*last)->right = item; + else + *list = item; item->left = *last; item->right = NULL; @@ -223,7 +223,7 @@ insert(const char *str, ssize_t n) { if(n > 0) memcpy(&text[cursor], str, n); cursor += n; - match(n > 0 && text[cursor] == '\0'); + match(); } void @@ -252,7 +252,7 @@ keypress(XKeyEvent *ev) { case XK_k: /* delete right */ text[cursor] = '\0'; - match(False); + match(); break; case XK_u: /* delete left */ insert(NULL, 0 - cursor); @@ -355,31 +355,42 @@ keypress(XKeyEvent *ev) { return; strncpy(text, sel->text, sizeof text); cursor = strlen(text); - match(True); + match(); break; } drawmenu(); } void -match(Bool sub) { - size_t len = strlen(text); - Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - Item *item, *lnext; +match(void) { + static char **tokv = NULL; + static int tokn = 0; - lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL; - for(item = sub ? matches : items; item && item->text; item = lnext) { - lnext = sub ? item->right : item + 1; - if(!fstrncmp(text, item->text, len + 1)) - appenditem(item, &lexact, &exactend); - else if(!fstrncmp(text, item->text, len)) + char buf[sizeof text], *s; + int i, tokc = 0; + size_t len; + Item *item, *lprefix, *lsubstr, *prefixend, *substrend; + + strcpy(buf, text); + for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) + if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) + eprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv); + len = tokc ? strlen(tokv[0]) : 0; + + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + for(item = items; item && item->text; item++) { + for(i = 0; i < tokc; i++) + if(!fstrstr(item->text, tokv[i])) + break; + if(i != tokc) + continue; + if(!tokc || !fstrncmp(tokv[0], item->text, len+1)) + appenditem(item, &matches, &matchend); + else if(!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); - else if(fstrstr(item->text, text)) + else appenditem(item, &lsubstr, &substrend); } - matches = lexact; - matchend = exactend; - if(lprefix) { if(matchend) { matchend->right = lprefix; @@ -514,7 +525,7 @@ setup(void) { } promptw = prompt ? textw(dc, prompt) : 0; inputw = MIN(inputw, mw/3); - match(False); + match(); /* menu window */ wa.override_redirect = True; From b63b137a2744df72a8857092447effbbd76ede6e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 19 Sep 2011 18:15:03 +0100 Subject: [PATCH 435/590] detect active monitor using input focus --- dmenubar/dmenu.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fd98d54..6c1407d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -473,7 +473,7 @@ void setup(void) { int x, y, screen = DefaultScreen(dc->dpy); Window root = RootWindow(dc->dpy, screen); - XSetWindowAttributes wa; + XSetWindowAttributes swa; #ifdef XINERAMA int n; XineramaScreenInfo *info; @@ -494,9 +494,14 @@ setup(void) { if((info = XineramaQueryScreens(dc->dpy, &n))) { int i, di; unsigned int du; - Window dw; + Window w, dw; + XWindowAttributes wa; - XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); + XGetInputFocus(dc->dpy, &w, &di); + if(w != root && XGetWindowAttributes(dc->dpy, w, &wa)) + XTranslateCoordinates(dc->dpy, root, root, wa.x, wa.y, &x, &y, &dw); + else + XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n-1; i++) if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; @@ -517,13 +522,13 @@ setup(void) { match(False); /* menu window */ - wa.override_redirect = True; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + swa.override_redirect = True; + swa.background_pixmap = ParentRelative; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, DefaultDepth(dc->dpy, screen), CopyFromParent, DefaultVisual(dc->dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa); XMapRaised(dc->dpy, win); resizedc(dc, mw, mh); From a2afffca82c639bb59ada49b2c0e5f6fbd324908 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 20 Sep 2011 00:06:13 +0100 Subject: [PATCH 436/590] update manpage --- dmenubar/dmenu.1 | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 616a2a5..7243a36 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -25,13 +25,10 @@ dmenu \- dynamic menu .BR dmenu_run " ..." .SH DESCRIPTION .B dmenu -is a dynamic menu for X, originally designed for -.IR dwm (1). -It manages huge numbers of user\-defined menu items efficiently. -.P -dmenu reads a list of newline\-separated items from stdin and creates a menu. -When the user selects an item or enters any text and presses Return, their -choice is printed to stdout and dmenu terminates. +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 dmenu script used by dwm which lists programs in the user's $PATH and @@ -42,8 +39,8 @@ executes the selected item. dmenu appears at the bottom of the screen. .TP .B \-f -dmenu grabs the keyboard before reading stdin. This is faster, but may lock up -X if stdin is from a terminal. +dmenu grabs the keyboard before reading stdin. This is faster, but will lock up +X until stdin reaches end\-of\-file. .TP .B \-i dmenu matches menu items case insensitively. From bc8d75a8854d62b5822089000cf8fb844ef78ea8 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 20 Sep 2011 00:09:20 +0100 Subject: [PATCH 437/590] tweak match --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 2bad8d6..1cd9f61 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -392,7 +392,7 @@ match(void) { appenditem(item, &lsubstr, &substrend); } if(lprefix) { - if(matchend) { + if(matches) { matchend->right = lprefix; lprefix->left = matchend; } @@ -401,7 +401,7 @@ match(void) { matchend = prefixend; } if(lsubstr) { - if(matchend) { + if(matches) { matchend->right = lsubstr; lsubstr->left = matchend; } From 9d8b545ed42262289b68cdc795991862423acb15 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 30 Sep 2011 21:08:37 +0100 Subject: [PATCH 438/590] fix monitor select when no focus --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9d479f9..458f5ab 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -509,7 +509,7 @@ setup(void) { XWindowAttributes wa; XGetInputFocus(dc->dpy, &w, &di); - if(w != root && XGetWindowAttributes(dc->dpy, w, &wa)) + if(w != root && w != PointerRoot && w != None && XGetWindowAttributes(dc->dpy, w, &wa)) XTranslateCoordinates(dc->dpy, root, root, wa.x, wa.y, &x, &y, &dw); else XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); From f90d89fd386433f99cd10a9e057f353532e1b97a Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 4 Oct 2011 21:39:56 +0100 Subject: [PATCH 439/590] input focus: fix for reparenting wms --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 458f5ab..5d11932 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -510,7 +510,7 @@ setup(void) { XGetInputFocus(dc->dpy, &w, &di); if(w != root && w != PointerRoot && w != None && XGetWindowAttributes(dc->dpy, w, &wa)) - XTranslateCoordinates(dc->dpy, root, root, wa.x, wa.y, &x, &y, &dw); + XTranslateCoordinates(dc->dpy, w, root, wa.x, wa.y, &x, &y, &dw); else XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n-1; i++) From 6a5bcd6ac9d290344d8b82f385d5a18e51529375 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Thu, 13 Oct 2011 20:43:59 +0100 Subject: [PATCH 440/590] limit lines to input --- dmenubar/dmenu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5d11932..f105b56 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -454,6 +454,7 @@ readstdin(void) { if(items) items[i].text = NULL; inputw = maxstr ? textw(dc, maxstr) : 0; + lines = MIN(lines, i); } void From 07e68d6f0f86f2b233ec16a30d6d7b17653e3989 Mon Sep 17 00:00:00 2001 From: Troels Henriksen <athas@sigkill.dk> Date: Sun, 16 Oct 2011 17:21:33 +0100 Subject: [PATCH 441/590] add xim support --- dmenubar/dmenu.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f105b56..6d1cdf0 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -58,6 +58,7 @@ static Item *items = NULL; static Item *matches, *matchend; static Item *prev, *curr, *next, *sel; static Window win; +static XIC xic; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; @@ -230,8 +231,10 @@ void keypress(XKeyEvent *ev) { char buf[32]; KeySym ksym; + int len; + Status status; - XLookupString(ev, buf, sizeof buf, &ksym, NULL); + len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status); if(ev->state & ControlMask) { KeySym lower, upper; @@ -273,7 +276,7 @@ keypress(XKeyEvent *ev) { switch(ksym) { default: if(!iscntrl(*buf)) - insert(buf, strlen(buf)); + insert(buf, len); break; case XK_Delete: if(text[cursor] == '\0') @@ -461,7 +464,9 @@ void run(void) { XEvent ev; - while(!XNextEvent(dc->dpy, &ev)) + while(!XNextEvent(dc->dpy, &ev)) { + if(XFilterEvent(&ev, win)) + continue; switch(ev.type) { case Expose: if(ev.xexpose.count == 0) @@ -479,6 +484,7 @@ run(void) { XRaiseWindow(dc->dpy, win); break; } + } } void @@ -486,6 +492,7 @@ setup(void) { int x, y, screen = DefaultScreen(dc->dpy); Window root = RootWindow(dc->dpy, screen); XSetWindowAttributes swa; + XIM xim; #ifdef XINERAMA int n; XineramaScreenInfo *info; @@ -542,6 +549,11 @@ setup(void) { DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa); + /* input methods */ + xim = XOpenIM(dc->dpy, NULL, NULL, NULL); + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, win, XNFocusWindow, win, NULL); + XMapRaised(dc->dpy, win); resizedc(dc, mw, mh); drawmenu(); From 1b6f9f9451f7f4c187ed20d00f093cbcc7b0488d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 16 Oct 2011 18:14:51 +0100 Subject: [PATCH 442/590] lsx: return failure on error --- dmenubar/lsx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index f337a4a..57c03bf 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -8,6 +8,8 @@ static void lsx(const char *dir); +static int status = EXIT_SUCCESS; + int main(int argc, char *argv[]) { int i; @@ -16,7 +18,7 @@ main(int argc, char *argv[]) { lsx("."); else for(i = 1; i < argc; i++) lsx(argv[i]); - return EXIT_SUCCESS; + return status; } void @@ -27,12 +29,13 @@ lsx(const char *dir) { DIR *dp; if(!(dp = opendir(dir))) { + status = EXIT_FAILURE; perror(dir); return; } while((d = readdir(dp))) if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (int)sizeof buf - && !stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) + && stat(buf, &st) == 0 && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) puts(d->d_name); closedir(dp); } From e77544e1c877e29e5efe8943f08b8c843e7905ab Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 16 Oct 2011 18:26:11 +0100 Subject: [PATCH 443/590] fix extra warning --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f105b56..dc1f236 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -41,7 +41,6 @@ static void usage(void); static char text[BUFSIZ] = ""; static int bh, mw, mh; static int inputw, promptw; -static int lines = 0; static size_t cursor = 0; static const char *font = NULL; static const char *prompt = NULL; @@ -49,6 +48,7 @@ static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; +static unsigned int lines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; From bdd88fb054e046cefebdf2f19656b5e345015cc1 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 17 Oct 2011 01:18:57 +0100 Subject: [PATCH 444/590] xim: check for corner cases --- dmenubar/dmenu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6d1cdf0..895542d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -230,11 +230,13 @@ insert(const char *str, ssize_t n) { void keypress(XKeyEvent *ev) { char buf[32]; - KeySym ksym; int len; + KeySym ksym = NoSymbol; Status status; - len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status); + len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); + if(status == XBufferOverflow) + return; if(ev->state & ControlMask) { KeySym lower, upper; @@ -549,10 +551,10 @@ setup(void) { DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa); - /* input methods */ + /* input methods */ xim = XOpenIM(dc->dpy, NULL, NULL, NULL); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, win, XNFocusWindow, win, NULL); + XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dc->dpy, win); resizedc(dc, mw, mh); From 19a37c60e36d1d2a968f4e3333e8e0eefdbcc5bf Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 17 Oct 2011 01:44:07 +0100 Subject: [PATCH 445/590] lsx: detect read errors --- dmenubar/lsx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c index 57c03bf..cb016cf 100644 --- a/dmenubar/lsx.c +++ b/dmenubar/lsx.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <dirent.h> +#include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -28,14 +29,15 @@ lsx(const char *dir) { struct stat st; DIR *dp; - if(!(dp = opendir(dir))) { + for(dp = opendir(dir); dp && (d = readdir(dp)); errno = 0) + if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (int)sizeof buf + && access(buf, X_OK) == 0 && stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + puts(d->d_name); + + if(errno != 0) { status = EXIT_FAILURE; perror(dir); - return; } - while((d = readdir(dp))) - if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (int)sizeof buf - && stat(buf, &st) == 0 && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) - puts(d->d_name); - closedir(dp); + if(dp) + closedir(dp); } From 240b06fd91c8028e012240828e32ab0246b8e7aa Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 17 Oct 2011 02:12:33 +0100 Subject: [PATCH 446/590] use ~/.dmenu_cache if no xdg cache --- dmenubar/dmenu_run | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 2d12243..21dc72b 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,9 +1,12 @@ #!/bin/sh CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run +if [ ! -d "`dirname "$CACHE"`" ]; then + CACHE=$HOME/.dmenu_cache +fi ( IFS=: if test "`ls -dt $PATH "$CACHE" 2> /dev/null | sed 1q`" != "$CACHE"; then - mkdir -p "`dirname "$CACHE"`" && lsx $PATH | sort -u > "$CACHE" + lsx $PATH | sort -u > "$CACHE" fi ) cmd=`dmenu "$@" < "$CACHE"` && exec sh -c "$cmd" From 68ec7d0fc0acef863ed2a899e7505b1cd85681ef Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 17 Oct 2011 10:22:23 +0100 Subject: [PATCH 447/590] simplify dmenu_run --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 21dc72b..2747919 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -5,7 +5,7 @@ if [ ! -d "`dirname "$CACHE"`" ]; then fi ( IFS=: - if test "`ls -dt $PATH "$CACHE" 2> /dev/null | sed 1q`" != "$CACHE"; then + if [ "`ls -dt $PATH "$CACHE" | head -n 1`" != "$CACHE" ]; then lsx $PATH | sort -u > "$CACHE" fi ) From 04ccbaceb226e9e39af91f282202dd180efd6cd5 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 26 Oct 2011 12:14:50 +0100 Subject: [PATCH 448/590] input focus: calculate areas of intersection --- dmenubar/dmenu.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 671095e..841af4a 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -13,9 +13,10 @@ #endif #include "draw.h" -#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#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 MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) typedef struct Item Item; struct Item { @@ -513,19 +514,28 @@ setup(void) { mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { - int i, di; + int a, j, di, i = 0, area = 0; unsigned int du; - Window w, dw; + Window w, pw, dw, *dws; XWindowAttributes wa; XGetInputFocus(dc->dpy, &w, &di); - if(w != root && w != PointerRoot && w != None && XGetWindowAttributes(dc->dpy, w, &wa)) - XTranslateCoordinates(dc->dpy, w, root, wa.x, wa.y, &x, &y, &dw); - else - XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); - for(i = 0; i < n-1; i++) - if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) - break; + if(w != root && w != PointerRoot && w != None) { + do { + if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) + XFree(dws); + } while(w != root && w != pw); + if(XGetWindowAttributes(dc->dpy, pw, &wa)) + for(j = 0; j < n; j++) + if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { + area = a; + i = j; + } + } + if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + for(i = 0; i < n; i++) + if(INTERSECT(x, y, 1, 1, info[i])) + break; x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; From fdd4605f65abcd34e994904fc88e81ec95fed6be Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 26 Oct 2011 13:20:14 +0100 Subject: [PATCH 449/590] add lots of comments --- dmenubar/dmenu.c | 51 +++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 841af4a..5e01441 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -70,35 +70,35 @@ main(int argc, char *argv[]) { int i; for(i = 1; i < argc; i++) - /* single flags */ - if(!strcmp(argv[i], "-v")) { + /* these options take no arguments */ + if(!strcmp(argv[i], "-v")) { /* prints version information */ puts("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details"); exit(EXIT_SUCCESS); } - else if(!strcmp(argv[i], "-b")) + else if(!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ topbar = False; - else if(!strcmp(argv[i], "-f")) + else if(!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = True; - else if(!strcmp(argv[i], "-i")) { + else if(!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; } else if(i+1 == argc) usage(); - /* double flags */ - else if(!strcmp(argv[i], "-l")) + /* these options take one argument */ + else if(!strcmp(argv[i], "-l")) /* number of lines in vertical list */ lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-p")) + else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; - else if(!strcmp(argv[i], "-fn")) + else if(!strcmp(argv[i], "-fn")) /* font or font set */ font = argv[++i]; - else if(!strcmp(argv[i], "-nb")) + else if(!strcmp(argv[i], "-nb")) /* normal background color */ normbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-nf")) + else if(!strcmp(argv[i], "-nf")) /* normal foreground color */ normfgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sb")) + else if(!strcmp(argv[i], "-sb")) /* selected background color */ selbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sf")) + else if(!strcmp(argv[i], "-sf")) /* selected foreground color */ selfgcolor = argv[++i]; else usage(); @@ -140,7 +140,7 @@ calcoffsets(void) { n = lines * bh; else n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); - + /* calculate which items will begin the next page and previous page */ for(i = 0, next = curr; next; next = next->right) if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), n)) > n) break; @@ -174,12 +174,14 @@ drawmenu(void) { drawtext(dc, prompt, selcol); dc->x = dc->w; } + /* draw input field */ dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; drawtext(dc, text, normcol); if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); if(lines > 0) { + /* draw vertical list */ dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; @@ -187,6 +189,7 @@ drawmenu(void) { } } else if(matches) { + /* draw horizontal list */ dc->x += inputw; dc->w = textw(dc, "<"); if(curr->left) @@ -208,6 +211,7 @@ void grabkeyboard(void) { int i; + /* try to grab keyboard, we may have to wait for another process to ungrab */ for(i = 0; i < 1000; i++) { if(XGrabKeyboard(dc->dpy, DefaultRootWindow(dc->dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) @@ -221,6 +225,7 @@ void insert(const char *str, ssize_t n) { if(strlen(text) + n > sizeof text - 1) return; + /* 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); @@ -297,6 +302,7 @@ keypress(XKeyEvent *ev) { break; } if(next) { + /* jump to end of list and position items in reverse */ curr = matchend; calcoffsets(); curr = prev; @@ -378,6 +384,7 @@ match(void) { Item *item, *lprefix, *lsubstr, *prefixend, *substrend; strcpy(buf, text); + /* separate input text into tokens to be matched individually */ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) eprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv); @@ -388,8 +395,9 @@ match(void) { for(i = 0; i < tokc; i++) if(!fstrstr(item->text, tokv[i])) break; - if(i != tokc) + if(i != tokc) /* not all tokens match */ continue; + /* exact matches go first, then prefixes, then substrings */ if(!tokc || !fstrncmp(tokv[0], item->text, len+1)) appenditem(item, &matches, &matchend); else if(!fstrncmp(tokv[0], item->text, len)) @@ -423,6 +431,7 @@ size_t nextrune(int inc) { ssize_t n; + /* return location of next utf8 rune in the given direction (+1 or -1) */ for(n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc); return n; } @@ -434,6 +443,7 @@ paste(void) { unsigned long dl; Atom da; + /* we have been given the current selection, now insert it into input */ XGetWindowProperty(dc->dpy, win, utf8, 0, (sizeof text / 4) + 1, False, utf8, &da, &di, &dl, &dl, (unsigned char **)&p); insert(p, (q = strchr(p, '\n')) ? q-p : (ssize_t)strlen(p)); @@ -446,6 +456,7 @@ readstdin(void) { char buf[sizeof text], *p, *maxstr = NULL; size_t i, max = 0, size = 0; + /* 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) if(!(items = realloc(items, (size += BUFSIZ)))) @@ -508,7 +519,7 @@ setup(void) { utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - /* menu geometry */ + /* calculate menu geometry */ bh = dc->font.height + 2; lines = MAX(lines, 0); mh = (lines + 1) * bh; @@ -521,10 +532,12 @@ setup(void) { XGetInputFocus(dc->dpy, &w, &di); if(w != root && w != PointerRoot && w != None) { + /* find top-level window containing current input focus */ do { if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) XFree(dws); } while(w != root && w != pw); + /* find xinerama screen with which the window intersects most */ if(XGetWindowAttributes(dc->dpy, pw, &wa)) for(j = 0; j < n; j++) if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { @@ -532,10 +545,12 @@ setup(void) { i = j; } } + /* no focused window is on screen, so use pointer location instead */ if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for(i = 0; i < n; i++) if(INTERSECT(x, y, 1, 1, info[i])) break; + x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; @@ -552,7 +567,7 @@ setup(void) { inputw = MIN(inputw, mw/3); match(); - /* menu window */ + /* create menu window */ swa.override_redirect = True; swa.background_pixmap = ParentRelative; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; @@ -561,7 +576,7 @@ setup(void) { DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa); - /* input methods */ + /* open input methods */ xim = XOpenIM(dc->dpy, NULL, NULL, NULL); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); From f0a09bc70d23bc9d8f8f960a606be4b4fb302f0a Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 26 Oct 2011 13:28:15 +0100 Subject: [PATCH 450/590] add paste from clipboard --- dmenubar/dmenu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5e01441..3f48d30 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -52,7 +52,7 @@ static const char *selfgcolor = "#ffffff"; static unsigned int lines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; -static Atom utf8; +static Atom clip, utf8; static Bool topbar = True; static DC *dc; static Item *items = NULL; @@ -275,7 +275,8 @@ keypress(XKeyEvent *ev) { insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ - XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); + XConvertSelection(dc->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, + utf8, utf8, win, CurrentTime); return; default: return; @@ -517,6 +518,7 @@ setup(void) { selcol[ColBG] = getcolor(dc, selbgcolor); selcol[ColFG] = getcolor(dc, selfgcolor); + clip = XInternAtom(dc->dpy, "CLIPBOARD", False); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); /* calculate menu geometry */ From 1ff6048402cc8eccfa893550941472f0b539ce47 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 26 Oct 2011 14:16:12 +0100 Subject: [PATCH 451/590] makefile: *.o depend on draw.h --- dmenubar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 1135d65..929b108 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -18,7 +18,7 @@ options: @echo CC -c $< @${CC} -c $< ${CFLAGS} -${OBJ}: config.mk +${OBJ}: config.mk draw.h dmenu: dmenu.o draw.o @echo CC -o $@ From 235950275753c262659ff354d0966d8124f20499 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 14 Nov 2011 00:46:56 +0100 Subject: [PATCH 452/590] new default colour scheme --- dmenubar/dmenu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3f48d30..f71b056 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -45,10 +45,10 @@ static int inputw, promptw; static size_t cursor = 0; static const char *font = NULL; static const char *prompt = NULL; -static const char *normbgcolor = "#cccccc"; -static const char *normfgcolor = "#000000"; -static const char *selbgcolor = "#0066ff"; -static const char *selfgcolor = "#ffffff"; +static const char *normbgcolor = "#222222"; +static const char *normfgcolor = "#bbbbbb"; +static const char *selbgcolor = "#005577"; +static const char *selfgcolor = "#eeeeee"; static unsigned int lines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; From e6a86af5e1b776ee5fbee176244f9a04ef352014 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 14 Nov 2011 20:02:16 +0100 Subject: [PATCH 453/590] fix C-n / C-p directions (thanks bastien) --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f71b056..d0e27da 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -258,8 +258,8 @@ keypress(XKeyEvent *ev) { case XK_i: ksym = XK_Tab; break; case XK_j: ksym = XK_Return; break; case XK_m: ksym = XK_Return; break; - case XK_n: ksym = XK_Up; break; - case XK_p: ksym = XK_Down; break; + case XK_n: ksym = XK_Down; break; + case XK_p: ksym = XK_Up; break; case XK_k: /* delete right */ text[cursor] = '\0'; From 0f02fab14501519b58f87a9f2af6b5b4e62ce9d6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Tue, 15 Nov 2011 20:32:39 +0100 Subject: [PATCH 454/590] limit direction keys in vline --- dmenubar/dmenu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d0e27da..99db24e 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -328,6 +328,8 @@ keypress(XKeyEvent *ev) { cursor = nextrune(-1); break; } + if(lines > 0) + return; /* fallthrough */ case XK_Up: if(sel && sel->left && (sel = sel->left)->right == curr) { @@ -356,6 +358,8 @@ keypress(XKeyEvent *ev) { cursor = nextrune(+1); break; } + if(lines > 0) + return; /* fallthrough */ case XK_Down: if(sel && sel->right && (sel = sel->right) == next) { From cf719ccccb23d1db71c85855c1a2f4a483461f96 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 16 Nov 2011 11:26:15 +0100 Subject: [PATCH 455/590] update manpage --- dmenubar/dmenu.1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 7243a36..5f74463 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -31,8 +31,9 @@ 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 dmenu script used by dwm which lists programs in the user's $PATH and -executes the selected item. +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and executes the selected item. .SH OPTIONS .TP .B \-b @@ -90,7 +91,10 @@ Confirm input. Prints the input text to stdout and exits, returning success. Exit without selecting an item, returning failure. .TP .B Ctrl\-y -Paste the current X selection into the input field. +Paste the primary X selection into the input field. +.TP +.B Ctrl-Shift-y +Paste the X clipboard into the input field. .SH SEE ALSO .IR dwm (1), .IR lsx (1) From de04dff5d5f88304b851f67149f1a63fdb2930b3 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 19 Nov 2011 19:54:55 +0100 Subject: [PATCH 456/590] replace lsx with stest --- dmenubar/Makefile | 24 ++++++------- dmenubar/config.mk | 2 +- dmenubar/dmenu_run | 6 ++-- dmenubar/lsx.1 | 11 ------ dmenubar/lsx.c | 43 ----------------------- dmenubar/stest.1 | 87 ++++++++++++++++++++++++++++++++++++++++++++++ dmenubar/stest.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 189 insertions(+), 69 deletions(-) delete mode 100644 dmenubar/lsx.1 delete mode 100644 dmenubar/lsx.c create mode 100644 dmenubar/stest.1 create mode 100644 dmenubar/stest.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 929b108..c127f6a 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,10 +3,10 @@ include config.mk -SRC = dmenu.c draw.c lsx.c +SRC = dmenu.c draw.c stest.c OBJ = ${SRC:.c=.o} -all: options dmenu lsx +all: options dmenu stest options: @echo dmenu build options: @@ -24,18 +24,18 @@ dmenu: dmenu.o draw.o @echo CC -o $@ @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} -lsx: lsx.o +stest: stest.o @echo CC -o $@ - @${CC} -o $@ lsx.o ${LDFLAGS} + @${CC} -o $@ stest.o ${LDFLAGS} clean: @echo cleaning - @rm -f dmenu lsx ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dmenu stest ${OBJ} dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run lsx.1 ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run stest.1 ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} @@ -43,24 +43,24 @@ dist: clean install: all @echo installing executables to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_run lsx ${DESTDIR}${PREFIX}/bin + @cp -f dmenu dmenu_run stest ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run - @chmod 755 ${DESTDIR}${PREFIX}/bin/lsx + @chmod 755 ${DESTDIR}${PREFIX}/bin/stest @echo installing manual pages 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" < lsx.1 > ${DESTDIR}${MANPREFIX}/man1/lsx.1 + @sed "s/VERSION/${VERSION}/g" < stest.1 > ${DESTDIR}${MANPREFIX}/man1/stest.1 @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/lsx.1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/stest.1 uninstall: @echo removing executables from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run - @rm -f ${DESTDIR}${PREFIX}/bin/lsx + @rm -f ${DESTDIR}${PREFIX}/bin/stest @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 - @rm -f ${DESTDIR}${MANPREFIX}/man1/lsx.1 + @rm -f ${DESTDIR}${MANPREFIX}/man1/stest.1 .PHONY: all options clean dist install uninstall diff --git a/dmenubar/config.mk b/dmenubar/config.mk index f66389d..87a87f9 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -17,7 +17,7 @@ INCS = -I${X11INC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 2747919..a15df0f 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -5,8 +5,10 @@ if [ ! -d "`dirname "$CACHE"`" ]; then fi ( IFS=: - if [ "`ls -dt $PATH "$CACHE" | head -n 1`" != "$CACHE" ]; then - lsx $PATH | sort -u > "$CACHE" + if ls -d $PATH | stest -q -n "$CACHE"; then + for dir in $PATH; do + ls $dir | stest -C $dir -fx + done | sort -u > "$CACHE" fi ) cmd=`dmenu "$@" < "$CACHE"` && exec sh -c "$cmd" diff --git a/dmenubar/lsx.1 b/dmenubar/lsx.1 deleted file mode 100644 index 1b2a15e..0000000 --- a/dmenubar/lsx.1 +++ /dev/null @@ -1,11 +0,0 @@ -.TH LSX 1 dmenu\-VERSION -.SH NAME -lsx \- list executables -.SH SYNOPSIS -.B lsx -.RI [ directory ...] -.SH DESCRIPTION -.B lsx -lists the executables in each -.IR directory . -If none are given the current working directory is used. diff --git a/dmenubar/lsx.c b/dmenubar/lsx.c deleted file mode 100644 index cb016cf..0000000 --- a/dmenubar/lsx.c +++ /dev/null @@ -1,43 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <dirent.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/stat.h> - -static void lsx(const char *dir); - -static int status = EXIT_SUCCESS; - -int -main(int argc, char *argv[]) { - int i; - - if(argc < 2) - lsx("."); - else for(i = 1; i < argc; i++) - lsx(argv[i]); - return status; -} - -void -lsx(const char *dir) { - char buf[PATH_MAX]; - struct dirent *d; - struct stat st; - DIR *dp; - - for(dp = opendir(dir); dp && (d = readdir(dp)); errno = 0) - if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (int)sizeof buf - && access(buf, X_OK) == 0 && stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - puts(d->d_name); - - if(errno != 0) { - status = EXIT_FAILURE; - perror(dir); - } - if(dp) - closedir(dp); -} diff --git a/dmenubar/stest.1 b/dmenubar/stest.1 new file mode 100644 index 0000000..cafd4bb --- /dev/null +++ b/dmenubar/stest.1 @@ -0,0 +1,87 @@ +.TH STEST 1 dmenu\-VERSION +.SH NAME +stest \- filter a list of files by properties +.SH SYNOPSIS +.B stest +.RB [ -bcdefghpqrsuwx ] +.RB [ -C +.IR dir ] +.RB [ -n +.IR file ] +.RB [ -o +.IR file ] +.RI [ file ...] +.SH DESCRIPTION +.B stest +takes a list of files and filters by the files' properties, analogous to +.IR test (1). +Files which pass all tests are printed to stdout. If no files are given as +arguments, stest will read a list of files from stdin, one path per line. +.SH OPTIONS +.TP +.BI \-C " dir" +Tests files relative to directory +.IR dir . +.TP +.B \-b +Test that files are block specials. +.TP +.B \-c +Test that files are character specials. +.TP +.B \-d +Test that files are directories. +.TP +.B \-e +Test that files exist. +.TP +.B \-f +Test that files are regular files. +.TP +.B \-g +Test that files have their set-group-ID flag set. +.TP +.B \-h +Test that files are symbolic links. +.TP +.BI \-n " file" +Test that files are newer than +.IR file . +.TP +.BI \-o " file" +Test that files are older than +.IR file . +.TP +.B \-p +Test that files are named pipes. +.TP +.B \-q +No files are printed, only the exit status is returned. +.TP +.B \-r +Test that files are readable. +.TP +.B \-s +Test that files are not empty. +.TP +.B \-u +Test that files have their set-user-ID flag set. +.TP +.B \-w +Test that files are writable. +.TP +.B \-x +Test that files are executable. +.SH EXIT STATUS +.TP +.B 0 +At least one file passed all tests. +.TP +.B 1 +No files passed all tests. +.TP +.B 2 +An error occurred. +.SH SEE ALSO +.IR dmenu (1), +.IR test (1) diff --git a/dmenubar/stest.c b/dmenubar/stest.c new file mode 100644 index 0000000..a5596ea --- /dev/null +++ b/dmenubar/stest.c @@ -0,0 +1,85 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +#define OPER(x) (oper[(x)-'a']) + +static bool test(const char *); + +static bool quiet = false; +static bool oper[26]; +static struct stat old, new; + +int +main(int argc, char *argv[]) { + char buf[BUFSIZ], *p; + bool match = false; + int opt; + + while((opt = getopt(argc, argv, "C:bcdefghn:o:pqrsuwx")) != -1) + switch(opt) { + case 'C': /* tests relative to directory */ + if(chdir(optarg) == -1) { + perror(optarg); + exit(2); + } + break; + case 'n': /* newer than file */ + case 'o': /* older than file */ + if(!(OPER(opt) = stat(optarg, (opt == 'n' ? &new : &old)) == 0)) + perror(optarg); + break; + case 'q': /* quiet (no output, just status) */ + quiet = true; + break; + default: /* miscellaneous operators */ + OPER(opt) = true; + break; + case '?': /* error: unknown flag */ + fprintf(stderr, "usage: %s [-bcdefghpqrsuwx] [-C dir] [-n file] [-o file] [file...]\n", argv[0]); + exit(2); + } + if(optind == argc) + while(fgets(buf, sizeof buf, stdin)) { + if(*(p = &buf[strlen(buf)-1]) == '\n') + *p = '\0'; + match |= test(buf); + } + else + while(optind < argc) + match |= test(argv[optind++]); + + return match ? 0 : 1; +} + +bool +test(const char *path) { + struct stat st; + + if((!OPER('b') || (stat(path, &st) == 0 && S_ISBLK(st.st_mode))) /* block special */ + && (!OPER('c') || (stat(path, &st) == 0 && S_ISCHR(st.st_mode))) /* character special */ + && (!OPER('d') || (stat(path, &st) == 0 && S_ISDIR(st.st_mode))) /* directory */ + && (!OPER('e') || (access(path, F_OK) == 0)) /* exists */ + && (!OPER('f') || (stat(path, &st) == 0 && S_ISREG(st.st_mode))) /* regular file */ + && (!OPER('g') || (stat(path, &st) == 0 && (st.st_mode & S_ISGID))) /* set-group-id flag */ + && (!OPER('h') || (lstat(path, &st) == 0 && S_ISLNK(st.st_mode))) /* symbolic link */ + && (!OPER('n') || (stat(path, &st) == 0 && st.st_mtime > new.st_mtime)) /* newer than file */ + && (!OPER('o') || (stat(path, &st) == 0 && st.st_mtime < old.st_mtime)) /* older than file */ + && (!OPER('p') || (stat(path, &st) == 0 && S_ISFIFO(st.st_mode))) /* named pipe */ + && (!OPER('r') || (access(path, R_OK) == 0)) /* readable */ + && (!OPER('s') || (stat(path, &st) == 0 && st.st_size > 0)) /* not empty */ + && (!OPER('u') || (stat(path, &st) == 0 && (st.st_mode & S_ISUID))) /* set-user-id flag */ + && (!OPER('w') || (access(path, W_OK) == 0)) /* writable */ + && (!OPER('x') || (access(path, X_OK) == 0))) { /* executable */ + if(quiet) + exit(0); + puts(path); + return true; + } + else + return false; +} From 9edfe41b9d96aa2d1d8b7fc943d3b9cc860f15be Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 19 Nov 2011 21:24:07 +0100 Subject: [PATCH 457/590] faster dmenu_run -f --- dmenubar/dmenu.c | 2 +- dmenubar/dmenu_run | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 99db24e..a5af9d5 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -117,7 +117,7 @@ main(int argc, char *argv[]) { setup(); run(); - return EXIT_FAILURE; /* unreachable */ + return 1; /* unreachable */ } void diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 2747919..cf75b0a 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,12 +1,15 @@ #!/bin/sh -CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run -if [ ! -d "`dirname "$CACHE"`" ]; then - CACHE=$HOME/.dmenu_cache +cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"} +if [ -d "$cachedir" ]; then + cache=$cachedir/dmenu_run +else + cache=$HOME/.dmenu_cache fi ( IFS=: - if [ "`ls -dt $PATH "$CACHE" | head -n 1`" != "$CACHE" ]; then - lsx $PATH | sort -u > "$CACHE" + if [ "`ls -dt $PATH "$cache" | head -n 1`" != "$cache" ]; then + lsx $PATH | sort -u | tee "$cache" | dmenu "$@" + else + dmenu "$@" < "$cache" fi -) -cmd=`dmenu "$@" < "$CACHE"` && exec sh -c "$cmd" +) | read cmd && exec sh -c "$cmd" From 0f7ffd38a50fac16a491b35f5381a4e94d06af3c Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sat, 19 Nov 2011 21:31:18 +0100 Subject: [PATCH 458/590] fix dmenu_path exec sh --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index cf75b0a..3279aa8 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -12,4 +12,4 @@ fi else dmenu "$@" < "$cache" fi -) | read cmd && exec sh -c "$cmd" +) | exec sh From e8e70769d418b42dc38a1de05fd708946f60714d Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Nov 2011 14:40:21 +0100 Subject: [PATCH 459/590] set window background_pixel --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a5af9d5..019fa3e 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -575,12 +575,12 @@ setup(void) { /* create menu window */ swa.override_redirect = True; - swa.background_pixmap = ParentRelative; + swa.background_pixel = normcol[ColBG]; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, DefaultDepth(dc->dpy, screen), CopyFromParent, DefaultVisual(dc->dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa); + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); /* open input methods */ xim = XOpenIM(dc->dpy, NULL, NULL, NULL); From 3503bfba6540c361b9167bb1b7d6f8d54235d6fa Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 23 Nov 2011 15:17:32 +0100 Subject: [PATCH 460/590] dmenu_run: use $SHELL --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 3279aa8..35a4db3 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -12,4 +12,4 @@ fi else dmenu "$@" < "$cache" fi -) | exec sh +) | exec ${SHELL:-"/bin/sh"} From a8ee2aa230a5a8ffb1d747cd85b5006876248220 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 27 Nov 2011 23:35:09 +0100 Subject: [PATCH 461/590] simplify stest --- dmenubar/dmenu_run | 6 +-- dmenubar/stest.1 | 15 ++++---- dmenubar/stest.c | 94 ++++++++++++++++++++++------------------------ 3 files changed, 53 insertions(+), 62 deletions(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index a15df0f..e0a3e13 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -5,10 +5,8 @@ if [ ! -d "`dirname "$CACHE"`" ]; then fi ( IFS=: - if ls -d $PATH | stest -q -n "$CACHE"; then - for dir in $PATH; do - ls $dir | stest -C $dir -fx - done | sort -u > "$CACHE" + if stest -dqr -n "$CACHE" $PATH; then + stest -flx $PATH | sort -u > "$CACHE" fi ) cmd=`dmenu "$@" < "$CACHE"` && exec sh -c "$cmd" diff --git a/dmenubar/stest.1 b/dmenubar/stest.1 index cafd4bb..1f590ec 100644 --- a/dmenubar/stest.1 +++ b/dmenubar/stest.1 @@ -3,9 +3,7 @@ stest \- filter a list of files by properties .SH SYNOPSIS .B stest -.RB [ -bcdefghpqrsuwx ] -.RB [ -C -.IR dir ] +.RB [ -abcdefghlpqrsuwx ] .RB [ -n .IR file ] .RB [ -o @@ -15,13 +13,11 @@ stest \- filter a list of files by properties .B stest takes a list of files and filters by the files' properties, analogous to .IR test (1). -Files which pass all tests are printed to stdout. If no files are given as -arguments, stest will read a list of files from stdin, one path per line. +Files which pass all tests are printed to stdout. .SH OPTIONS .TP -.BI \-C " dir" -Tests files relative to directory -.IR dir . +.B \-a +Test hidden files. .TP .B \-b Test that files are block specials. @@ -44,6 +40,9 @@ Test that files have their set-group-ID flag set. .B \-h Test that files are symbolic links. .TP +.B \-l +Test the contents of a directory given as an argument. +.TP .BI \-n " file" Test that files are newer than .IR file . diff --git a/dmenubar/stest.c b/dmenubar/stest.c index a5596ea..e75d321 100644 --- a/dmenubar/stest.c +++ b/dmenubar/stest.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#include <dirent.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -6,80 +7,73 @@ #include <unistd.h> #include <sys/stat.h> -#define OPER(x) (oper[(x)-'a']) +#define FLAG(x) (flag[(x)-'a']) -static bool test(const char *); +static void test(const char *, const char *); -static bool quiet = false; -static bool oper[26]; +static bool match = false; +static bool flag[26]; static struct stat old, new; int main(int argc, char *argv[]) { - char buf[BUFSIZ], *p; - bool match = false; + struct dirent *d; + char buf[BUFSIZ]; + DIR *dir; int opt; - while((opt = getopt(argc, argv, "C:bcdefghn:o:pqrsuwx")) != -1) + while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuwx")) != -1) switch(opt) { - case 'C': /* tests relative to directory */ - if(chdir(optarg) == -1) { - perror(optarg); - exit(2); - } - break; case 'n': /* newer than file */ case 'o': /* older than file */ - if(!(OPER(opt) = stat(optarg, (opt == 'n' ? &new : &old)) == 0)) + if(!(FLAG(opt) = !stat(optarg, (opt == 'n' ? &new : &old)))) perror(optarg); break; - case 'q': /* quiet (no output, just status) */ - quiet = true; - break; default: /* miscellaneous operators */ - OPER(opt) = true; + FLAG(opt) = true; break; case '?': /* error: unknown flag */ - fprintf(stderr, "usage: %s [-bcdefghpqrsuwx] [-C dir] [-n file] [-o file] [file...]\n", argv[0]); + fprintf(stderr, "usage: %s [-abcdefghlpqrsuwx] [-n file] [-o file] [file...]\n", argv[0]); exit(2); } - if(optind == argc) - while(fgets(buf, sizeof buf, stdin)) { - if(*(p = &buf[strlen(buf)-1]) == '\n') - *p = '\0'; - match |= test(buf); + for(; optind < argc; optind++) + if(FLAG('l') && (dir = opendir(argv[optind]))) { + /* test directory contents */ + while((d = readdir(dir))) + if(snprintf(buf, sizeof buf, "%s/%s", argv[optind], d->d_name) < sizeof buf) + test(buf, d->d_name); + closedir(dir); } - else - while(optind < argc) - match |= test(argv[optind++]); + else + test(argv[optind], argv[optind]); return match ? 0 : 1; } -bool -test(const char *path) { - struct stat st; +void +test(const char *path, const char *name) { + struct stat st, ln; - if((!OPER('b') || (stat(path, &st) == 0 && S_ISBLK(st.st_mode))) /* block special */ - && (!OPER('c') || (stat(path, &st) == 0 && S_ISCHR(st.st_mode))) /* character special */ - && (!OPER('d') || (stat(path, &st) == 0 && S_ISDIR(st.st_mode))) /* directory */ - && (!OPER('e') || (access(path, F_OK) == 0)) /* exists */ - && (!OPER('f') || (stat(path, &st) == 0 && S_ISREG(st.st_mode))) /* regular file */ - && (!OPER('g') || (stat(path, &st) == 0 && (st.st_mode & S_ISGID))) /* set-group-id flag */ - && (!OPER('h') || (lstat(path, &st) == 0 && S_ISLNK(st.st_mode))) /* symbolic link */ - && (!OPER('n') || (stat(path, &st) == 0 && st.st_mtime > new.st_mtime)) /* newer than file */ - && (!OPER('o') || (stat(path, &st) == 0 && st.st_mtime < old.st_mtime)) /* older than file */ - && (!OPER('p') || (stat(path, &st) == 0 && S_ISFIFO(st.st_mode))) /* named pipe */ - && (!OPER('r') || (access(path, R_OK) == 0)) /* readable */ - && (!OPER('s') || (stat(path, &st) == 0 && st.st_size > 0)) /* not empty */ - && (!OPER('u') || (stat(path, &st) == 0 && (st.st_mode & S_ISUID))) /* set-user-id flag */ - && (!OPER('w') || (access(path, W_OK) == 0)) /* writable */ - && (!OPER('x') || (access(path, X_OK) == 0))) { /* executable */ - if(quiet) + if(!stat(path, &st) && !lstat(path, &ln) + && ( FLAG('a') || name[0] != '.') /* hidden */ + && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ + && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ + && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ + && (!FLAG('e') || access(path, F_OK) == 0) /* exists */ + && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */ + && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */ + && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */ + && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */ + && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */ + && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */ + && (!FLAG('r') || access(path, R_OK) == 0) /* readable */ + && (!FLAG('s') || st.st_size > 0) /* not empty */ + && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */ + && (!FLAG('w') || access(path, W_OK) == 0) /* writable */ + && (!FLAG('x') || access(path, X_OK) == 0)) { /* executable */ + if(FLAG('q')) exit(0); - puts(path); - return true; + match = true; + puts(name); } - else - return false; } From 38cb254399bb23e04db933bb7f91d31c2aeef99f Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 27 Nov 2011 23:37:01 +0100 Subject: [PATCH 462/590] stest: remove unneeded lstat --- dmenubar/stest.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/stest.c b/dmenubar/stest.c index e75d321..9dbf9c1 100644 --- a/dmenubar/stest.c +++ b/dmenubar/stest.c @@ -54,8 +54,7 @@ void test(const char *path, const char *name) { struct stat st, ln; - if(!stat(path, &st) && !lstat(path, &ln) - && ( FLAG('a') || name[0] != '.') /* hidden */ + if(!stat(path, &st) && ( FLAG('a') || name[0] != '.') /* hidden files */ && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ From 2ef2230c9134d7fbb1536ad4473b00485d0d4c6e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 27 Nov 2011 23:40:48 +0100 Subject: [PATCH 463/590] stest: cleanup --- dmenubar/stest.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dmenubar/stest.c b/dmenubar/stest.c index 9dbf9c1..b4dba64 100644 --- a/dmenubar/stest.c +++ b/dmenubar/stest.c @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <unistd.h> #include <sys/stat.h> @@ -54,7 +53,7 @@ void test(const char *path, const char *name) { struct stat st, ln; - if(!stat(path, &st) && ( FLAG('a') || name[0] != '.') /* hidden files */ + if(!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ From 7fd7a3bfc7927d64958f35eee538df623026b1e4 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 9 Dec 2011 11:36:26 +0100 Subject: [PATCH 464/590] fork dmenu_run to disown child shell --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 35a4db3..2bb1dfd 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -12,4 +12,4 @@ fi else dmenu "$@" < "$cache" fi -) | exec ${SHELL:-"/bin/sh"} +) | ${SHELL:-"/bin/sh"} & From 1d944814cfed12ffc2d258a43ed4cd9d4489d5af Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 9 Dec 2011 11:49:44 +0100 Subject: [PATCH 465/590] stest: restore stream testing --- dmenubar/stest.1 | 3 ++- dmenubar/stest.c | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dmenubar/stest.1 b/dmenubar/stest.1 index 1f590ec..bb48f45 100644 --- a/dmenubar/stest.1 +++ b/dmenubar/stest.1 @@ -13,7 +13,8 @@ stest \- filter a list of files by properties .B stest takes a list of files and filters by the files' properties, analogous to .IR test (1). -Files which pass all tests are printed to stdout. +Files which pass all tests are printed to stdout. If no files are given, stest +reads files from stdin. .SH OPTIONS .TP .B \-a diff --git a/dmenubar/stest.c b/dmenubar/stest.c index b4dba64..e1dcf36 100644 --- a/dmenubar/stest.c +++ b/dmenubar/stest.c @@ -3,6 +3,7 @@ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include <sys/stat.h> @@ -17,7 +18,7 @@ static struct stat old, new; int main(int argc, char *argv[]) { struct dirent *d; - char buf[BUFSIZ]; + char buf[BUFSIZ], *p; DIR *dir; int opt; @@ -35,6 +36,12 @@ main(int argc, char *argv[]) { fprintf(stderr, "usage: %s [-abcdefghlpqrsuwx] [-n file] [-o file] [file...]\n", argv[0]); exit(2); } + if(optind == argc) + while(fgets(buf, sizeof buf, stdin)) { + if((p = strchr(buf, '\n'))) + *p = '\0'; + test(buf, buf); + } for(; optind < argc; optind++) if(FLAG('l') && (dir = opendir(argv[optind]))) { /* test directory contents */ From 3b3945e80606dc047d85a2ead4b0215320ab565a Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 19 Dec 2011 16:05:55 +0100 Subject: [PATCH 466/590] comment xdg fallback behaviour --- dmenubar/dmenu_run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 2bb1dfd..976da46 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -3,7 +3,7 @@ cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"} if [ -d "$cachedir" ]; then cache=$cachedir/dmenu_run else - cache=$HOME/.dmenu_cache + cache=$HOME/.dmenu_cache # if no xdg dir, fall back to dotfile in ~ fi ( IFS=: From c18f75412e644dc3e64c44186d086f13e840e0e9 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 1 Jan 2012 20:32:40 +0100 Subject: [PATCH 467/590] add Mod1Mask keybindings --- dmenubar/dmenu.1 | 88 +++++++++++++++++++++++++++++++++++++++++------- dmenubar/dmenu.c | 19 +++++++---- 2 files changed, 88 insertions(+), 19 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 5f74463..b221417 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -33,7 +33,7 @@ matching the tokens in the input. .B dmenu_run is a script used by .IR dwm (1) -which lists programs in the user's $PATH and executes the selected item. +which lists programs in the user's $PATH and runs the result in their $SHELL. .SH OPTIONS .TP .B \-b @@ -73,28 +73,90 @@ defines the selected foreground color. .B \-v prints version information to stdout, then exits. .SH USAGE -dmenu is completely controlled by the keyboard. Besides standard Unix line -editing and item selection (arrow keys, page up/down, home and end), the -following keys are recognized: +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. .TP -.B Tab (Ctrl\-i) +.B Tab Copy the selected item to the input field. .TP -.B Return (Ctrl\-j) +.B Return Confirm selection. Prints the selected item to stdout and exits, returning success. .TP -.B Shift\-Return (Ctrl\-Shift\-j) +.B Shift\-Return Confirm input. Prints the input text to stdout and exits, returning success. .TP -.B Escape (Ctrl\-c) +.B Escape Exit without selecting an item, returning failure. .TP -.B Ctrl\-y -Paste the primary X selection into the input field. +C\-a +Home .TP -.B Ctrl-Shift-y -Paste the X clipboard into the input field. +C\-b +Left +.TP +C\-c +Escape +.TP +C\-d +Delete +.TP +C\-e +End +.TP +C\-f +Right +.TP +C\-h +Backspace +.TP +C\-i +Tab +.TP +C\-j +Return +.TP +C\-k +Delete line right +.TP +C\-m +Return +.TP +C\-n +Down +.TP +C\-p +Up +.TP +C\-u +Delete line left +.TP +C\-w +Delete word left +.TP +C\-y +Paste from primary X selection +.TP +C\-Y +Paste from X clipboard +.TP +M\-g +Home +.TP +M\-G +End +.TP +M\-h +Page up +.TP +M\-j +Up +.TP +M\-k +Down +.TP +M\-l +Page down .SH SEE ALSO .IR dwm (1), -.IR lsx (1) +.IR stest (1) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 019fa3e..9fa3e3c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -243,11 +243,8 @@ keypress(XKeyEvent *ev) { len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); if(status == XBufferOverflow) return; - if(ev->state & ControlMask) { - KeySym lower, upper; - - XConvertCase(ksym, &lower, &upper); - switch(lower) { + if(ev->state & ControlMask) + switch(ksym) { case XK_a: ksym = XK_Home; break; case XK_b: ksym = XK_Left; break; case XK_c: ksym = XK_Escape; break; @@ -281,7 +278,17 @@ keypress(XKeyEvent *ev) { default: return; } - } + else if(ev->state & Mod1Mask) + switch(ksym) { + case XK_g: ksym = XK_Home; break; + case XK_G: ksym = XK_End; break; + case XK_h: ksym = XK_Prior; break; + case XK_j: ksym = XK_Up; break; + case XK_k: ksym = XK_Down; break; + case XK_l: ksym = XK_Next; break; + default: + return; + } switch(ksym) { default: if(!iscntrl(*buf)) From c394e16ee3d3a86f2cb155d6fb0b3c21856e43b3 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 1 Jan 2012 20:33:56 +0100 Subject: [PATCH 468/590] happy new year! --- dmenubar/LICENSE | 4 ++-- dmenubar/dmenu.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 25eb571..e2bfc83 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License -© 2010-2011 Connor Lane Smith <cls@lubutu.com> -© 2006-2011 Anselm R Garbe <anselm@garbe.us> +© 2010-2012 Connor Lane Smith <cls@lubutu.com> +© 2006-2012 Anselm R Garbe <anselm@garbe.us> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9fa3e3c..6f6123d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -72,7 +72,7 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* these options take no arguments */ if(!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details"); + puts("dmenu-"VERSION", © 2006-2012 dmenu engineers, see LICENSE for details"); exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ From a70c695cfecc0012a46460b742142dbb556405ae Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Mon, 2 Jan 2012 19:48:11 +0100 Subject: [PATCH 469/590] align M-[hjkl] closer to vi keys --- dmenubar/dmenu.1 | 13 ++++++++----- dmenubar/dmenu.c | 8 ++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index b221417..0784cd9 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -116,6 +116,9 @@ Tab C\-j Return .TP +C\-J +Shift-Return +.TP C\-k Delete line right .TP @@ -147,16 +150,16 @@ M\-G End .TP M\-h -Page up -.TP -M\-j Up .TP +M\-j +Page down +.TP M\-k -Down +Page up .TP M\-l -Page down +Down .SH SEE ALSO .IR dwm (1), .IR stest (1) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6f6123d..4ea95f8 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -282,10 +282,10 @@ keypress(XKeyEvent *ev) { switch(ksym) { case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; - case XK_h: ksym = XK_Prior; break; - case XK_j: ksym = XK_Up; break; - case XK_k: ksym = XK_Down; break; - case XK_l: ksym = XK_Next; break; + case XK_h: ksym = XK_Up; break; + case XK_j: ksym = XK_Next; break; + case XK_k: ksym = XK_Prior; break; + case XK_l: ksym = XK_Down; break; default: return; } From 495768286f5cff68d0f43d9ea0ec9ad5f7ac8abe Mon Sep 17 00:00:00 2001 From: "anselm@garbe.us" <unknown> Date: Wed, 4 Jan 2012 13:30:47 +0100 Subject: [PATCH 470/590] config.mk cleanup --- dmenubar/config.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 87a87f9..1726b35 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = hg +VERSION = 4.4.1-tip # paths PREFIX = /usr/local @@ -18,7 +18,8 @@ LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} # compiler and linker From 4eaf6706c581acce347620866dd150332a3cb472 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Sun, 8 Jan 2012 13:13:00 +0100 Subject: [PATCH 471/590] update version 4.5-hg --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 1726b35..725e28e 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.4.1-tip +VERSION = 4.5-tip # paths PREFIX = /usr/local From 8746d52a846e0e8806c58a46d27b4a237ade5625 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Wed, 18 Jan 2012 23:56:13 +0000 Subject: [PATCH 472/590] remove _POSIX_C_SOURCE cflag --- dmenubar/config.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 725e28e..ca89fd6 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -17,9 +17,8 @@ INCS = -I${X11INC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} # compiler and linker From 0473f39359a454d12ff6885a37f6b79d74433c92 Mon Sep 17 00:00:00 2001 From: Karl F <karlf@thep.lu.se> Date: Thu, 19 Jan 2012 22:52:17 +0000 Subject: [PATCH 473/590] add ^G escape keybinding --- dmenubar/dmenu.1 | 3 +++ dmenubar/dmenu.c | 1 + 2 files changed, 4 insertions(+) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 0784cd9..3a0f4ef 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -107,6 +107,9 @@ End C\-f Right .TP +C\-g +Escape +.TP C\-h Backspace .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 4ea95f8..fad4443 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -251,6 +251,7 @@ keypress(XKeyEvent *ev) { case XK_d: ksym = XK_Delete; break; case XK_e: ksym = XK_End; 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; case XK_j: ksym = XK_Return; break; From 3b11538d35a0cf3621aefbc358d3c2464882cbf6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 10 Feb 2012 00:37:42 +0000 Subject: [PATCH 474/590] listen for C-S-[jm] --- dmenubar/dmenu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index fad4443..f7eba87 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -254,8 +254,10 @@ keypress(XKeyEvent *ev) { case XK_g: ksym = XK_Escape; break; case XK_h: ksym = XK_BackSpace; break; case XK_i: ksym = XK_Tab; break; - case XK_j: ksym = XK_Return; break; - case XK_m: ksym = XK_Return; break; + case XK_j: /* fallthrough */ + case XK_J: ksym = XK_Return; break; + case XK_m: /* fallthrough */ + case XK_M: ksym = XK_Return; break; case XK_n: ksym = XK_Down; break; case XK_p: ksym = XK_Up; break; From 53d7808eed0eb7fcf756eb550f5f2d200cf93fa3 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith <cls@lubutu.com> Date: Fri, 6 Apr 2012 16:38:01 +0100 Subject: [PATCH 475/590] _POSIX_C_SOURCE=200809L --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index ca89fd6..c0d466b 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -17,7 +17,7 @@ INCS = -I${X11INC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} From 987d1e80dcdc1b0af27cd39b46cd70daaff30f3a Mon Sep 17 00:00:00 2001 From: Moritz Wilhelmy <moritz+hg@wzff.de> Date: Tue, 15 May 2012 11:47:54 +0200 Subject: [PATCH 476/590] ignore prompt if it is empty in addition to NULL --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f7eba87..3962801 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -169,7 +169,7 @@ drawmenu(void) { dc->h = bh; drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); - if(prompt) { + if(prompt && *prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; @@ -579,7 +579,7 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } - promptw = prompt ? textw(dc, prompt) : 0; + promptw = (prompt && *prompt) ? textw(dc, prompt) : 0; inputw = MIN(inputw, mw/3); match(); From 93c482544c65477242d5ba00a1d74bd9fe683795 Mon Sep 17 00:00:00 2001 From: Quentin Glidic <sardemff7+hg@sardemff7.net> Date: Mon, 30 Jul 2012 17:02:12 +0200 Subject: [PATCH 477/590] dmenu_run: Split cache logic to dmenu_path again This allows to run dmenu_path to update the cache using a packager manager hook system --- dmenubar/Makefile | 6 ++++-- dmenubar/dmenu_path | 13 +++++++++++++ dmenubar/dmenu_run | 15 +-------------- 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 dmenubar/dmenu_path diff --git a/dmenubar/Makefile b/dmenubar/Makefile index c127f6a..f011ad7 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -35,7 +35,7 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run stest.1 ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_path dmenu_run stest.1 ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} @@ -43,8 +43,9 @@ dist: clean install: all @echo installing executables to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_run stest ${DESTDIR}${PREFIX}/bin + @cp -f dmenu dmenu_path dmenu_run stest ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu + @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run @chmod 755 ${DESTDIR}${PREFIX}/bin/stest @echo installing manual pages to ${DESTDIR}${MANPREFIX}/man1 @@ -57,6 +58,7 @@ install: all uninstall: @echo removing executables from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/dmenu + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_path @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run @rm -f ${DESTDIR}${PREFIX}/bin/stest @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path new file mode 100644 index 0000000..338bac4 --- /dev/null +++ b/dmenubar/dmenu_path @@ -0,0 +1,13 @@ +#!/bin/sh +cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"} +if [ -d "$cachedir" ]; then + cache=$cachedir/dmenu_run +else + cache=$HOME/.dmenu_cache # if no xdg dir, fall back to dotfile in ~ +fi +IFS=: +if stest -dqr -n "$cache" $PATH; then + stest -flx $PATH | sort -u | tee "$cache" +else + cat "$cache" +fi diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run index 052e51b..834ede5 100755 --- a/dmenubar/dmenu_run +++ b/dmenubar/dmenu_run @@ -1,15 +1,2 @@ #!/bin/sh -cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"} -if [ -d "$cachedir" ]; then - cache=$cachedir/dmenu_run -else - cache=$HOME/.dmenu_cache # if no xdg dir, fall back to dotfile in ~ -fi -( - IFS=: - if stest -dqr -n "$cache" $PATH; then - stest -flx $PATH | sort -u | tee "$cache" | dmenu "$@" - else - dmenu "$@" < "$cache" - fi -) | ${SHELL:-"/bin/sh"} & +dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & From 873fa559447881ec285baa5e74ea71d7207d5421 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Wed, 17 Apr 2013 20:56:54 +0200 Subject: [PATCH 478/590] applied multisel patch to mainline --- dmenubar/dmenu.1 | 3 +++ dmenubar/dmenu.c | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 3a0f4ef..88f77de 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -83,6 +83,9 @@ Copy the selected item to the input field. 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 diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3962801..efc1e54 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -22,6 +22,7 @@ typedef struct Item Item; struct Item { char *text; Item *left, *right; + Bool out; }; static void appenditem(Item *item, Item **list, Item **last); @@ -49,9 +50,12 @@ static const char *normbgcolor = "#222222"; static const char *normfgcolor = "#bbbbbb"; static const char *selbgcolor = "#005577"; static const char *selfgcolor = "#eeeeee"; +static const char *outbgcolor = "#00ffff"; +static const char *outfgcolor = "#000000"; static unsigned int lines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; +static unsigned long outcol[ColLast]; static Atom clip, utf8; static Bool topbar = True; static DC *dc; @@ -185,7 +189,8 @@ drawmenu(void) { dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; - drawtext(dc, item->text, (item == sel) ? selcol : normcol); + drawtext(dc, item->text, (item == sel) ? selcol : + (item->out) ? outcol : normcol); } } else if(matches) { @@ -197,7 +202,8 @@ drawmenu(void) { for(item = curr; item != next; item = item->right) { dc->x += dc->w; dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); - drawtext(dc, item->text, (item == sel) ? selcol : normcol); + drawtext(dc, item->text, (item == sel) ? selcol : + (item->out) ? outcol : normcol); } dc->w = textw(dc, ">"); dc->x = mw - dc->w; @@ -278,6 +284,9 @@ keypress(XKeyEvent *ev) { XConvertSelection(dc->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + case XK_Return: + case XK_KP_Enter: + break; default: return; } @@ -362,7 +371,10 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - exit(EXIT_SUCCESS); + if(!(ev->state & ControlMask)) + exit(EXIT_SUCCESS); + sel->out = True; + break; case XK_Right: if(text[cursor] != '\0') { cursor = nextrune(+1); @@ -480,6 +492,7 @@ readstdin(void) { *p = '\0'; if(!(items[i].text = strdup(buf))) eprintf("cannot strdup %u bytes:", strlen(buf)+1); + items[i].out = False; if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } @@ -531,6 +544,8 @@ setup(void) { normcol[ColFG] = getcolor(dc, normfgcolor); selcol[ColBG] = getcolor(dc, selbgcolor); selcol[ColFG] = getcolor(dc, selfgcolor); + outcol[ColBG] = getcolor(dc, outbgcolor); + outcol[ColFG] = getcolor(dc, outfgcolor); clip = XInternAtom(dc->dpy, "CLIPBOARD", False); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); From 5f0f8e4db7da67751fde5d7ff110b895d45fa556 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Wed, 17 Apr 2013 20:59:12 +0200 Subject: [PATCH 479/590] applied Alex Sedov's Tab buffer termination patch, thanks --- dmenubar/dmenu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index efc1e54..c25dc82 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -392,7 +392,8 @@ keypress(XKeyEvent *ev) { case XK_Tab: if(!sel) return; - strncpy(text, sel->text, sizeof text); + strncpy(text, sel->text, sizeof text - 1); + text[sizeof text - 1] = '\0'; cursor = strlen(text); match(); break; From 06ee65a7b9a2517d90a99c822242c4dc1730845f Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Wed, 17 Apr 2013 21:04:05 +0200 Subject: [PATCH 480/590] adopted Alex Sedov's config.h revival patch to tip --- dmenubar/Makefile | 6 +++++- dmenubar/dmenu.c | 12 ++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index f011ad7..0f7dfbd 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -18,7 +18,11 @@ options: @echo CC -c $< @${CC} -c $< ${CFLAGS} -${OBJ}: config.mk draw.h +config.h: + @echo creating $@ from config.def.h + @cp config.def.h $@ + +${OBJ}: config.h config.mk draw.h dmenu: dmenu.o draw.o @echo CC -o $@ diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c25dc82..a06ae15 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -44,20 +44,10 @@ static char text[BUFSIZ] = ""; static int bh, mw, mh; static int inputw, promptw; static size_t cursor = 0; -static const char *font = NULL; -static const char *prompt = NULL; -static const char *normbgcolor = "#222222"; -static const char *normfgcolor = "#bbbbbb"; -static const char *selbgcolor = "#005577"; -static const char *selfgcolor = "#eeeeee"; -static const char *outbgcolor = "#00ffff"; -static const char *outfgcolor = "#000000"; -static unsigned int lines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static unsigned long outcol[ColLast]; static Atom clip, utf8; -static Bool topbar = True; static DC *dc; static Item *items = NULL; static Item *matches, *matchend; @@ -65,6 +55,8 @@ static Item *prev, *curr, *next, *sel; static Window win; static XIC xic; +#include "config.h" + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; From edae6ee0ab26c8cbc15dfd574ce95c80a2ab48d0 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Wed, 17 Apr 2013 21:16:51 +0200 Subject: [PATCH 481/590] forgot to add config.def.h, thanks William --- dmenubar/config.def.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 dmenubar/config.def.h diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h new file mode 100644 index 0000000..c2a23fa --- /dev/null +++ b/dmenubar/config.def.h @@ -0,0 +1,17 @@ +/* See LICENSE file for copyright and license details. */ +/* vim: expandtab + */ +/* Default settings; can be overrided by command line. */ + +static Bool topbar = True; /* -b option; if False, dmenu appears at bottom */ +static const char *font = NULL; /* -fn option; default X11 font or font set */ +static const char *prompt = NULL; /* -p option; prompt to the elft of input field */ +static const char *normbgcolor = "#222222"; /* -nb option; normal background */ +static const char *normfgcolor = "#bbbbbb"; /* -nf option; normal foreground */ +static const char *selbgcolor = "#005577"; /* -sb option; selected background */ +static const char *selfgcolor = "#eeeeee"; /* -sf option; selected foreground */ +static const char *outbgcolor = "#00ffff"; +static const char *outfgcolor = "#000000"; +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 0; + From e749e527f6678dc5ff3fafd324f3244f52b87875 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Fri, 28 Jun 2013 22:06:02 +0200 Subject: [PATCH 482/590] accepted vi'is exit approach ^[ (suggested by Arkaduisz) --- dmenubar/dmenu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a06ae15..5e0a19c 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -279,6 +279,8 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: break; + case XK_bracketleft: + exit(EXIT_FAILURE); default: return; } From e35061137abbfdce430460aecc1fc3d90ec44b39 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Fri, 2 Aug 2013 22:30:20 +0200 Subject: [PATCH 483/590] =?UTF-8?q?applied=20Martti=20K=C3=BChne's=20dmenu?= =?UTF-8?q?=20monitor=20patch=20https://gist.github.com/mar77i/3349298/raw?= =?UTF-8?q?/f6581ca96627f4c71c0bd1faf531daaf2a613b95/monarg.patch=20become?= =?UTF-8?q?s=20upstream=20now?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dmenubar/LICENSE | 2 +- dmenubar/dmenu.1 | 5 +++++ dmenubar/dmenu.c | 11 ++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index e2bfc83..0df62c6 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License +© 2006-2013 Anselm R Garbe <anselm@garbe.us> © 2010-2012 Connor Lane Smith <cls@lubutu.com> -© 2006-2012 Anselm R Garbe <anselm@garbe.us> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 88f77de..bbee17d 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -7,6 +7,8 @@ dmenu \- dynamic menu .RB [ \-f ] .RB [ \-i ] .RB [ \-l +.RB [ \-m +.IR monitor ] .IR lines ] .RB [ \-p .IR prompt ] @@ -49,6 +51,9 @@ dmenu matches menu items case insensitively. .BI \-l " lines" dmenu lists items vertically, with the given number of lines. .TP +.BI \-m " monitor" +dmenu is displayed on the monitor supplied. +.TP .BI \-p " prompt" defines the prompt to be displayed to the left of the input field. .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5e0a19c..8d9bbb6 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -54,6 +54,7 @@ static Item *matches, *matchend; static Item *prev, *curr, *next, *sel; static Window win; static XIC xic; +static int mon = -1; #include "config.h" @@ -84,6 +85,8 @@ main(int argc, char *argv[]) { /* these options take one argument */ else if(!strcmp(argv[i], "-l")) /* number of lines in vertical list */ lines = atoi(argv[++i]); + else if(!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) /* font or font set */ @@ -557,7 +560,9 @@ setup(void) { XWindowAttributes wa; XGetInputFocus(dc->dpy, &w, &di); - if(w != root && w != PointerRoot && w != None) { + if(mon != -1 && mon < n) + i = mon; + if(!i && w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ do { if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) @@ -572,7 +577,7 @@ setup(void) { } } /* no focused window is on screen, so use pointer location instead */ - if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + if(mon == -1 && !area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for(i = 0; i < n; i++) if(INTERSECT(x, y, 1, 1, info[i])) break; @@ -614,7 +619,7 @@ setup(void) { void usage(void) { - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); } From 8d707f76cf37de7c25141732194b2c092a123cc5 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Tue, 13 Aug 2013 19:15:04 +0200 Subject: [PATCH 484/590] =?UTF-8?q?applied=20Martin=20K=C3=BChl's=20invers?= =?UTF-8?q?e=20matching=20flag=20to=20stest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dmenubar/stest.1 | 3 +++ dmenubar/stest.c | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dmenubar/stest.1 b/dmenubar/stest.1 index bb48f45..2667d8a 100644 --- a/dmenubar/stest.1 +++ b/dmenubar/stest.1 @@ -67,6 +67,9 @@ Test that files are not empty. .B \-u Test that files have their set-user-ID flag set. .TP +.B \-v +Invert the sense of tests, only failing files pass. +.TP .B \-w Test that files are writable. .TP diff --git a/dmenubar/stest.c b/dmenubar/stest.c index e1dcf36..8fac42a 100644 --- a/dmenubar/stest.c +++ b/dmenubar/stest.c @@ -22,7 +22,7 @@ main(int argc, char *argv[]) { DIR *dir; int opt; - while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuwx")) != -1) + while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuvwx")) != -1) switch(opt) { case 'n': /* newer than file */ case 'o': /* older than file */ @@ -33,7 +33,7 @@ main(int argc, char *argv[]) { FLAG(opt) = true; break; case '?': /* error: unknown flag */ - fprintf(stderr, "usage: %s [-abcdefghlpqrsuwx] [-n file] [-o file] [file...]\n", argv[0]); + fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] [-n file] [-o file] [file...]\n", argv[0]); exit(2); } if(optind == argc) @@ -60,7 +60,7 @@ void test(const char *path, const char *name) { struct stat st, ln; - if(!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ + if((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ @@ -75,7 +75,7 @@ test(const char *path, const char *name) { && (!FLAG('s') || st.st_size > 0) /* not empty */ && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */ && (!FLAG('w') || access(path, W_OK) == 0) /* writable */ - && (!FLAG('x') || access(path, X_OK) == 0)) { /* executable */ + && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */ if(FLAG('q')) exit(0); match = true; From 3673394bdc258dd3a52a6b3d2a509ba6f38c9cc9 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.us> Date: Thu, 29 May 2014 18:03:53 +0200 Subject: [PATCH 485/590] updated copyright notices in LICENSE and dmenu.c file --- dmenubar/LICENSE | 2 +- dmenubar/dmenu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 0df62c6..39c4b6e 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,6 +1,6 @@ MIT/X Consortium License -© 2006-2013 Anselm R Garbe <anselm@garbe.us> +© 2006-2014 Anselm R Garbe <anselm@garbe.us> © 2010-2012 Connor Lane Smith <cls@lubutu.com> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8d9bbb6..dd2c128 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -69,7 +69,7 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* these options take no arguments */ if(!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION", © 2006-2012 dmenu engineers, see LICENSE for details"); + puts("dmenu-"VERSION", © 2006-2014 dmenu engineers, see LICENSE for details"); exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ From 4669af9d8eedb95ab88a72648a4616ba624a45bb Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Thu, 24 Jul 2014 19:10:23 +0000 Subject: [PATCH 486/590] fix crash with ctrl-enter as input reproduce: ./dmenu; send EOF; press ctrl+enter. --- dmenubar/dmenu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index dd2c128..b56f3a8 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -370,7 +370,8 @@ keypress(XKeyEvent *ev) { puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); if(!(ev->state & ControlMask)) exit(EXIT_SUCCESS); - sel->out = True; + if(sel) + sel->out = True; break; case XK_Right: if(text[cursor] != '\0') { From 8ec422a3dcfa609775856ff6586f31e471185ca1 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <garbeam@gmail.com> Date: Wed, 17 Sep 2014 13:40:11 +0200 Subject: [PATCH 487/590] applied Hiltjo's patch as suggested on the ml to fix ControlMask for C-j and C-m --- dmenubar/dmenu.1 | 3 +++ dmenubar/dmenu.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index bbee17d..2897ab1 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -136,6 +136,9 @@ Delete line right C\-m Return .TP +C\-M +Shift-Return +.TP C\-n Down .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b56f3a8..94c70de 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -256,9 +256,9 @@ keypress(XKeyEvent *ev) { case XK_h: ksym = XK_BackSpace; break; case XK_i: ksym = XK_Tab; break; case XK_j: /* fallthrough */ - case XK_J: ksym = XK_Return; break; + case XK_J: /* fallthrough */ case XK_m: /* fallthrough */ - case XK_M: ksym = XK_Return; break; + case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; case XK_n: ksym = XK_Down; break; case XK_p: ksym = XK_Up; break; From a2e8616d0e5ffb29f82f4426243eeae2a002e30a Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Mon, 4 May 2015 21:54:46 +0200 Subject: [PATCH 488/590] Use libdraw: add Xft and fallback-fonts support to graphics lib - libdraw, util: add drw.{c,h}, util.{c,h} and update code. - libdraw: fix drw_rect(): use w and h parameter. - libdraw: print errstr if last character in string was ":" (sbase). - libdraw: drw_clr_free() allow valid free(NULL). - config.def.h: set default font to monospace. - cleanup() on exit. - LICENSE: update license string for dmenu -v to 2015. - LICENSE: add myself to LICENSE --- dmenubar/LICENSE | 1 + dmenubar/Makefile | 15 +- dmenubar/config.def.h | 10 +- dmenubar/config.mk | 4 +- dmenubar/dmenu.c | 243 +++++++++++++++---------- dmenubar/draw.c | 177 ------------------ dmenubar/draw.h | 35 ---- dmenubar/drw.c | 413 ++++++++++++++++++++++++++++++++++++++++++ dmenubar/drw.h | 74 ++++++++ dmenubar/util.c | 23 +++ dmenubar/util.h | 7 + 11 files changed, 685 insertions(+), 317 deletions(-) delete mode 100644 dmenubar/draw.c delete mode 100644 dmenubar/draw.h create mode 100644 dmenubar/drw.c create mode 100644 dmenubar/drw.h create mode 100644 dmenubar/util.c create mode 100644 dmenubar/util.h diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 39c4b6e..221603d 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -7,6 +7,7 @@ MIT/X Consortium License © 2009 Evan Gates <evan.gates@gmail.com> © 2006-2008 Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2006-2007 Michał Janeczek <janeczek at gmail dot com> +© 2014-2015 Hiltjo Posthuma <hiltjo@codemadness.org> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 0f7dfbd..4a412ee 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = dmenu.c draw.c stest.c +SRC = drw.c dmenu.c stest.c util.c OBJ = ${SRC:.c=.o} all: options dmenu stest @@ -15,18 +15,18 @@ options: @echo "CC = ${CC}" .c.o: - @echo CC -c $< - @${CC} -c $< ${CFLAGS} + @echo CC $< + @${CC} -c ${CFLAGS} $< config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -${OBJ}: config.h config.mk draw.h +${OBJ}: config.h config.mk drw.h -dmenu: dmenu.o draw.o +dmenu: dmenu.o drw.o util.o @echo CC -o $@ - @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} + @${CC} -o $@ dmenu.o drw.o util.o ${LDFLAGS} stest: stest.o @echo CC -o $@ @@ -39,7 +39,8 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_path dmenu_run stest.1 ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 drw.h util.h dmenu_path \ + dmenu_run stest.1 ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index c2a23fa..4e5e3e7 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -4,8 +4,11 @@ /* Default settings; can be overrided by command line. */ static Bool topbar = True; /* -b option; if False, dmenu appears at bottom */ -static const char *font = NULL; /* -fn option; default X11 font or font set */ -static const char *prompt = NULL; /* -p option; prompt to the elft of input field */ +/* -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 elft of input field */ static const char *normbgcolor = "#222222"; /* -nb option; normal background */ static const char *normfgcolor = "#bbbbbb"; /* -nf option; normal foreground */ static const char *selbgcolor = "#005577"; /* -sb option; selected background */ @@ -13,5 +16,4 @@ static const char *selfgcolor = "#eeeeee"; /* -sf option; selected foreground static const char *outbgcolor = "#00ffff"; static const char *outfgcolor = "#000000"; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ -static unsigned int lines = 0; - +static unsigned int lines = 0; diff --git a/dmenubar/config.mk b/dmenubar/config.mk index c0d466b..4e62a09 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -13,8 +13,8 @@ XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA # includes and libs -INCS = -I${X11INC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} +INCS = -I${X11INC} -I/usr/include/freetype2 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -lfontconfig -lXft # flags CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 94c70de..94be574 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> +#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -11,12 +12,20 @@ #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif -#include "draw.h" +#include <X11/Xft/Xft.h> +#include "drw.h" +#include "util.h" + +/* 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 MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define TEXTNW(X,N) (drw_font_getexts_width(drw->fonts[0], (X), (N))) +#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h) + +/* enums */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ typedef struct Item Item; struct Item { @@ -28,6 +37,7 @@ struct Item { static void appenditem(Item *item, Item **list, Item **last); static void calcoffsets(void); static char *cistrstr(const char *s, const char *sub); +static void cleanup(void); static void drawmenu(void); static void grabkeyboard(void); static void insert(const char *str, ssize_t n); @@ -44,11 +54,7 @@ static char text[BUFSIZ] = ""; static int bh, mw, mh; static int inputw, promptw; static size_t cursor = 0; -static unsigned long normcol[ColLast]; -static unsigned long selcol[ColLast]; -static unsigned long outcol[ColLast]; static Atom clip, utf8; -static DC *dc; static Item *items = NULL; static Item *matches, *matchend; static Item *prev, *curr, *next, *sel; @@ -56,6 +62,13 @@ static Window win; static XIC xic; static int mon = -1; +static ClrScheme scheme[SchemeLast]; +static Display *dpy; +static int screen; +static Window root; +static Drw *drw; +static int sw, sh; /* X display screen geometry width, height */ + #include "config.h" static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; @@ -69,8 +82,8 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* these options take no arguments */ if(!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION", © 2006-2014 dmenu engineers, see LICENSE for details"); - exit(EXIT_SUCCESS); + puts("dmenu-"VERSION", © 2006-2015 dmenu engineers, see LICENSE for details"); + exit(0); } else if(!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ topbar = False; @@ -90,7 +103,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) /* font or font set */ - font = argv[++i]; + fonts[0] = argv[++i]; else if(!strcmp(argv[i], "-nb")) /* normal background color */ normbgcolor = argv[++i]; else if(!strcmp(argv[i], "-nf")) /* normal foreground color */ @@ -102,8 +115,19 @@ main(int argc, char *argv[]) { else usage(); - dc = initdc(); - initfont(dc, font); + if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if(!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display\n"); + screen = DefaultScreen(dpy); + root = RootWindow(dpy, screen); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + drw_load_fonts(drw, fonts, LENGTH(fonts)); + if(!drw->fontcount) + die("No fonts could be loaded.\n"); + drw_setscheme(drw, &scheme[SchemeNorm]); if(fast) { grabkeyboard(); @@ -138,16 +162,30 @@ calcoffsets(void) { if(lines > 0) n = lines * bh; else - n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); + n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), n)) > n) + if((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) break; for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? bh : MIN(textw(dc, prev->left->text), n)) > n) + if((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) break; } +void +cleanup(void) { + XUngrabKey(dpy, AnyKey, AnyModifier, root); + drw_clr_free(scheme[SchemeNorm].bg); + drw_clr_free(scheme[SchemeNorm].fg); + drw_clr_free(scheme[SchemeSel].fg); + drw_clr_free(scheme[SchemeSel].bg); + drw_clr_free(scheme[SchemeOut].fg); + drw_clr_free(scheme[SchemeOut].bg); + drw_free(drw); + XSync(dpy, False); + XCloseDisplay(dpy); +} + char * cistrstr(const char *s, const char *sub) { size_t len; @@ -162,50 +200,69 @@ void drawmenu(void) { int curpos; Item *item; + int x = 0, y = 0, h = bh, w; - dc->x = 0; - dc->y = 0; - dc->h = bh; - drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, True, 1, 1); if(prompt && *prompt) { - dc->w = promptw; - drawtext(dc, prompt, selcol); - dc->x = dc->w; + drw_setscheme(drw, &scheme[SchemeSel]); + drw_text(drw, x, 0, promptw, bh, prompt, 1); + x += promptw; } /* draw input field */ - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) - drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); + w = (lines > 0 || !matches) ? mw - x : inputw; + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, text, 0); + + if((curpos = TEXTNW(text, cursor) + bh/2 - 2) < w) { + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_rect(drw, x + curpos + 2, 2, 1, bh - 4, 1, 1, 0); + } if(lines > 0) { /* draw vertical list */ - dc->w = mw - dc->x; + w = mw - x; for(item = curr; item != next; item = item->right) { - dc->y += dc->h; - drawtext(dc, item->text, (item == sel) ? selcol : - (item->out) ? outcol : normcol); + y += h; + if(item == sel) + drw_setscheme(drw, &scheme[SchemeSel]); + else if(item->out) + drw_setscheme(drw, &scheme[SchemeOut]); + else + drw_setscheme(drw, &scheme[SchemeNorm]); + + drw_text(drw, x, y, w, bh, item->text, 0); } } else if(matches) { /* draw horizontal list */ - dc->x += inputw; - dc->w = textw(dc, "<"); - if(curr->left) - drawtext(dc, "<", normcol); - for(item = curr; item != next; item = item->right) { - dc->x += dc->w; - dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); - drawtext(dc, item->text, (item == sel) ? selcol : - (item->out) ? outcol : normcol); + x += inputw; + w = TEXTW("<"); + if(curr->left) { + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, "<", 0); + } + for(item = curr; item != next; item = item->right) { + x += w; + w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); + + if(item == sel) + drw_setscheme(drw, &scheme[SchemeSel]); + else if(item->out) + drw_setscheme(drw, &scheme[SchemeOut]); + else + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, item->text, 0); + } + w = TEXTW(">"); + x = mw - w; + if(next) { + drw_setscheme(drw, &scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, ">", 0); } - dc->w = textw(dc, ">"); - dc->x = mw - dc->w; - if(next) - drawtext(dc, ">", normcol); } - mapdc(dc, win, mw, mh); + drw_map(drw, win, 0, 0, mw, mh); } void @@ -214,12 +271,12 @@ grabkeyboard(void) { /* try to grab keyboard, we may have to wait for another process to ungrab */ for(i = 0; i < 1000; i++) { - if(XGrabKeyboard(dc->dpy, DefaultRootWindow(dc->dpy), True, + if(XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) return; usleep(1000); } - eprintf("cannot grab keyboard\n"); + die("cannot grab keyboard\n"); } void @@ -276,14 +333,15 @@ keypress(XKeyEvent *ev) { insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ - XConvertSelection(dc->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, + XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; case XK_Return: case XK_KP_Enter: break; case XK_bracketleft: - exit(EXIT_FAILURE); + cleanup(); + exit(1); default: return; } @@ -330,7 +388,8 @@ keypress(XKeyEvent *ev) { sel = matchend; break; case XK_Escape: - exit(EXIT_FAILURE); + cleanup(); + exit(1); case XK_Home: if(sel == matches) { cursor = 0; @@ -368,8 +427,10 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if(!(ev->state & ControlMask)) - exit(EXIT_SUCCESS); + if(!(ev->state & ControlMask)) { + cleanup(); + exit(0); + } if(sel) sel->out = True; break; @@ -413,7 +474,7 @@ match(void) { /* separate input text into tokens to be matched individually */ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - eprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv); + die("cannot realloc %u bytes\n", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; @@ -470,7 +531,7 @@ paste(void) { Atom da; /* we have been given the current selection, now insert it into input */ - XGetWindowProperty(dc->dpy, win, utf8, 0, (sizeof text / 4) + 1, False, + XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, utf8, &da, &di, &dl, &dl, (unsigned char **)&p); insert(p, (q = strchr(p, '\n')) ? q-p : (ssize_t)strlen(p)); XFree(p); @@ -486,18 +547,18 @@ readstdin(void) { for(i = 0; fgets(buf, sizeof buf, stdin); i++) { if(i+1 >= size / sizeof *items) if(!(items = realloc(items, (size += BUFSIZ)))) - eprintf("cannot realloc %u bytes:", size); + die("cannot realloc %u bytes:", size); if((p = strchr(buf, '\n'))) *p = '\0'; if(!(items[i].text = strdup(buf))) - eprintf("cannot strdup %u bytes:", strlen(buf)+1); + die("cannot strdup %u bytes:", strlen(buf)+1); items[i].out = False; if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } if(items) items[i].text = NULL; - inputw = maxstr ? textw(dc, maxstr) : 0; + inputw = maxstr ? TEXTW(maxstr) : 0; lines = MIN(lines, i); } @@ -505,13 +566,13 @@ void run(void) { XEvent ev; - while(!XNextEvent(dc->dpy, &ev)) { + while(!XNextEvent(dpy, &ev)) { if(XFilterEvent(&ev, win)) continue; switch(ev.type) { case Expose: if(ev.xexpose.count == 0) - mapdc(dc, win, mw, mh); + drw_map(drw, win, 0, 0, mw, mh); break; case KeyPress: keypress(&ev.xkey); @@ -522,7 +583,7 @@ run(void) { break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dc->dpy, win); + XRaiseWindow(dpy, win); break; } } @@ -530,47 +591,45 @@ run(void) { void setup(void) { - int x, y, screen = DefaultScreen(dc->dpy); - Window root = RootWindow(dc->dpy, screen); + int x, y; XSetWindowAttributes swa; XIM xim; #ifdef XINERAMA - int n; XineramaScreenInfo *info; + Window w, pw, dw, *dws; + XWindowAttributes wa; + int a, j, di, n, i = 0, area = 0; + unsigned int du; #endif - normcol[ColBG] = getcolor(dc, normbgcolor); - normcol[ColFG] = getcolor(dc, normfgcolor); - selcol[ColBG] = getcolor(dc, selbgcolor); - selcol[ColFG] = getcolor(dc, selfgcolor); - outcol[ColBG] = getcolor(dc, outbgcolor); - outcol[ColFG] = getcolor(dc, outfgcolor); + /* init appearance */ + scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor); + scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor); + scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); + scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); + scheme[SchemeOut].bg = drw_clr_create(drw, outbgcolor); + scheme[SchemeOut].fg = drw_clr_create(drw, outfgcolor); - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); /* calculate menu geometry */ - bh = dc->font.height + 2; + bh = drw->fonts[0]->h + 2; lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA - if((info = XineramaQueryScreens(dc->dpy, &n))) { - int a, j, di, i = 0, area = 0; - unsigned int du; - Window w, pw, dw, *dws; - XWindowAttributes wa; - - XGetInputFocus(dc->dpy, &w, &di); + if((info = XineramaQueryScreens(dpy, &n))) { + XGetInputFocus(dpy, &w, &di); if(mon != -1 && mon < n) i = mon; if(!i && w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ do { - if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) + if(XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) XFree(dws); } while(w != root && w != pw); /* find xinerama screen with which the window intersects most */ - if(XGetWindowAttributes(dc->dpy, pw, &wa)) + if(XGetWindowAttributes(dpy, pw, &wa)) for(j = 0; j < n; j++) if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { area = a; @@ -578,7 +637,7 @@ setup(void) { } } /* no focused window is on screen, so use pointer location instead */ - if(mon == -1 && !area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + if(mon == -1 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for(i = 0; i < n; i++) if(INTERSECT(x, y, 1, 1, info[i])) break; @@ -592,29 +651,29 @@ setup(void) { #endif { x = 0; - y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; - mw = DisplayWidth(dc->dpy, screen); + y = topbar ? 0 : sh - mh; + mw = sw; } - promptw = (prompt && *prompt) ? textw(dc, prompt) : 0; + promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; inputw = MIN(inputw, mw/3); match(); /* create menu window */ swa.override_redirect = True; - swa.background_pixel = normcol[ColBG]; + swa.background_pixel = scheme[SchemeNorm].bg->pix; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, - DefaultVisual(dc->dpy, screen), + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); /* open input methods */ - xim = XOpenIM(dc->dpy, NULL, NULL, NULL); + xim = XOpenIM(dpy, NULL, NULL, NULL); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); - XMapRaised(dc->dpy, win); - resizedc(dc, mw, mh); + XMapRaised(dpy, win); + drw_resize(drw, mw, mh); drawmenu(); } @@ -622,5 +681,5 @@ void usage(void) { fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); + exit(1); } diff --git a/dmenubar/draw.c b/dmenubar/draw.c deleted file mode 100644 index 76f0c54..0000000 --- a/dmenubar/draw.c +++ /dev/null @@ -1,177 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <locale.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <X11/Xlib.h> -#include "draw.h" - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define DEFAULTFN "fixed" - -static Bool loadfont(DC *dc, const char *fontstr); - -void -drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { - XSetForeground(dc->dpy, dc->gc, color); - if(fill) - XFillRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w, h); - else - XDrawRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w-1, h-1); -} - -void -drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - - /* shorten text if necessary */ - for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) + dc->font.height/2 > dc->w; mn--) - if(mn == 0) - return; - memcpy(buf, text, mn); - if(mn < n) - for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); - - drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); - drawtextn(dc, buf, mn, col); -} - -void -drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { - int x = dc->x + dc->font.height/2; - int y = dc->y + dc->font.ascent+1; - - XSetForeground(dc->dpy, dc->gc, FG(dc, col)); - if(dc->font.set) - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); - else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -} - -void -eprintf(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if(fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } - exit(EXIT_FAILURE); -} - -void -freedc(DC *dc) { - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); - if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - XFreeGC(dc->dpy, dc->gc); - XCloseDisplay(dc->dpy); - free(dc); -} - -unsigned long -getcolor(DC *dc, const char *colstr) { - Colormap cmap = DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)); - XColor color; - - if(!XAllocNamedColor(dc->dpy, cmap, colstr, &color, &color)) - eprintf("cannot allocate color '%s'\n", colstr); - return color.pixel; -} - -DC * -initdc(void) { - DC *dc; - - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("no locale support\n", stderr); - if(!(dc = calloc(1, sizeof *dc))) - eprintf("cannot malloc %u bytes:", sizeof *dc); - if(!(dc->dpy = XOpenDisplay(NULL))) - eprintf("cannot open display\n"); - - dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL); - XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); - return dc; -} - -void -initfont(DC *dc, const char *fontstr) { - if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { - if(fontstr != NULL) - fprintf(stderr, "cannot load font '%s'\n", fontstr); - if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) - eprintf("cannot load font '%s'\n", DEFAULTFN); - } - dc->font.height = dc->font.ascent + dc->font.descent; -} - -Bool -loadfont(DC *dc, const char *fontstr) { - char *def, **missing, **names; - int i, n; - XFontStruct **xfonts; - - if(!*fontstr) - return False; - if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { - n = XFontsOfFontSet(dc->font.set, &xfonts, &names); - for(i = 0; i < n; i++) { - dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); - dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); - dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); - } - } - else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { - dc->font.ascent = dc->font.xfont->ascent; - dc->font.descent = dc->font.xfont->descent; - dc->font.width = dc->font.xfont->max_bounds.width; - } - if(missing) - XFreeStringList(missing); - return dc->font.set || dc->font.xfont; -} - -void -mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { - XCopyArea(dc->dpy, dc->canvas, win, dc->gc, 0, 0, w, h, 0, 0); -} - -void -resizedc(DC *dc, unsigned int w, unsigned int h) { - if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); - - dc->w = w; - dc->h = h; - dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, - DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); -} - -int -textnw(DC *dc, const char *text, size_t len) { - if(dc->font.set) { - XRectangle r; - - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } - return XTextWidth(dc->font.xfont, text, len); -} - -int -textw(DC *dc, const char *text) { - return textnw(dc, text, strlen(text)) + dc->font.height; -} diff --git a/dmenubar/draw.h b/dmenubar/draw.h deleted file mode 100644 index 43a57bf..0000000 --- a/dmenubar/draw.h +++ /dev/null @@ -1,35 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -#define FG(dc, col) ((col)[(dc)->invert ? ColBG : ColFG]) -#define BG(dc, col) ((col)[(dc)->invert ? ColFG : ColBG]) - -enum { ColBG, ColFG, ColBorder, ColLast }; - -typedef struct { - int x, y, w, h; - Bool invert; - Display *dpy; - GC gc; - Pixmap canvas; - struct { - int ascent; - int descent; - int height; - int width; - XFontSet set; - XFontStruct *xfont; - } font; -} DC; /* draw context */ - -void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); -void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); -void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -void eprintf(const char *fmt, ...); -void freedc(DC *dc); -unsigned long getcolor(DC *dc, const char *colstr); -DC *initdc(void); -void initfont(DC *dc, const char *fontstr); -void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); -void resizedc(DC *dc, unsigned int w, unsigned int h); -int textnw(DC *dc, const char *text, size_t len); -int textw(DC *dc, const char *text); diff --git a/dmenubar/drw.c b/dmenubar/drw.c new file mode 100644 index 0000000..0423873 --- /dev/null +++ b/dmenubar/drw.c @@ -0,0 +1,413 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xft/Xft.h> + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) { + for(*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if(((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) { + if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for(i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) { + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if(!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if(!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if(type != 0) + return j; + } + if(j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { + Drw *drw = (Drw *)calloc(1, sizeof(Drw)); + if(!drw) + return NULL; + drw->dpy = dpy; + drw->screen = screen; + 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->fontcount = 0; + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) { + if(!drw) + return; + drw->w = w; + drw->h = h; + if(drw->drawable != 0) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); +} + +void +drw_free(Drw *drw) { + size_t i; + + for (i = 0; i < drw->fontcount; i++) { + drw_font_free(drw->fonts[i]); + } + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_font_create instead. + */ +static Fnt * +drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { + Fnt *font; + + if (!(fontname || fontpattern)) + die("No font specified.\n"); + + if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) + return NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield same + * the same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in + * missing-character-rectangles being drawn, at least with some fonts. + */ + if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) || + !(font->pattern = FcNameParse((FcChar8 *) fontname))) { + if (font->xfont) { + XftFontClose(drw->dpy, font->xfont); + font->xfont = NULL; + } + fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + } + } else if (fontpattern) { + if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font pattern.\n"); + } else { + font->pattern = NULL; + } + } + + if (!font->xfont) { + free(font); + return NULL; + } + + font->ascent = font->xfont->ascent; + font->descent = font->xfont->descent; + font->h = font->ascent + font->descent; + font->dpy = drw->dpy; + return font; +} + +Fnt* +drw_font_create(Drw *drw, const char *fontname) { + return drw_font_xcreate(drw, fontname, NULL); +} + +void +drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { + size_t i; + Fnt *font; + + for (i = 0; i < fontcount; i++) { + if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { + die("Font cache exhausted.\n"); + } else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) { + drw->fonts[drw->fontcount++] = font; + } + } +} + +void +drw_font_free(Fnt *font) { + if(!font) + return; + if(font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); + free(font); +} + +Clr * +drw_clr_create(Drw *drw, const char *clrname) { + Clr *clr; + Colormap cmap; + Visual *vis; + + if(!drw) + return NULL; + clr = (Clr *)calloc(1, sizeof(Clr)); + if(!clr) + return NULL; + cmap = DefaultColormap(drw->dpy, drw->screen); + vis = DefaultVisual(drw->dpy, drw->screen); + if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) + die("error, cannot allocate color '%s'\n", clrname); + clr->pix = clr->rgb.pixel; + return clr; +} + +void +drw_clr_free(Clr *clr) { + free(clr); +} + +void +drw_setscheme(Drw *drw, ClrScheme *scheme) { + if(!drw) + return; + drw->scheme = scheme; +} + +void +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) { + if(!drw || !drw->scheme) + return; + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); + if(filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); + else if(empty) + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); +} + +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) { + char buf[1024]; + int tx, ty, th; + Extnts tex; + Colormap cmap; + Visual *vis; + XftDraw *d; + Fnt *curfont, *nextfont; + size_t i, len; + int utf8strlen, utf8charlen, render; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0; + + if (!(render = x || y || w || h)) { + w = ~w; + } + + if (!drw || !drw->scheme) { + return 0; + } else if (render) { + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->pix : drw->scheme->bg->pix); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + } + + if (!text || !drw->fontcount) { + return 0; + } else if (render) { + cmap = DefaultColormap(drw->dpy, drw->screen); + vis = DefaultVisual(drw->dpy, drw->screen); + d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); + } + + curfont = drw->fonts[0]; + while (1) { + utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (i = 0; i < drw->fontcount; i++) { + charexists = charexists || XftCharExists(drw->dpy, drw->fonts[i]->xfont, utf8codepoint); + if (charexists) { + if (drw->fonts[i] == curfont) { + utf8strlen += utf8charlen; + text += utf8charlen; + } else { + nextfont = drw->fonts[i]; + } + break; + } + } + + if (!charexists || (nextfont && nextfont != curfont)) { + break; + } else { + charexists = 0; + } + } + + if (utf8strlen) { + drw_font_getexts(curfont, utf8str, utf8strlen, &tex); + /* shorten text if necessary */ + for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) + drw_font_getexts(curfont, utf8str, len, &tex); + + if (len) { + memcpy(buf, utf8str, len); + buf[len] = '\0'; + if(len < utf8strlen) + for(i = len; i && i > len - 3; buf[--i] = '.'); + + if (render) { + th = curfont->ascent + curfont->descent; + ty = y + (h / 2) - (th / 2) + curfont->ascent; + tx = x + (h / 2); + XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); + } + + x += tex.w; + w -= tex.w; + } + } + + if (!*text) { + break; + } else if (nextfont) { + charexists = 0; + curfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. + */ + charexists = 1; + + if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { + continue; + } + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts[0]->pattern) { + /* Refer to the comment in drw_font_xcreate for more + * information. + */ + die("The first font in the cache must be loaded from a font string.\n"); + } + + fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + curfont = drw_font_xcreate(drw, NULL, match); + if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { + drw->fonts[drw->fontcount++] = curfont; + } else { + if (curfont) { + drw_font_free(curfont); + } + curfont = drw->fonts[0]; + } + } + } + } + + if (render) { + XftDrawDestroy(d); + } + + return x; +} + +void +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { + if(!drw) + return; + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); + XSync(drw->dpy, False); +} + + +void +drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { + XGlyphInfo ext; + + if(!font || !text) + return; + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + tex->h = font->h; + tex->w = ext.xOff; +} + +unsigned int +drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) { + Extnts tex; + + if(!font) + return -1; + drw_font_getexts(font, text, len, &tex); + return tex.w; +} + +Cur * +drw_cur_create(Drw *drw, int shape) { + Cur *cur; + + if(!drw) + return NULL; + cur = (Cur *)calloc(1, sizeof(Cur)); + if (!cur) + return NULL; + cur->cursor = XCreateFontCursor(drw->dpy, shape); + return cur; +} + +void +drw_cur_free(Drw *drw, Cur *cursor) { + if(!drw || !cursor) + return; + XFreeCursor(drw->dpy, cursor->cursor); + free(cursor); +} diff --git a/dmenubar/drw.h b/dmenubar/drw.h new file mode 100644 index 0000000..536171b --- /dev/null +++ b/dmenubar/drw.h @@ -0,0 +1,74 @@ +/* See LICENSE file for copyright and license details. */ +#define DRW_FONT_CACHE_SIZE 32 + +typedef struct { + unsigned long pix; + XftColor rgb; +} Clr; + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct { + Display *dpy; + int ascent; + int descent; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; +} Fnt; + +typedef struct { + Clr *fg; + Clr *bg; + Clr *border; +} ClrScheme; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + GC gc; + ClrScheme *scheme; + size_t fontcount; + Fnt *fonts[DRW_FONT_CACHE_SIZE]; +} Drw; + +typedef struct { + unsigned int w; + unsigned int h; +} Extnts; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_font_create(Drw *drw, const char *fontname); +void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); +void drw_font_free(Fnt *font); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *extnts); +unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int len); + +/* Colour abstraction */ +Clr *drw_clr_create(Drw *drw, const char *clrname); +void drw_clr_free(Clr *clr); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfont(Drw *drw, Fnt *font); +void drw_setscheme(Drw *drw, ClrScheme *scheme); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/dmenubar/util.c b/dmenubar/util.c new file mode 100644 index 0000000..9b27512 --- /dev/null +++ b/dmenubar/util.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "util.h" + +void +die(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } + + exit(1); +} diff --git a/dmenubar/util.h b/dmenubar/util.h new file mode 100644 index 0000000..f7ce721 --- /dev/null +++ b/dmenubar/util.h @@ -0,0 +1,7 @@ +/* See LICENSE file for copyright and license details. */ + +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) + +void die(const char *errstr, ...); From 5205d3ee61dfbc341680e5808bf8b8925003705b Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 19 Jul 2015 20:29:26 +0200 Subject: [PATCH 489/590] fix prompt color style how it used to be This is the style how it was before the big Xft change. The colors were inverted, this was not the case before the change. Reported by "zvz" on #suckless IRC, thanks! --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 94be574..11b6e8d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -207,7 +207,7 @@ drawmenu(void) { if(prompt && *prompt) { drw_setscheme(drw, &scheme[SchemeSel]); - drw_text(drw, x, 0, promptw, bh, prompt, 1); + drw_text(drw, x, 0, promptw, bh, prompt, 0); x += promptw; } /* draw input field */ From aa6aca092d6a345f9462d20d132a8beb25459955 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 19 Jul 2015 20:32:08 +0200 Subject: [PATCH 490/590] config.mk: add FREETYPELIBS and FREETYPEINC These variables make it simpler to change the paths to this for ports. `pkg-config` is avoided because it sucks, in particular for cross-compilation. A commented path for *BSD is added, the Xft includes are located at: /usr/X11R6/include there. Also already bump the version number to 4.6, a release will come approximately in August. --- dmenubar/config.mk | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 4e62a09..95690f9 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.5-tip +VERSION = 4.6 # paths PREFIX = /usr/local @@ -12,9 +12,15 @@ X11LIB = /usr/X11R6/lib XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA +# freetype +FREETYPELIBS = -lfontconfig -lXft +FREETYPEINC = /usr/include/freetype2 +# OpenBSD (uncomment) +#FREETYPEINC = ${X11INC}/freetype2 + # includes and libs -INCS = -I${X11INC} -I/usr/include/freetype2 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -lfontconfig -lXft +INCS = -I${X11INC} -I${FREETYPEINC} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} From 2ee4123d1fad3cdd2526a0f3451535747264adb2 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 19 Jul 2015 21:34:51 +0200 Subject: [PATCH 491/590] stest: get rid of getopt, use suckless arg.h ... also some style improvements. --- dmenubar/Makefile | 6 +-- dmenubar/arg.h | 63 +++++++++++++++++++++++ dmenubar/stest.c | 125 +++++++++++++++++++++++++++------------------- 3 files changed, 141 insertions(+), 53 deletions(-) create mode 100644 dmenubar/arg.h diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 4a412ee..8f14a8c 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -22,7 +22,7 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -${OBJ}: config.h config.mk drw.h +${OBJ}: arg.h config.h config.mk drw.h dmenu: dmenu.o drw.o util.o @echo CC -o $@ @@ -39,8 +39,8 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 drw.h util.h dmenu_path \ - dmenu_run stest.1 ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README arg.h config.mk dmenu.1 drw.h util.h \ + dmenu_path dmenu_run stest.1 ${SRC} dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenubar/arg.h b/dmenubar/arg.h new file mode 100644 index 0000000..4df77a7 --- /dev/null +++ b/dmenubar/arg.h @@ -0,0 +1,63 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][1]\ + && argv[0][0] == '-';\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +/* Handles obsolete -NUM syntax */ +#define ARGNUM case '0':\ + case '1':\ + case '2':\ + case '3':\ + case '4':\ + case '5':\ + case '6':\ + case '7':\ + case '8':\ + case '9' + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/dmenubar/stest.c b/dmenubar/stest.c index 8fac42a..7a7b0bc 100644 --- a/dmenubar/stest.c +++ b/dmenubar/stest.c @@ -1,66 +1,31 @@ /* See LICENSE file for copyright and license details. */ +#include <sys/stat.h> + #include <dirent.h> -#include <stdbool.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <sys/stat.h> + +#include "arg.h" +char *argv0; #define FLAG(x) (flag[(x)-'a']) static void test(const char *, const char *); +static void usage(void); -static bool match = false; -static bool flag[26]; +static int match = 0; +static int flag[26]; static struct stat old, new; -int -main(int argc, char *argv[]) { - struct dirent *d; - char buf[BUFSIZ], *p; - DIR *dir; - int opt; - - while((opt = getopt(argc, argv, "abcdefghln:o:pqrsuvwx")) != -1) - switch(opt) { - case 'n': /* newer than file */ - case 'o': /* older than file */ - if(!(FLAG(opt) = !stat(optarg, (opt == 'n' ? &new : &old)))) - perror(optarg); - break; - default: /* miscellaneous operators */ - FLAG(opt) = true; - break; - case '?': /* error: unknown flag */ - fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] [-n file] [-o file] [file...]\n", argv[0]); - exit(2); - } - if(optind == argc) - while(fgets(buf, sizeof buf, stdin)) { - if((p = strchr(buf, '\n'))) - *p = '\0'; - test(buf, buf); - } - for(; optind < argc; optind++) - if(FLAG('l') && (dir = opendir(argv[optind]))) { - /* test directory contents */ - while((d = readdir(dir))) - if(snprintf(buf, sizeof buf, "%s/%s", argv[optind], d->d_name) < sizeof buf) - test(buf, d->d_name); - closedir(dir); - } - else - test(argv[optind], argv[optind]); - - return match ? 0 : 1; -} - -void -test(const char *path, const char *name) { +static void +test(const char *path, const char *name) +{ struct stat st, ln; - if((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ + if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ @@ -76,9 +41,69 @@ test(const char *path, const char *name) { && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */ && (!FLAG('w') || access(path, W_OK) == 0) /* writable */ && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */ - if(FLAG('q')) + if (FLAG('q')) exit(0); - match = true; + match = 1; puts(name); } } + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] " + "[-n file] [-o file] [file...]\n", argv0); + exit(2); /* like test(1) return > 1 on error */ +} + +int +main(int argc, char *argv[]) +{ + struct dirent *d; + char path[PATH_MAX], *line = NULL, *file; + size_t linesiz = 0; + ssize_t n; + DIR *dir; + int r; + + ARGBEGIN { + case 'n': /* newer than file */ + case 'o': /* older than file */ + file = EARGF(usage()); + if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old)))) + perror(file); + break; + default: + /* miscellaneous operators */ + if (strchr("abcdefghlpqrsuvwx", ARGC())) + FLAG(ARGC()) = 1; + else + usage(); /* unknown flag */ + } ARGEND; + + if (!argc) { + /* read list from stdin */ + while ((n = getline(&line, &linesiz, stdin)) > 0) { + if (n && line[n - 1] == '\n') + line[n - 1] = '\0'; + test(line, line); + } + free(line); + } else { + for (; argc; argc--, argv++) { + if (FLAG('l') && (dir = opendir(*argv))) { + /* test directory contents */ + while ((d = readdir(dir))) { + r = snprintf(path, sizeof path, "%s/%s", + *argv, d->d_name); + if (r >= 0 && (size_t)r < sizeof path) + test(path, d->d_name); + } + closedir(dir); + } else { + test(*argv, *argv); + } + } + } + return match ? 0 : 1; +} From 845d0098779e187df9100849c4e2c7b4ca39c7fd Mon Sep 17 00:00:00 2001 From: Eric Pruitt <eric.pruitt@gmail.com> Date: Wed, 5 Aug 2015 19:19:14 -0700 Subject: [PATCH 492/590] Fixed typo introduced by shared code --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 11b6e8d..f0bc176 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -118,7 +118,7 @@ main(int argc, char *argv[]) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); if(!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display\n"); + die("dmenu: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); sw = DisplayWidth(dpy, screen); From e8767b2e703aea7f5a62fb406a04593572fc0fa0 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 27 Sep 2015 22:38:14 +0200 Subject: [PATCH 493/590] config.mk: improve feature test check this fixes a crash on NetBSD because it requires -D_XOPEN_SOURCE (strdup, usleep). thanks k0ga and stateless for reporting and fixing this issue! --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 95690f9..7b08bf1 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -23,7 +23,7 @@ INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} From 9ca51863464b869313b7a984cee6c651b9c4cf12 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 27 Sep 2015 22:55:21 +0200 Subject: [PATCH 494/590] config.mk: fix _XOPEN_SOURCE=700 for getline() --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 7b08bf1..ea23da4 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -23,7 +23,7 @@ INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} From 046475f73ee423e79a3f192cb523c37a72857c46 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 27 Sep 2015 23:02:33 +0200 Subject: [PATCH 495/590] separate program-specific c99 bool and X11 True, False are X11-specific, make sure to use c99 stdbool for program-specific things. ... also remove left-over vim mode string in config. --- dmenubar/config.def.h | 6 ++---- dmenubar/dmenu.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 4e5e3e7..bc2dc40 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -1,9 +1,7 @@ /* See LICENSE file for copyright and license details. */ -/* vim: expandtab - */ -/* Default settings; can be overrided by command line. */ +/* Default settings; can be overriden by command line. */ -static Bool topbar = True; /* -b option; if False, dmenu appears at bottom */ +static bool topbar = true; /* -b option; if False, dmenu appears at bottom */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f0bc176..9e78e83 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <locale.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -31,7 +32,7 @@ typedef struct Item Item; struct Item { char *text; Item *left, *right; - Bool out; + bool out; }; static void appenditem(Item *item, Item **list, Item **last); @@ -76,7 +77,7 @@ static char *(*fstrstr)(const char *, const char *) = strstr; int main(int argc, char *argv[]) { - Bool fast = False; + bool fast = false; int i; for(i = 1; i < argc; i++) @@ -86,9 +87,9 @@ main(int argc, char *argv[]) { exit(0); } else if(!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ - topbar = False; + topbar = false; else if(!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = True; + fast = true; else if(!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; @@ -203,7 +204,7 @@ drawmenu(void) { int x = 0, y = 0, h = bh, w; drw_setscheme(drw, &scheme[SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, True, 1, 1); + drw_rect(drw, 0, 0, mw, mh, 1, 1, 1); if(prompt && *prompt) { drw_setscheme(drw, &scheme[SchemeSel]); @@ -432,7 +433,7 @@ keypress(XKeyEvent *ev) { exit(0); } if(sel) - sel->out = True; + sel->out = true; break; case XK_Right: if(text[cursor] != '\0') { @@ -552,7 +553,7 @@ readstdin(void) { *p = '\0'; if(!(items[i].text = strdup(buf))) die("cannot strdup %u bytes:", strlen(buf)+1); - items[i].out = False; + items[i].out = false; if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } From 7d4dff565a7ee79fbbc3f1b01484272453e98477 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 27 Sep 2015 23:56:02 +0200 Subject: [PATCH 496/590] drw style improvements this makes the code-style more consistent aswell. --- dmenubar/drw.c | 165 ++++++++++++++++++++++++++----------------------- dmenubar/drw.h | 34 +++++----- 2 files changed, 106 insertions(+), 93 deletions(-) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 0423873..6aeb59d 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -9,7 +9,7 @@ #include "util.h" #define UTF_INVALID 0xFFFD -#define UTF_SIZ 4 +#define UTF_SIZ 4 static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; @@ -17,49 +17,55 @@ static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000 static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; static long -utf8decodebyte(const char c, size_t *i) { - for(*i = 0; *i < (UTF_SIZ + 1); ++(*i)) - if(((unsigned char)c & utfmask[*i]) == utfbyte[*i]) +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) return (unsigned char)c & ~utfmask[*i]; return 0; } static size_t -utf8validate(long *u, size_t i) { - if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) *u = UTF_INVALID; - for(i = 1; *u > utfmax[i]; ++i) + for (i = 1; *u > utfmax[i]; ++i) ; return i; } static size_t -utf8decode(const char *c, long *u, size_t clen) { +utf8decode(const char *c, long *u, size_t clen) +{ size_t i, j, len, type; long udecoded; *u = UTF_INVALID; - if(!clen) + if (!clen) return 0; udecoded = utf8decodebyte(c[0], &len); - if(!BETWEEN(len, 1, UTF_SIZ)) + if (!BETWEEN(len, 1, UTF_SIZ)) return 1; - for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); - if(type != 0) + if (type) return j; } - if(j < len) + if (j < len) return 0; *u = udecoded; utf8validate(u, len); + return len; } Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) { - Drw *drw = (Drw *)calloc(1, sizeof(Drw)); - if(!drw) +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw; + + if (!(drw = calloc(1, sizeof(Drw)))) return NULL; drw->dpy = dpy; drw->screen = screen; @@ -70,27 +76,29 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->gc = XCreateGC(dpy, root, 0, NULL); drw->fontcount = 0; XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + return drw; } void -drw_resize(Drw *drw, unsigned int w, unsigned int h) { - if(!drw) +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) return; drw->w = w; drw->h = h; - if(drw->drawable != 0) + if (drw->drawable) XFreePixmap(drw->dpy, drw->drawable); drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); } void -drw_free(Drw *drw) { +drw_free(Drw *drw) +{ size_t i; - for (i = 0; i < drw->fontcount; i++) { + for (i = 0; i < drw->fontcount; i++) drw_font_free(drw->fonts[i]); - } XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); free(drw); @@ -100,13 +108,14 @@ drw_free(Drw *drw) { * drw_font_create instead. */ static Fnt * -drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { +drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ Fnt *font; if (!(fontname || fontpattern)) die("No font specified.\n"); - if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) + if (!(font = calloc(1, sizeof(Fnt)))) return NULL; if (fontname) { @@ -125,11 +134,10 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { fprintf(stderr, "error, cannot load font: '%s'\n", fontname); } } else if (fontpattern) { - if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) fprintf(stderr, "error, cannot load font pattern.\n"); - } else { + else font->pattern = NULL; - } } if (!font->xfont) { @@ -141,16 +149,19 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { font->descent = font->xfont->descent; font->h = font->ascent + font->descent; font->dpy = drw->dpy; + return font; } Fnt* -drw_font_create(Drw *drw, const char *fontname) { +drw_font_create(Drw *drw, const char *fontname) +{ return drw_font_xcreate(drw, fontname, NULL); } void -drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { +drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) +{ size_t i; Fnt *font; @@ -164,59 +175,65 @@ drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { } void -drw_font_free(Fnt *font) { - if(!font) +drw_font_free(Fnt *font) +{ + if (!font) return; - if(font->pattern) + if (font->pattern) FcPatternDestroy(font->pattern); XftFontClose(font->dpy, font->xfont); free(font); } Clr * -drw_clr_create(Drw *drw, const char *clrname) { +drw_clr_create(Drw *drw, const char *clrname) +{ Clr *clr; Colormap cmap; Visual *vis; - if(!drw) + if (!drw) return NULL; - clr = (Clr *)calloc(1, sizeof(Clr)); - if(!clr) + if (!(clr = calloc(1, sizeof(Clr)))) return NULL; cmap = DefaultColormap(drw->dpy, drw->screen); vis = DefaultVisual(drw->dpy, drw->screen); - if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) + if (!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) die("error, cannot allocate color '%s'\n", clrname); clr->pix = clr->rgb.pixel; + return clr; } void -drw_clr_free(Clr *clr) { +drw_clr_free(Clr *clr) +{ free(clr); } void -drw_setscheme(Drw *drw, ClrScheme *scheme) { - if(!drw) +drw_setscheme(Drw *drw, ClrScheme *scheme) +{ + if (!drw) return; drw->scheme = scheme; } void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) { - if(!drw || !drw->scheme) +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) +{ + if (!drw || !drw->scheme) return; XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); - if(filled) + if (filled) XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); - else if(empty) + else if (empty) XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); } int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) { +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) +{ char buf[1024]; int tx, ty, th; Extnts tex; @@ -234,9 +251,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex XftResult result; int charexists = 0; - if (!(render = x || y || w || h)) { + if (!(render = x || y || w || h)) w = ~w; - } if (!drw || !drw->scheme) { return 0; @@ -273,24 +289,23 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex } } - if (!charexists || (nextfont && nextfont != curfont)) { + if (!charexists || (nextfont && nextfont != curfont)) break; - } else { + else charexists = 0; - } } if (utf8strlen) { drw_font_getexts(curfont, utf8str, utf8strlen, &tex); /* shorten text if necessary */ - for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) + for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) drw_font_getexts(curfont, utf8str, len, &tex); if (len) { memcpy(buf, utf8str, len); buf[len] = '\0'; - if(len < utf8strlen) - for(i = len; i && i > len - 3; buf[--i] = '.'); + if (len < utf8strlen) + for (i = len; i && i > len - 3; buf[--i] = '.'); if (render) { th = curfont->ascent + curfont->descent; @@ -298,7 +313,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex tx = x + (h / 2); XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); } - x += tex.w; w -= tex.w; } @@ -315,17 +329,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex */ charexists = 1; - if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { + if (drw->fontcount >= DRW_FONT_CACHE_SIZE) continue; - } fccharset = FcCharSetCreate(); FcCharSetAddChar(fccharset, utf8codepoint); if (!drw->fonts[0]->pattern) { /* Refer to the comment in drw_font_xcreate for more - * information. - */ + * information. */ die("The first font in the cache must be loaded from a font string.\n"); } @@ -345,36 +357,34 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { drw->fonts[drw->fontcount++] = curfont; } else { - if (curfont) { + if (curfont) drw_font_free(curfont); - } curfont = drw->fonts[0]; } } } } - - if (render) { + if (render) XftDrawDestroy(d); - } return x; } void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { - if(!drw) +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ + if (!drw) return; XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); XSync(drw->dpy, False); } - void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { +drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) +{ XGlyphInfo ext; - if(!font || !text) + if (!font || !text) return; XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); tex->h = font->h; @@ -382,31 +392,34 @@ drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { } unsigned int -drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) { +drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) +{ Extnts tex; - if(!font) + if (!font) return -1; drw_font_getexts(font, text, len, &tex); return tex.w; } Cur * -drw_cur_create(Drw *drw, int shape) { +drw_cur_create(Drw *drw, int shape) +{ Cur *cur; - if(!drw) + if (!drw) return NULL; - cur = (Cur *)calloc(1, sizeof(Cur)); - if (!cur) + if (!(cur = calloc(1, sizeof(Cur)))) return NULL; cur->cursor = XCreateFontCursor(drw->dpy, shape); + return cur; } void -drw_cur_free(Drw *drw, Cur *cursor) { - if(!drw || !cursor) +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!drw || !cursor) return; XFreeCursor(drw->dpy, cursor->cursor); free(cursor); diff --git a/dmenubar/drw.h b/dmenubar/drw.h index 536171b..e3b8515 100644 --- a/dmenubar/drw.h +++ b/dmenubar/drw.h @@ -43,32 +43,32 @@ typedef struct { } Extnts; /* Drawable abstraction */ -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); -void drw_resize(Drw *drw, unsigned int w, unsigned int h); -void drw_free(Drw *drw); +Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); +void drw_resize(Drw *, unsigned int, unsigned int); +void drw_free(Drw *); /* Fnt abstraction */ -Fnt *drw_font_create(Drw *drw, const char *fontname); -void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); -void drw_font_free(Fnt *font); -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *extnts); -unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int len); +Fnt *drw_font_create(Drw *, const char *); +void drw_load_fonts(Drw *, const char *[], size_t); +void drw_font_free(Fnt *); +void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); +unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int); /* Colour abstraction */ -Clr *drw_clr_create(Drw *drw, const char *clrname); -void drw_clr_free(Clr *clr); +Clr *drw_clr_create(Drw *, const char *); +void drw_clr_free(Clr *); /* Cursor abstraction */ -Cur *drw_cur_create(Drw *drw, int shape); -void drw_cur_free(Drw *drw, Cur *cursor); +Cur *drw_cur_create(Drw *, int); +void drw_cur_free(Drw *, Cur *); /* Drawing context manipulation */ -void drw_setfont(Drw *drw, Fnt *font); -void drw_setscheme(Drw *drw, ClrScheme *scheme); +void drw_setfont(Drw *, Fnt *); +void drw_setscheme(Drw *, ClrScheme *); /* Drawing functions */ -void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert); -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert); +void drw_rect(Drw *, int, int, unsigned int, unsigned int, int, int, int); +int drw_text(Drw *, int, int, unsigned int, unsigned int, const char *, int); /* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); +void drw_map(Drw *, Window, int, int, unsigned int, unsigned int); From 803f9e4e30ff1e8a100de62d3bc225e9100a2cde Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 27 Sep 2015 23:57:39 +0200 Subject: [PATCH 497/590] dmenu: style improvements - move main to bottom, usage above main. - dont use variable names with function prototypes. - space before if, for, while, etc: 'if(' -> 'if ('. this makes the code-style more consistent --- dmenubar/dmenu.c | 417 ++++++++++++++++++++++++----------------------- 1 file changed, 213 insertions(+), 204 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9e78e83..49a6583 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -35,16 +35,16 @@ struct Item { bool out; }; -static void appenditem(Item *item, Item **list, Item **last); +static void appenditem(Item *, Item **, Item **); static void calcoffsets(void); -static char *cistrstr(const char *s, const char *sub); +static char *cistrstr(const char *, const char *); static void cleanup(void); static void drawmenu(void); static void grabkeyboard(void); -static void insert(const char *str, ssize_t n); -static void keypress(XKeyEvent *ev); +static void insert(const char *, ssize_t); +static void keypress(XKeyEvent *); static void match(void); -static size_t nextrune(int inc); +static size_t nextrune(int); static void paste(void); static void readstdin(void); static void run(void); @@ -53,100 +53,31 @@ static void usage(void); static char text[BUFSIZ] = ""; static int bh, mw, mh; +static int sw, sh; /* X display screen geometry width, height */ static int inputw, promptw; -static size_t cursor = 0; -static Atom clip, utf8; +static size_t cursor; static Item *items = NULL; static Item *matches, *matchend; static Item *prev, *curr, *next, *sel; -static Window win; +static int mon = -1, screen; + +static Atom clip, utf8; +static Display *dpy; +static Window root, win; static XIC xic; -static int mon = -1; static ClrScheme scheme[SchemeLast]; -static Display *dpy; -static int screen; -static Window root; static Drw *drw; -static int sw, sh; /* X display screen geometry width, height */ #include "config.h" static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; -int -main(int argc, char *argv[]) { - bool fast = false; - int i; - - for(i = 1; i < argc; i++) - /* these options take no arguments */ - if(!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION", © 2006-2015 dmenu engineers, see LICENSE for details"); - exit(0); - } - else if(!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ - topbar = false; - else if(!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = true; - else if(!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } - else if(i+1 == argc) - usage(); - /* these options take one argument */ - else if(!strcmp(argv[i], "-l")) /* number of lines in vertical list */ - lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-m")) - mon = atoi(argv[++i]); - else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; - else if(!strcmp(argv[i], "-fn")) /* font or font set */ - fonts[0] = argv[++i]; - else if(!strcmp(argv[i], "-nb")) /* normal background color */ - normbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-nf")) /* normal foreground color */ - normfgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sb")) /* selected background color */ - selbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sf")) /* selected foreground color */ - selfgcolor = argv[++i]; - else - usage(); - - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - if(!(dpy = XOpenDisplay(NULL))) - die("dmenu: cannot open display\n"); - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); - drw_load_fonts(drw, fonts, LENGTH(fonts)); - if(!drw->fontcount) - die("No fonts could be loaded.\n"); - drw_setscheme(drw, &scheme[SchemeNorm]); - - if(fast) { - grabkeyboard(); - readstdin(); - } - else { - readstdin(); - grabkeyboard(); - } - setup(); - run(); - - return 1; /* unreachable */ -} - -void -appenditem(Item *item, Item **list, Item **last) { - if(*last) +static void +appenditem(Item *item, Item **list, Item **last) +{ + if (*last) (*last)->right = item; else *list = item; @@ -156,25 +87,27 @@ appenditem(Item *item, Item **list, Item **last) { *last = item; } -void -calcoffsets(void) { +static void +calcoffsets(void) +{ int i, n; - if(lines > 0) + if (lines > 0) n = lines * bh; else n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ - for(i = 0, next = curr; next; next = next->right) - if((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) + for (i = 0, next = curr; next; next = next->right) + if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) break; - for(i = 0, prev = curr; prev && prev->left; prev = prev->left) - if((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) + for (i = 0, prev = curr; prev && prev->left; prev = prev->left) + if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) break; } -void -cleanup(void) { +static void +cleanup(void) +{ XUngrabKey(dpy, AnyKey, AnyModifier, root); drw_clr_free(scheme[SchemeNorm].bg); drw_clr_free(scheme[SchemeNorm].fg); @@ -187,18 +120,20 @@ cleanup(void) { XCloseDisplay(dpy); } -char * -cistrstr(const char *s, const char *sub) { +static char * +cistrstr(const char *s, const char *sub) +{ size_t len; - for(len = strlen(sub); *s; s++) - if(!strncasecmp(s, sub, len)) + for (len = strlen(sub); *s; s++) + if (!strncasecmp(s, sub, len)) return (char *)s; return NULL; } -void -drawmenu(void) { +static void +drawmenu(void) +{ int curpos; Item *item; int x = 0, y = 0, h = bh, w; @@ -206,7 +141,7 @@ drawmenu(void) { drw_setscheme(drw, &scheme[SchemeNorm]); drw_rect(drw, 0, 0, mw, mh, 1, 1, 1); - if(prompt && *prompt) { + if (prompt && *prompt) { drw_setscheme(drw, &scheme[SchemeSel]); drw_text(drw, x, 0, promptw, bh, prompt, 0); x += promptw; @@ -216,41 +151,40 @@ drawmenu(void) { drw_setscheme(drw, &scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, text, 0); - if((curpos = TEXTNW(text, cursor) + bh/2 - 2) < w) { + if ((curpos = TEXTNW(text, cursor) + bh / 2 - 2) < w) { drw_setscheme(drw, &scheme[SchemeNorm]); drw_rect(drw, x + curpos + 2, 2, 1, bh - 4, 1, 1, 0); } - if(lines > 0) { + if (lines > 0) { /* draw vertical list */ w = mw - x; - for(item = curr; item != next; item = item->right) { + for (item = curr; item != next; item = item->right) { y += h; - if(item == sel) + if (item == sel) drw_setscheme(drw, &scheme[SchemeSel]); - else if(item->out) + else if (item->out) drw_setscheme(drw, &scheme[SchemeOut]); else drw_setscheme(drw, &scheme[SchemeNorm]); drw_text(drw, x, y, w, bh, item->text, 0); } - } - else if(matches) { + } else if (matches) { /* draw horizontal list */ x += inputw; w = TEXTW("<"); - if(curr->left) { + if (curr->left) { drw_setscheme(drw, &scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, "<", 0); } - for(item = curr; item != next; item = item->right) { + for (item = curr; item != next; item = item->right) { x += w; w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); - if(item == sel) + if (item == sel) drw_setscheme(drw, &scheme[SchemeSel]); - else if(item->out) + else if (item->out) drw_setscheme(drw, &scheme[SchemeOut]); else drw_setscheme(drw, &scheme[SchemeNorm]); @@ -258,7 +192,7 @@ drawmenu(void) { } w = TEXTW(">"); x = mw - w; - if(next) { + if (next) { drw_setscheme(drw, &scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, ">", 0); } @@ -266,13 +200,14 @@ drawmenu(void) { drw_map(drw, win, 0, 0, mw, mh); } -void -grabkeyboard(void) { +static void +grabkeyboard(void) +{ int i; /* 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, + for (i = 0; i < 1000; i++) { + if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) return; usleep(1000); @@ -280,29 +215,31 @@ grabkeyboard(void) { die("cannot grab keyboard\n"); } -void -insert(const char *str, ssize_t n) { - if(strlen(text) + n > sizeof text - 1) +static void +insert(const char *str, ssize_t n) +{ + if (strlen(text) + n > sizeof text - 1) return; /* 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) + if (n > 0) memcpy(&text[cursor], str, n); cursor += n; match(); } -void -keypress(XKeyEvent *ev) { +static void +keypress(XKeyEvent *ev) +{ char buf[32]; int len; KeySym ksym = NoSymbol; Status status; len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - if(status == XBufferOverflow) + if (status == XBufferOverflow) return; - if(ev->state & ControlMask) + if (ev->state & ControlMask) switch(ksym) { case XK_a: ksym = XK_Home; break; case XK_b: ksym = XK_Left; break; @@ -328,9 +265,9 @@ keypress(XKeyEvent *ev) { insert(NULL, 0 - cursor); break; case XK_w: /* delete word */ - while(cursor > 0 && text[nextrune(-1)] == ' ') + while (cursor > 0 && text[nextrune(-1)] == ' ') insert(NULL, nextrune(-1) - cursor); - while(cursor > 0 && text[nextrune(-1)] != ' ') + while (cursor > 0 && text[nextrune(-1)] != ' ') insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ @@ -346,7 +283,7 @@ keypress(XKeyEvent *ev) { default: return; } - else if(ev->state & Mod1Mask) + else if (ev->state & Mod1Mask) switch(ksym) { case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; @@ -359,31 +296,31 @@ keypress(XKeyEvent *ev) { } switch(ksym) { default: - if(!iscntrl(*buf)) + if (!iscntrl(*buf)) insert(buf, len); break; case XK_Delete: - if(text[cursor] == '\0') + if (text[cursor] == '\0') return; cursor = nextrune(+1); /* fallthrough */ case XK_BackSpace: - if(cursor == 0) + if (cursor == 0) return; insert(NULL, nextrune(-1) - cursor); break; case XK_End: - if(text[cursor] != '\0') { + if (text[cursor] != '\0') { cursor = strlen(text); break; } - if(next) { + if (next) { /* jump to end of list and position items in reverse */ curr = matchend; calcoffsets(); curr = prev; calcoffsets(); - while(next && (curr = curr->right)) + while (next && (curr = curr->right)) calcoffsets(); } sel = matchend; @@ -392,7 +329,7 @@ keypress(XKeyEvent *ev) { cleanup(); exit(1); case XK_Home: - if(sel == matches) { + if (sel == matches) { cursor = 0; break; } @@ -400,27 +337,27 @@ keypress(XKeyEvent *ev) { calcoffsets(); break; case XK_Left: - if(cursor > 0 && (!sel || !sel->left || lines > 0)) { + if (cursor > 0 && (!sel || !sel->left || lines > 0)) { cursor = nextrune(-1); break; } - if(lines > 0) + if (lines > 0) return; /* fallthrough */ case XK_Up: - if(sel && sel->left && (sel = sel->left)->right == curr) { + if (sel && sel->left && (sel = sel->left)->right == curr) { curr = prev; calcoffsets(); } break; case XK_Next: - if(!next) + if (!next) return; sel = curr = next; calcoffsets(); break; case XK_Prior: - if(!prev) + if (!prev) return; sel = curr = prev; calcoffsets(); @@ -428,29 +365,29 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if(!(ev->state & ControlMask)) { + if (!(ev->state & ControlMask)) { cleanup(); exit(0); } - if(sel) + if (sel) sel->out = true; break; case XK_Right: - if(text[cursor] != '\0') { + if (text[cursor] != '\0') { cursor = nextrune(+1); break; } - if(lines > 0) + if (lines > 0) return; /* fallthrough */ case XK_Down: - if(sel && sel->right && (sel = sel->right) == next) { + if (sel && sel->right && (sel = sel->right) == next) { curr = next; calcoffsets(); } break; case XK_Tab: - if(!sel) + if (!sel) return; strncpy(text, sel->text, sizeof text - 1); text[sizeof text - 1] = '\0'; @@ -461,8 +398,9 @@ keypress(XKeyEvent *ev) { drawmenu(); } -void -match(void) { +static void +match(void) +{ static char **tokv = NULL; static int tokn = 0; @@ -473,41 +411,39 @@ match(void) { strcpy(buf, text); /* separate input text into tokens to be matched individually */ - for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) - if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) + for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) + if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) die("cannot realloc %u bytes\n", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - for(item = items; item && item->text; item++) { - for(i = 0; i < tokc; i++) - if(!fstrstr(item->text, tokv[i])) + for (item = items; item && item->text; item++) { + for (i = 0; i < tokc; i++) + if (!fstrstr(item->text, tokv[i])) break; - if(i != tokc) /* not all tokens match */ + if (i != tokc) /* not all tokens match */ continue; /* exact matches go first, then prefixes, then substrings */ - if(!tokc || !fstrncmp(tokv[0], item->text, len+1)) + if (!tokc || !fstrncmp(tokv[0], item->text, len + 1)) appenditem(item, &matches, &matchend); - else if(!fstrncmp(tokv[0], item->text, len)) + else if (!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); else appenditem(item, &lsubstr, &substrend); } - if(lprefix) { - if(matches) { + if (lprefix) { + if (matches) { matchend->right = lprefix; lprefix->left = matchend; - } - else + } else matches = lprefix; matchend = prefixend; } - if(lsubstr) { - if(matches) { + if (lsubstr) { + if (matches) { matchend->right = lsubstr; lsubstr->left = matchend; - } - else + } else matches = lsubstr; matchend = substrend; } @@ -515,17 +451,20 @@ match(void) { calcoffsets(); } -size_t -nextrune(int inc) { +static size_t +nextrune(int inc) +{ ssize_t n; /* return location of next utf8 rune in the given direction (+1 or -1) */ - for(n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc); + for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) + ; return n; } -void -paste(void) { +static void +paste(void) +{ char *p, *q; int di; unsigned long dl; @@ -534,64 +473,67 @@ paste(void) { /* we have been given the current selection, now insert it into input */ XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, utf8, &da, &di, &dl, &dl, (unsigned char **)&p); - insert(p, (q = strchr(p, '\n')) ? q-p : (ssize_t)strlen(p)); + insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); XFree(p); drawmenu(); } -void -readstdin(void) { +static void +readstdin(void) +{ char buf[sizeof text], *p, *maxstr = NULL; size_t i, max = 0, size = 0; /* 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) - if(!(items = realloc(items, (size += BUFSIZ)))) + for (i = 0; fgets(buf, sizeof buf, stdin); i++) { + if (i + 1 >= size / sizeof *items) + if (!(items = realloc(items, (size += BUFSIZ)))) die("cannot realloc %u bytes:", size); - if((p = strchr(buf, '\n'))) + if ((p = strchr(buf, '\n'))) *p = '\0'; - if(!(items[i].text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf)+1); + if (!(items[i].text = strdup(buf))) + die("cannot strdup %u bytes:", strlen(buf) + 1); items[i].out = false; - if(strlen(items[i].text) > max) + if (strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } - if(items) + if (items) items[i].text = NULL; inputw = maxstr ? TEXTW(maxstr) : 0; lines = MIN(lines, i); } -void -run(void) { +static void +run(void) +{ XEvent ev; - while(!XNextEvent(dpy, &ev)) { - if(XFilterEvent(&ev, win)) + while (!XNextEvent(dpy, &ev)) { + if (XFilterEvent(&ev, win)) continue; switch(ev.type) { case Expose: - if(ev.xexpose.count == 0) + if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); break; case KeyPress: keypress(&ev.xkey); break; case SelectionNotify: - if(ev.xselection.property == utf8) + if (ev.xselection.property == utf8) paste(); break; case VisibilityNotify: - if(ev.xvisibility.state != VisibilityUnobscured) + if (ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); break; } } } -void -setup(void) { +static void +setup(void) +{ int x, y; XSetWindowAttributes swa; XIM xim; @@ -619,36 +561,35 @@ setup(void) { lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA - if((info = XineramaQueryScreens(dpy, &n))) { + if ((info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); - if(mon != -1 && mon < n) + if (mon != -1 && mon < n) i = mon; - if(!i && w != root && w != PointerRoot && w != None) { + if (!i && w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ do { - if(XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) + if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) XFree(dws); - } while(w != root && w != pw); + } while (w != root && w != pw); /* find xinerama screen with which the window intersects most */ - if(XGetWindowAttributes(dpy, pw, &wa)) - for(j = 0; j < n; j++) - if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { + if (XGetWindowAttributes(dpy, pw, &wa)) + for (j = 0; j < n; j++) + if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { area = a; i = j; } } /* no focused window is on screen, so use pointer location instead */ - if(mon == -1 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) - for(i = 0; i < n; i++) - if(INTERSECT(x, y, 1, 1, info[i])) + if (mon == -1 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + for (i = 0; i < n; i++) + if (INTERSECT(x, y, 1, 1, info[i])) break; x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; XFree(info); - } - else + } else #endif { x = 0; @@ -678,9 +619,77 @@ setup(void) { drawmenu(); } -void -usage(void) { +static void +usage(void) +{ fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(1); } + +int +main(int argc, char *argv[]) +{ + bool fast = false; + int i; + + for (i = 1; i < argc; i++) + /* these options take no arguments */ + if (!strcmp(argv[i], "-v")) { /* prints version information */ + puts("dmenu-"VERSION); + exit(0); + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ + topbar = false; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = true; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ + else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ + lines = atoi(argv[++i]); + else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ + prompt = argv[++i]; + else if (!strcmp(argv[i], "-fn")) /* font or font set */ + fonts[0] = argv[++i]; + else if (!strcmp(argv[i], "-nb")) /* normal background color */ + normbgcolor = argv[++i]; + else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ + normfgcolor = argv[++i]; + else if (!strcmp(argv[i], "-sb")) /* selected background color */ + selbgcolor = argv[++i]; + else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ + selfgcolor = argv[++i]; + else + usage(); + + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("cannot open display\n"); + screen = DefaultScreen(dpy); + root = RootWindow(dpy, screen); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + drw_load_fonts(drw, fonts, LENGTH(fonts)); + if (!drw->fontcount) + die("no fonts could be loaded.\n"); + drw_setscheme(drw, &scheme[SchemeNorm]); + + if (fast) { + grabkeyboard(); + readstdin(); + } else { + readstdin(); + grabkeyboard(); + } + setup(); + run(); + + return 1; /* unreachable */ +} From c5ff29c1bf56ee4ab0628b7bb12aeaf36f2a7764 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Mon, 28 Sep 2015 00:02:28 +0200 Subject: [PATCH 498/590] config.mk: use -std=c99 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index ea23da4..faea37f 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -24,7 +24,7 @@ LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags CPPFLAGS = -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} # compiler and linker From 57c147c7dd9e919b8d44241645d1aff82370a9ba Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Mon, 28 Sep 2015 00:06:05 +0200 Subject: [PATCH 499/590] Replace deprecated usleep() with nanosleep() --- dmenubar/dmenu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 49a6583..aa6e5d8 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -6,7 +6,7 @@ #include <stdlib.h> #include <string.h> #include <strings.h> -#include <unistd.h> +#include <time.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <X11/Xutil.h> @@ -203,6 +203,7 @@ drawmenu(void) static void grabkeyboard(void) { + struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 }; int i; /* try to grab keyboard, we may have to wait for another process to ungrab */ @@ -210,7 +211,7 @@ grabkeyboard(void) if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) return; - usleep(1000); + nanosleep(&ts, NULL); } die("cannot grab keyboard\n"); } From 84184ff29d0a306467f20bcd9b04c8c0a4c0458d Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Mon, 28 Sep 2015 00:18:35 +0200 Subject: [PATCH 500/590] Fix the conversion from microseconds to nanoseconds --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index aa6e5d8..cf5d976 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -203,7 +203,7 @@ drawmenu(void) static void grabkeyboard(void) { - struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 }; + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; int i; /* try to grab keyboard, we may have to wait for another process to ungrab */ From 0afc13c10d42af53a6e8d6d591bfd1068da62efc Mon Sep 17 00:00:00 2001 From: FRIGN <dev@frign.de> Date: Mon, 28 Sep 2015 00:15:03 +0200 Subject: [PATCH 501/590] Untypedef struct item Adds clarity. Typedefs for structs are definitely a discussion matter, but there's no reason to hide a simple data-structure behind a meaningless typedef. --- dmenubar/dmenu.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index cf5d976..050b858 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -28,14 +28,13 @@ /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ -typedef struct Item Item; -struct Item { +struct item { char *text; - Item *left, *right; + struct item *left, *right; bool out; }; -static void appenditem(Item *, Item **, Item **); +static void appenditem(struct item *, struct item **, struct item **); static void calcoffsets(void); static char *cistrstr(const char *, const char *); static void cleanup(void); @@ -56,9 +55,9 @@ static int bh, mw, mh; static int sw, sh; /* X display screen geometry width, height */ static int inputw, promptw; static size_t cursor; -static Item *items = NULL; -static Item *matches, *matchend; -static Item *prev, *curr, *next, *sel; +static struct item *items = NULL; +static struct item *matches, *matchend; +static struct item *prev, *curr, *next, *sel; static int mon = -1, screen; static Atom clip, utf8; @@ -75,7 +74,7 @@ static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; static void -appenditem(Item *item, Item **list, Item **last) +appenditem(struct item *item, struct item **list, struct item **last) { if (*last) (*last)->right = item; @@ -135,7 +134,7 @@ static void drawmenu(void) { int curpos; - Item *item; + struct item *item; int x = 0, y = 0, h = bh, w; drw_setscheme(drw, &scheme[SchemeNorm]); @@ -408,7 +407,7 @@ match(void) char buf[sizeof text], *s; int i, tokc = 0; size_t len; - Item *item, *lprefix, *lsubstr, *prefixend, *substrend; + struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; strcpy(buf, text); /* separate input text into tokens to be matched individually */ From 8a309cbf3fd68a9bbfad21e78e533c699ca8a54e Mon Sep 17 00:00:00 2001 From: FRIGN <dev@frign.de> Date: Mon, 28 Sep 2015 00:19:36 +0200 Subject: [PATCH 502/590] Remove function prototypes and reorder functions accordingly --- dmenubar/dmenu.c | 144 +++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 80 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 050b858..32a8330 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -34,22 +34,6 @@ struct item { bool out; }; -static void appenditem(struct item *, struct item **, struct item **); -static void calcoffsets(void); -static char *cistrstr(const char *, const char *); -static void cleanup(void); -static void drawmenu(void); -static void grabkeyboard(void); -static void insert(const char *, ssize_t); -static void keypress(XKeyEvent *); -static void match(void); -static size_t nextrune(int); -static void paste(void); -static void readstdin(void); -static void run(void); -static void setup(void); -static void usage(void); - static char text[BUFSIZ] = ""; static int bh, mw, mh; static int sw, sh; /* X display screen geometry width, height */ @@ -215,6 +199,59 @@ grabkeyboard(void) die("cannot grab keyboard\n"); } +static void +match(void) +{ + static char **tokv = NULL; + static int tokn = 0; + + char buf[sizeof text], *s; + int i, tokc = 0; + size_t len; + struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; + + strcpy(buf, text); + /* separate input text into tokens to be matched individually */ + for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) + if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) + die("cannot realloc %u bytes\n", tokn * sizeof *tokv); + len = tokc ? strlen(tokv[0]) : 0; + + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + for (item = items; item && item->text; item++) { + for (i = 0; i < tokc; i++) + if (!fstrstr(item->text, tokv[i])) + break; + if (i != tokc) /* not all tokens match */ + continue; + /* exact matches go first, then prefixes, then substrings */ + if (!tokc || !fstrncmp(tokv[0], item->text, len + 1)) + appenditem(item, &matches, &matchend); + else if (!fstrncmp(tokv[0], item->text, len)) + appenditem(item, &lprefix, &prefixend); + else + appenditem(item, &lsubstr, &substrend); + } + if (lprefix) { + if (matches) { + matchend->right = lprefix; + lprefix->left = matchend; + } else + matches = lprefix; + matchend = prefixend; + } + if (lsubstr) { + if (matches) { + matchend->right = lsubstr; + lsubstr->left = matchend; + } else + matches = lsubstr; + matchend = substrend; + } + curr = sel = matches; + calcoffsets(); +} + static void insert(const char *str, ssize_t n) { @@ -228,6 +265,17 @@ insert(const char *str, ssize_t n) match(); } +static size_t +nextrune(int inc) +{ + ssize_t n; + + /* return location of next utf8 rune in the given direction (+1 or -1) */ + for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) + ; + return n; +} + static void keypress(XKeyEvent *ev) { @@ -398,70 +446,6 @@ keypress(XKeyEvent *ev) drawmenu(); } -static void -match(void) -{ - static char **tokv = NULL; - static int tokn = 0; - - char buf[sizeof text], *s; - int i, tokc = 0; - size_t len; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; - - strcpy(buf, text); - /* separate input text into tokens to be matched individually */ - for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) - if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - die("cannot realloc %u bytes\n", tokn * sizeof *tokv); - len = tokc ? strlen(tokv[0]) : 0; - - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - for (item = items; item && item->text; item++) { - for (i = 0; i < tokc; i++) - if (!fstrstr(item->text, tokv[i])) - break; - if (i != tokc) /* not all tokens match */ - continue; - /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(tokv[0], item->text, len + 1)) - appenditem(item, &matches, &matchend); - else if (!fstrncmp(tokv[0], item->text, len)) - appenditem(item, &lprefix, &prefixend); - else - appenditem(item, &lsubstr, &substrend); - } - if (lprefix) { - if (matches) { - matchend->right = lprefix; - lprefix->left = matchend; - } else - matches = lprefix; - matchend = prefixend; - } - if (lsubstr) { - if (matches) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } else - matches = lsubstr; - matchend = substrend; - } - curr = sel = matches; - calcoffsets(); -} - -static size_t -nextrune(int inc) -{ - ssize_t n; - - /* return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - static void paste(void) { From a0e777abfa9f11d7993338374f08c3ec4bfc698f Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Mon, 28 Sep 2015 00:38:17 +0200 Subject: [PATCH 503/590] minor style fix --- dmenubar/dmenu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 32a8330..071cbc1 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -7,6 +7,7 @@ #include <string.h> #include <strings.h> #include <time.h> + #include <X11/Xlib.h> #include <X11/Xatom.h> #include <X11/Xutil.h> @@ -622,7 +623,7 @@ main(int argc, char *argv[]) if (!strcmp(argv[i], "-v")) { /* prints version information */ puts("dmenu-"VERSION); exit(0); - } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ + } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ topbar = false; else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ fast = true; From 5b6ac44274b6a759d7b2d62c6fc169cf018198df Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 4 Oct 2015 12:32:07 +0200 Subject: [PATCH 504/590] fix paste from clipboard (ctrl+shift+y) from Joshua Lloret on the ML: "attached is a small patch to enable pasting from clipboard, as well as primary. It seems like there was already code in there to allow this, but since there was never any case to match the upper case 'Y', that inline if would always evaluate to false." --- dmenubar/dmenu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 071cbc1..509e566 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -320,6 +320,7 @@ keypress(XKeyEvent *ev) insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ + case XK_Y: XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; From c168112042ae32373c689562df596ee14501bed1 Mon Sep 17 00:00:00 2001 From: Davide Del Zompo <davide.delzompo@gmail.com> Date: Sun, 4 Oct 2015 14:01:22 +0200 Subject: [PATCH 505/590] fix incorrect ordering of match results look for exact matches comparing the user input against the item text --- dmenubar/dmenu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 509e566..c9fb38b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -208,7 +208,7 @@ match(void) char buf[sizeof text], *s; int i, tokc = 0; - size_t len; + size_t len, textsize; struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; strcpy(buf, text); @@ -219,6 +219,7 @@ match(void) len = tokc ? strlen(tokv[0]) : 0; matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + textsize = strlen(text) + 1; for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) if (!fstrstr(item->text, tokv[i])) @@ -226,7 +227,7 @@ match(void) if (i != tokc) /* not all tokens match */ continue; /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(tokv[0], item->text, len + 1)) + if (!tokc || !fstrncmp(text, item->text, textsize)) appenditem(item, &matches, &matchend); else if (!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); From a69a065b02c594b79b14ce72b088ab3df2533072 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sun, 4 Oct 2015 14:47:52 +0200 Subject: [PATCH 506/590] fix input text matching just compare the size of the input string --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c9fb38b..4f22ffe 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -219,7 +219,7 @@ match(void) len = tokc ? strlen(tokv[0]) : 0; matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; + textsize = strlen(text); for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) if (!fstrstr(item->text, tokv[i])) From faf0f4d0eacc3277fc19c980c75321a005b9dafd Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 18 Oct 2015 18:37:20 +0200 Subject: [PATCH 507/590] free schemes as array this makes it slightly easier to add custom schemes aswell --- dmenubar/dmenu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 4f22ffe..1c2e780 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -92,13 +92,13 @@ calcoffsets(void) static void cleanup(void) { + size_t i; + XUngrabKey(dpy, AnyKey, AnyModifier, root); - drw_clr_free(scheme[SchemeNorm].bg); - drw_clr_free(scheme[SchemeNorm].fg); - drw_clr_free(scheme[SchemeSel].fg); - drw_clr_free(scheme[SchemeSel].bg); - drw_clr_free(scheme[SchemeOut].fg); - drw_clr_free(scheme[SchemeOut].bg); + for (i = 0; i < SchemeLast; i++) { + drw_clr_free(scheme[i].bg); + drw_clr_free(scheme[i].fg); + } drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); From d98328474a0a9e8efc2b6123409d4f64c857ee3c Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 20 Oct 2015 22:51:57 +0200 Subject: [PATCH 508/590] add sbase-style ecalloc(), calloc: or die ... remove intermediary variables --- dmenubar/drw.c | 19 +++++++------------ dmenubar/util.c | 10 ++++++++++ dmenubar/util.h | 1 + 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 6aeb59d..a98083e 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -65,8 +65,7 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h { Drw *drw; - if (!(drw = calloc(1, sizeof(Drw)))) - return NULL; + drw = ecalloc(1, sizeof(Drw)); drw->dpy = dpy; drw->screen = screen; drw->root = root; @@ -189,16 +188,13 @@ Clr * drw_clr_create(Drw *drw, const char *clrname) { Clr *clr; - Colormap cmap; - Visual *vis; - if (!drw) return NULL; - if (!(clr = calloc(1, sizeof(Clr)))) - return NULL; - cmap = DefaultColormap(drw->dpy, drw->screen); - vis = DefaultVisual(drw->dpy, drw->screen); - if (!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) + + clr = ecalloc(1, sizeof(Clr)); + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, &clr->rgb)) die("error, cannot allocate color '%s'\n", clrname); clr->pix = clr->rgb.pixel; @@ -409,8 +405,7 @@ drw_cur_create(Drw *drw, int shape) if (!drw) return NULL; - if (!(cur = calloc(1, sizeof(Cur)))) - return NULL; + cur = ecalloc(1, sizeof(Cur)); cur->cursor = XCreateFontCursor(drw->dpy, shape); return cur; diff --git a/dmenubar/util.c b/dmenubar/util.c index 9b27512..6b703e9 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -6,6 +6,16 @@ #include "util.h" +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + perror(NULL); + return p; +} + void die(const char *fmt, ...) { va_list ap; diff --git a/dmenubar/util.h b/dmenubar/util.h index f7ce721..cded043 100644 --- a/dmenubar/util.h +++ b/dmenubar/util.h @@ -5,3 +5,4 @@ #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) void die(const char *errstr, ...); +void *ecalloc(size_t, size_t); From eb26bb684d0c410dcc22671768846f2c4680844c Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 20 Oct 2015 22:53:55 +0200 Subject: [PATCH 509/590] drw: a valid (non-NULL) Drw and Fnt context must be passed don't do these checks on this level. However for resource drw_*_free we will allow it. --- dmenubar/drw.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index a98083e..4815e3a 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -82,8 +82,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h void drw_resize(Drw *drw, unsigned int w, unsigned int h) { - if (!drw) - return; drw->w = w; drw->h = h; if (drw->drawable) @@ -188,8 +186,6 @@ Clr * drw_clr_create(Drw *drw, const char *clrname) { Clr *clr; - if (!drw) - return NULL; clr = ecalloc(1, sizeof(Clr)); if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), @@ -210,15 +206,13 @@ drw_clr_free(Clr *clr) void drw_setscheme(Drw *drw, ClrScheme *scheme) { - if (!drw) - return; drw->scheme = scheme; } void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) { - if (!drw || !drw->scheme) + if (!drw->scheme) return; XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); if (filled) @@ -369,8 +363,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { - if (!drw) - return; XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); XSync(drw->dpy, False); } @@ -380,8 +372,6 @@ drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { XGlyphInfo ext; - if (!font || !text) - return; XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); tex->h = font->h; tex->w = ext.xOff; @@ -392,9 +382,8 @@ drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) { Extnts tex; - if (!font) - return -1; drw_font_getexts(font, text, len, &tex); + return tex.w; } @@ -403,8 +392,6 @@ drw_cur_create(Drw *drw, int shape) { Cur *cur; - if (!drw) - return NULL; cur = ecalloc(1, sizeof(Cur)); cur->cursor = XCreateFontCursor(drw->dpy, shape); @@ -414,7 +401,7 @@ drw_cur_create(Drw *drw, int shape) void drw_cur_free(Drw *drw, Cur *cursor) { - if (!drw || !cursor) + if (!cursor) return; XFreeCursor(drw->dpy, cursor->cursor); free(cursor); From 8648aacd5f0a308b80f803e7cff8f111715a55e2 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 20 Oct 2015 22:55:39 +0200 Subject: [PATCH 510/590] drw: simplify drw_font_xcreate and prevent a potential unneeded allocation --- dmenubar/drw.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 4815e3a..4364117 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -108,12 +108,8 @@ static Fnt * drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { Fnt *font; - - if (!(fontname || fontpattern)) - die("No font specified.\n"); - - if (!(font = calloc(1, sizeof(Fnt)))) - return NULL; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; if (fontname) { /* Using the pattern found at font->xfont->pattern does not yield same @@ -122,28 +118,29 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) * behaviour whereas the former just results in * missing-character-rectangles being drawn, at least with some fonts. */ - if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) || - !(font->pattern = FcNameParse((FcChar8 *) fontname))) { - if (font->xfont) { - XftFontClose(drw->dpy, font->xfont); - font->xfont = NULL; - } + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; } } else if (fontpattern) { - if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { fprintf(stderr, "error, cannot load font pattern.\n"); - else - font->pattern = NULL; + return NULL; + } + } else { + die("no font specified.\n"); } - if (!font->xfont) { - free(font); - return NULL; - } - - font->ascent = font->xfont->ascent; - font->descent = font->xfont->descent; + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->ascent = xfont->ascent; + font->descent = xfont->descent; font->h = font->ascent + font->descent; font->dpy = drw->dpy; From e426a3aa426faa8321ae4afd023697ba5dded1d0 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 20 Oct 2015 22:56:57 +0200 Subject: [PATCH 511/590] drw: cleanup drw_text, prevent gcc warning false-positive of unused var ... we don't allow passing text is NULL anymore either, for that behaviour just use drw_rect() (it is used in dwm). --- dmenubar/drw.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 4364117..80e3c39 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -224,9 +224,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex char buf[1024]; int tx, ty, th; Extnts tex; - Colormap cmap; - Visual *vis; - XftDraw *d; + XftDraw *d = NULL; Fnt *curfont, *nextfont; size_t i, len; int utf8strlen, utf8charlen, render; @@ -238,22 +236,18 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex XftResult result; int charexists = 0; - if (!(render = x || y || w || h)) + if (!drw->scheme || !drw->fontcount) + return 0; + + if (!(render = x || y || w || h)) { w = ~w; - - if (!drw || !drw->scheme) { - return 0; - } else if (render) { - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->pix : drw->scheme->bg->pix); + } else { + XSetForeground(drw->dpy, drw->gc, invert ? + drw->scheme->fg->pix : drw->scheme->bg->pix); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - } - - if (!text || !drw->fontcount) { - return 0; - } else if (render) { - cmap = DefaultColormap(drw->dpy, drw->screen); - vis = DefaultVisual(drw->dpy, drw->screen); - d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); } curfont = drw->fonts[0]; @@ -325,7 +319,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (!drw->fonts[0]->pattern) { /* Refer to the comment in drw_font_xcreate for more * information. */ - die("The first font in the cache must be loaded from a font string.\n"); + die("the first font in the cache must be loaded from a font string.\n"); } fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); @@ -344,14 +338,13 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { drw->fonts[drw->fontcount++] = curfont; } else { - if (curfont) - drw_font_free(curfont); + drw_font_free(curfont); curfont = drw->fonts[0]; } } } } - if (render) + if (d) XftDrawDestroy(d); return x; From 5c1c550164a96d1cc208b2a92b048a3d5702f109 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sat, 7 Nov 2015 12:43:00 +0100 Subject: [PATCH 512/590] fix: multimon: always spawn client on first monitor if specified with -m 0 This was always broken. Reproduce: focus client on second monitor, spawn dmenu with -m 0. Result: Old wrong behaviour: dmenu spawns on second monitor (focused client). Now: dmenu spawns on specified monitor (first). --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1c2e780..6308fa9 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -552,7 +552,7 @@ setup(void) XGetInputFocus(dpy, &w, &di); if (mon != -1 && mon < n) i = mon; - if (!i && w != root && w != PointerRoot && w != None) { + else if (w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ do { if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) From 14c7bed1b939048c4b446bbccd42508cac5cb048 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sat, 7 Nov 2015 12:53:00 +0100 Subject: [PATCH 513/590] dmenu.1: clarify monitor numbers are starting from 0 (first mon) --- dmenubar/dmenu.1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 2897ab1..d3ab805 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -52,7 +52,8 @@ dmenu matches menu items case insensitively. dmenu lists items vertically, with the given number of lines. .TP .BI \-m " monitor" -dmenu is displayed on the monitor supplied. +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. From d0ec76ff7ba7c79bfc8240abdbfad23540ba0e4c Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 8 Nov 2015 16:44:41 +0100 Subject: [PATCH 514/590] remove .hgtags file --- dmenubar/.hgtags | 49 ------------------------------------------------ 1 file changed, 49 deletions(-) delete mode 100644 dmenubar/.hgtags diff --git a/dmenubar/.hgtags b/dmenubar/.hgtags deleted file mode 100644 index c92818f..0000000 --- a/dmenubar/.hgtags +++ /dev/null @@ -1,49 +0,0 @@ -fcc8a282cb52c6a9343b461026b386825590cd31 0.1 -656be0f47df545dfdd2e1e0663663b8b1b26f031 0.2 -d352e9dc112ee96aa5cad961a0ed880ae9ce7276 0.3 -7acf0dde1120542917bae12e0e42293f9d2cc899 0.4 -4a0ecd881c4fc15de4a0bebd79308b064be020ef 0.5 -25f679fb19686140a907684ffcb423b9e9d44b53 0.6 -5fc20d7158bd16b4d5f8d1c25e177680b6d54252 0.7 -409667a57221f7e50ba8b5248f638915cd61b366 0.8 -d046c818ea467555cc338751c9bf3024609f1f12 0.9 -9e11140d4cc3eecac3b0ab752f91528fd5e04be8 1.0 -e8c1e9733752db12f2dbd1fa93c46f5806242ba9 1.1 -bee7fe6d1189174d0204ca3195b83cdc1bb4f82e 1.2 -2eb9997be51cb1b11a8900728ccc0904f9371157 1.3 -df3fbb050004c544d14e43c36f6a94cca6ed4a69 1.4 -e071fb045bd9e8574947acff7196360bc0270e68 1.5 -dcc5427f99f51a978386a0dd770467cd911ac84b 1.6 -58dbef4aef3d45c7a3da6945e53c9667c0f02d5b 1.7 -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 -1ca5d430524e838c52ede912533cb90108c5cd66 2.4.2 -041143e9fc544c62edc58af52cae9ac5237e5945 2.5 -775f761a5647a05038e091d1c99fc35d3034cd68 2.6 -fbd9e9d63f202afe6834ccfdf890904f1897ec0b 2.7 -dd3d02b07cac44fbafc074a361c1002cebe7aae4 2.8 -59b3024854db49739c6d237fa9077f04a2da847a 3.0 -8f0f917ac988164e1b4446236e3a6ab6cfcb8c67 3.1 -e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2 -709df5a4bad7015a346b2b44b1b3b573ea3088ff 3.3 -9ab649b3b3e5bfccf1c8f352c59e5361e070a25f 3.4 -05e5bd706b3b3e61399d57c4bb43df296a20112d 3.5 -0bc2751d06e8b95e0138854c7815e154c5c3d990 3.6 -0508a3a6ee106f36d9b8ff07bb5b28584edfa89c 3.7 -644b0798fcccd570fd519899e1601c6857496b91 3.8 -21a1ed9a69b9541a355758a57103e294fb722c33 3.9 -78f9f72cc9c6bdb022ff8908486b61ef5e242aad 4.0 -844587572673cf6326c3f61737264a46b728fc0a 4.1 -72749a826cab0baa805620e44a22e54486c97a4e 4.1.1 -379813a051f03a1b20bdbfdc2d2d1d2d794ace48 4.2 -abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1 -14c79f054bdf43ff3213af8e60a783192e92a018 4.3 -34a2d77049a95b02f3332a0b88f9370965ebcfad 4.3.1 -2b105eaae8315b076da93056da9ecd60de5a7ac9 4.4 From 1a5372e60a8bddaa23e857db5dbee9a3077632dd Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 8 Nov 2015 16:46:34 +0100 Subject: [PATCH 515/590] Makefile: package config.def.h on make dist --- dmenubar/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 8f14a8c..a7cd04f 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -39,8 +39,9 @@ clean: dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README arg.h config.mk dmenu.1 drw.h util.h \ - dmenu_path dmenu_run stest.1 ${SRC} dmenu-${VERSION} + @cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \ + drw.h util.h dmenu_path dmenu_run stest.1 ${SRC} \ + dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} From dcb45f75e8e07a37a414ecfe483a4dd24d09d907 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 8 Nov 2015 23:03:34 +0100 Subject: [PATCH 516/590] unboolify dmenu --- dmenubar/config.def.h | 2 +- dmenubar/dmenu.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index bc2dc40..a9122f7 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ /* Default settings; can be overriden by command line. */ -static bool topbar = true; /* -b option; if False, dmenu appears at bottom */ +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" diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6308fa9..a07f8e3 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -1,7 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <locale.h> -#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -32,7 +31,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ struct item { char *text; struct item *left, *right; - bool out; + int out; }; static char text[BUFSIZ] = ""; @@ -421,7 +420,7 @@ keypress(XKeyEvent *ev) exit(0); } if (sel) - sel->out = true; + sel->out = 1; break; case XK_Right: if (text[cursor] != '\0') { @@ -480,7 +479,7 @@ readstdin(void) *p = '\0'; if (!(items[i].text = strdup(buf))) die("cannot strdup %u bytes:", strlen(buf) + 1); - items[i].out = false; + items[i].out = 0; if (strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } @@ -617,8 +616,7 @@ usage(void) int main(int argc, char *argv[]) { - bool fast = false; - int i; + int i, fast = 0; for (i = 1; i < argc; i++) /* these options take no arguments */ @@ -626,9 +624,9 @@ main(int argc, char *argv[]) puts("dmenu-"VERSION); exit(0); } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ - topbar = false; + topbar = 0; else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = true; + fast = 1; else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; From 4de104cf77eae0609a0768f7187afed41386afbd Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 8 Nov 2015 23:37:47 +0100 Subject: [PATCH 517/590] arg.h: remove unused ARGNUM* macros --- dmenubar/arg.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/dmenubar/arg.h b/dmenubar/arg.h index 4df77a7..ff1fd13 100644 --- a/dmenubar/arg.h +++ b/dmenubar/arg.h @@ -29,25 +29,11 @@ extern char *argv0; argc_ = argv[0][0];\ switch (argc_) -/* Handles obsolete -NUM syntax */ -#define ARGNUM case '0':\ - case '1':\ - case '2':\ - case '3':\ - case '4':\ - case '5':\ - case '6':\ - case '7':\ - case '8':\ - case '9' - #define ARGEND }\ } #define ARGC() argc_ -#define ARGNUMF(base) (brk_ = 1, estrtol(argv[0], (base))) - #define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ ((x), abort(), (char *)0) :\ (brk_ = 1, (argv[0][1] != '\0')?\ From 30f13c7bb726aabfc353e7f3be02a227967b4409 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sat, 19 Dec 2015 09:32:55 +0100 Subject: [PATCH 518/590] Add config option for word delimiters Let the user configure word boundaries other than ' ', only works with the portable character set. --- dmenubar/config.def.h | 6 ++++++ dmenubar/dmenu.c | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index a9122f7..8db1dda 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -15,3 +15,9 @@ static const char *outbgcolor = "#00ffff"; static const char *outfgcolor = "#000000"; /* -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[] = " "; diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a07f8e3..e0c2f80 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -314,9 +314,11 @@ keypress(XKeyEvent *ev) insert(NULL, 0 - cursor); break; case XK_w: /* delete word */ - while (cursor > 0 && text[nextrune(-1)] == ' ') + while (cursor > 0 && strchr(worddelimiters, + text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); - while (cursor > 0 && text[nextrune(-1)] != ' ') + while (cursor > 0 && !strchr(worddelimiters, + text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ From d948f58bbbcc791e2057f005bc34bffc686efb4f Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sat, 19 Dec 2015 19:58:03 +0100 Subject: [PATCH 519/590] Shut up glibc about _BSD_SOURCE being deprecated --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index faea37f..4d908a5 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -23,7 +23,7 @@ INCS = -I${X11INC} -I${FREETYPEINC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} From 08979a3abde278c1a7b7c514bc651116ef4d6fb2 Mon Sep 17 00:00:00 2001 From: Klemens Nanni <kl3@posteo.org> Date: Mon, 11 Jan 2016 13:26:37 +0100 Subject: [PATCH 520/590] Typofix --- dmenubar/config.def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 8db1dda..dcffd38 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -6,7 +6,7 @@ static int topbar = 1; /* -b option; if 0, dmenu appears a static const char *fonts[] = { "monospace:size=10" }; -static const char *prompt = NULL; /* -p option; prompt to the elft of input field */ +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *normbgcolor = "#222222"; /* -nb option; normal background */ static const char *normfgcolor = "#bbbbbb"; /* -nf option; normal foreground */ static const char *selbgcolor = "#005577"; /* -sb option; selected background */ From c57ba0384aa3b30ff1cbb2516c86e478b010ff30 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Vuotto <l.vuotto92@gmail.com> Date: Mon, 22 Feb 2016 11:03:36 -0300 Subject: [PATCH 521/590] arg.h: fixed argv checks order This prevents accessing to a potentially out-of-bounds memory section. Signed-off-by: Lucas Gabriel Vuotto <l.vuotto92@gmail.com> --- dmenubar/arg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/arg.h b/dmenubar/arg.h index ff1fd13..e94e02b 100644 --- a/dmenubar/arg.h +++ b/dmenubar/arg.h @@ -10,8 +10,8 @@ extern char *argv0; /* use main(int argc, char *argv[]) */ #define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ - argv[0] && argv[0][1]\ - && argv[0][0] == '-';\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ argc--, argv++) {\ char argc_;\ char **argv_;\ From d76952cd7ea9a939d1f1b4019cb4650a16d306c6 Mon Sep 17 00:00:00 2001 From: Markus Teich <markus.teich@stusta.mhn.de> Date: Sat, 21 May 2016 21:51:14 +0200 Subject: [PATCH 522/590] import new drw from libsl and minor fixes. - extract drawitem function (code deduplication) - fix bug where inputw was not correctly calculated from the widest item, but just from the one with the longest strlen() which is not the same. It's better now, but does not account for fallback fonts, since it would be too slow to calculate all the correct item widths on startup. - minor code style fixes (indentation, useless line breaks) --- dmenubar/config.def.h | 12 +- dmenubar/dmenu.c | 147 ++++++++++++------------ dmenubar/drw.c | 253 +++++++++++++++++++++++------------------- dmenubar/drw.h | 63 ++++------- dmenubar/util.h | 4 +- 5 files changed, 237 insertions(+), 242 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index dcffd38..5ac2af8 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -7,12 +7,12 @@ static const char *fonts[] = { "monospace:size=10" }; static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *normbgcolor = "#222222"; /* -nb option; normal background */ -static const char *normfgcolor = "#bbbbbb"; /* -nf option; normal foreground */ -static const char *selbgcolor = "#005577"; /* -sb option; selected background */ -static const char *selfgcolor = "#eeeeee"; /* -sf option; selected foreground */ -static const char *outbgcolor = "#00ffff"; -static const char *outfgcolor = "#000000"; +static const char *colors[][2] = { +/* fg bg */ + { "#bbbbbb", "#222222" }, /* normal */ + { "#eeeeee", "#005577" }, /* selected */ + { "#000000", "#00ffff" }, /* out */ +}; /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ static unsigned int lines = 0; diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index e0c2f80..0e7b70b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -22,8 +22,7 @@ #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 TEXTNW(X,N) (drw_font_getexts_width(drw->fonts[0], (X), (N))) -#define TEXTW(X) (drw_text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ @@ -37,7 +36,8 @@ struct item { static char text[BUFSIZ] = ""; static int bh, mw, mh; static int sw, sh; /* X display screen geometry width, height */ -static int inputw, promptw; +static int inputw = 0, promptw; +static int lrpad; /* sum of left and right padding */ static size_t cursor; static struct item *items = NULL; static struct item *matches, *matchend; @@ -49,8 +49,8 @@ static Display *dpy; static Window root, win; static XIC xic; -static ClrScheme scheme[SchemeLast]; static Drw *drw; +static Clr *scheme[SchemeLast]; #include "config.h" @@ -81,10 +81,10 @@ calcoffsets(void) n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) + if ((i += (lines > 0) ? bh : TEXTW(next->text)) > n) break; for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) + if ((i += (lines > 0) ? bh : TEXTW(prev->left->text)) > n) break; } @@ -94,10 +94,8 @@ cleanup(void) size_t i; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < SchemeLast; i++) { - drw_clr_free(scheme[i].bg); - drw_clr_free(scheme[i].fg); - } + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); @@ -114,70 +112,63 @@ cistrstr(const char *s, const char *sub) return NULL; } +static int +drawitem(struct item *item, int x, int y, int w) +{ + if (item == sel) + drw_setscheme(drw, scheme[SchemeSel]); + else if (item->out) + drw_setscheme(drw, scheme[SchemeOut]); + else + drw_setscheme(drw, scheme[SchemeNorm]); + + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); +} + static void drawmenu(void) { - int curpos; + unsigned int curpos; struct item *item; - int x = 0, y = 0, h = bh, w; + int x = 0, y = 0, w; - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, 1, 1, 1); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); if (prompt && *prompt) { - drw_setscheme(drw, &scheme[SchemeSel]); - drw_text(drw, x, 0, promptw, bh, prompt, 0); - x += promptw; + drw_setscheme(drw, scheme[SchemeSel]); + x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); } /* draw input field */ w = (lines > 0 || !matches) ? mw - x : inputw; - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, text, 0); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - if ((curpos = TEXTNW(text, cursor) + bh / 2 - 2) < w) { - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_rect(drw, x + curpos + 2, 2, 1, bh - 4, 1, 1, 0); + drw_font_getexts(drw->fonts, text, cursor, &curpos, NULL); + if ((curpos += lrpad / 2 - 1) < w) { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); } if (lines > 0) { /* draw vertical list */ - w = mw - x; - for (item = curr; item != next; item = item->right) { - y += h; - if (item == sel) - drw_setscheme(drw, &scheme[SchemeSel]); - else if (item->out) - drw_setscheme(drw, &scheme[SchemeOut]); - else - drw_setscheme(drw, &scheme[SchemeNorm]); - - drw_text(drw, x, y, w, bh, item->text, 0); - } + for (item = curr; item != next; item = item->right) + drawitem(item, x, y += bh, mw - x); } else if (matches) { /* draw horizontal list */ x += inputw; w = TEXTW("<"); if (curr->left) { - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, "<", 0); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); } - for (item = curr; item != next; item = item->right) { - x += w; - w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); - - if (item == sel) - drw_setscheme(drw, &scheme[SchemeSel]); - else if (item->out) - drw_setscheme(drw, &scheme[SchemeOut]); - else - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, item->text, 0); - } - w = TEXTW(">"); - x = mw - w; + x += w; + for (item = curr; item != next; item = item->right) + x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">"))); if (next) { - drw_setscheme(drw, &scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, ">", 0); + w = TEXTW(">"); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); } } drw_map(drw, win, 0, 0, mw, mh); @@ -191,8 +182,8 @@ 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) + if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, + GrabModeAsync, CurrentTime) == GrabSuccess) return; nanosleep(&ts, NULL); } @@ -314,11 +305,9 @@ keypress(XKeyEvent *ev) insert(NULL, 0 - cursor); break; case XK_w: /* delete word */ - while (cursor > 0 && strchr(worddelimiters, - text[nextrune(-1)])) + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); - while (cursor > 0 && !strchr(worddelimiters, - text[nextrune(-1)])) + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) insert(NULL, nextrune(-1) - cursor); break; case XK_y: /* paste selection */ @@ -469,8 +458,9 @@ paste(void) static void readstdin(void) { - char buf[sizeof text], *p, *maxstr = NULL; - size_t i, max = 0, size = 0; + char buf[sizeof text], *p; + size_t i, imax = 0, size = 0; + unsigned int tmpmax = 0; /* read each line from stdin and add it to the item list */ for (i = 0; fgets(buf, sizeof buf, stdin); i++) { @@ -482,12 +472,15 @@ readstdin(void) if (!(items[i].text = strdup(buf))) die("cannot strdup %u bytes:", strlen(buf) + 1); items[i].out = 0; - if (strlen(items[i].text) > max) - max = strlen(maxstr = items[i].text); + drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); + if (tmpmax > inputw) { + inputw = tmpmax; + imax = i; + } } if (items) items[i].text = NULL; - inputw = maxstr ? TEXTW(maxstr) : 0; + inputw = TEXTW(items[imax].text); lines = MIN(lines, i); } @@ -534,18 +527,15 @@ setup(void) #endif /* init appearance */ - scheme[SchemeNorm].bg = drw_clr_create(drw, normbgcolor); - scheme[SchemeNorm].fg = drw_clr_create(drw, normfgcolor); - scheme[SchemeSel].bg = drw_clr_create(drw, selbgcolor); - scheme[SchemeSel].fg = drw_clr_create(drw, selfgcolor); - scheme[SchemeOut].bg = drw_clr_create(drw, outbgcolor); - scheme[SchemeOut].fg = drw_clr_create(drw, outfgcolor); + scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 2); + scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 2); + scheme[SchemeOut] = drw_scm_create(drw, colors[SchemeOut], 2); clip = XInternAtom(dpy, "CLIPBOARD", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); /* calculate menu geometry */ - bh = drw->fonts[0]->h + 2; + bh = drw->fonts->h + 2; lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA @@ -584,13 +574,13 @@ setup(void) y = topbar ? 0 : sh - mh; mw = sw; } - promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; inputw = MIN(inputw, mw/3); match(); /* create menu window */ swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm].bg->pix; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, @@ -644,13 +634,13 @@ main(int argc, char *argv[]) else if (!strcmp(argv[i], "-fn")) /* font or font set */ fonts[0] = argv[++i]; else if (!strcmp(argv[i], "-nb")) /* normal background color */ - normbgcolor = argv[++i]; + colors[SchemeNorm][ColBg] = argv[++i]; else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ - normfgcolor = argv[++i]; + colors[SchemeNorm][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-sb")) /* selected background color */ - selbgcolor = argv[++i]; + colors[SchemeSel][ColBg] = argv[++i]; else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ - selfgcolor = argv[++i]; + colors[SchemeSel][ColFg] = argv[++i]; else usage(); @@ -663,10 +653,9 @@ main(int argc, char *argv[]) sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); drw = drw_create(dpy, screen, root, sw, sh); - drw_load_fonts(drw, fonts, LENGTH(fonts)); - if (!drw->fontcount) + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded.\n"); - drw_setscheme(drw, &scheme[SchemeNorm]); + lrpad = drw->fonts->h; if (fast) { grabkeyboard(); diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 80e3c39..95839c9 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -63,9 +63,8 @@ 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 *drw; + Drw *drw = ecalloc(1, sizeof(Drw)); - drw = ecalloc(1, sizeof(Drw)); drw->dpy = dpy; drw->screen = screen; drw->root = root; @@ -73,7 +72,6 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->h = h; drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); drw->gc = XCreateGC(dpy, root, 0, NULL); - drw->fontcount = 0; XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); return drw; @@ -82,6 +80,9 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h void drw_resize(Drw *drw, unsigned int w, unsigned int h) { + if (!drw) + return; + drw->w = w; drw->h = h; if (drw->drawable) @@ -92,44 +93,39 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) void drw_free(Drw *drw) { - size_t i; - - for (i = 0; i < drw->fontcount; i++) - drw_font_free(drw->fonts[i]); XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); free(drw); } /* This function is an implementation detail. Library users should use - * drw_font_create instead. + * drw_fontset_create instead. */ static Fnt * -drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) { Fnt *font; XftFont *xfont = NULL; FcPattern *pattern = NULL; if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield same - * the same substitution results as using the pattern returned by + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by * FcNameParse; using the latter results in the desired fallback - * behaviour whereas the former just results in - * missing-character-rectangles being drawn, at least with some fonts. - */ + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); return NULL; } if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot load font: '%s'\n", fontname); + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); XftFontClose(drw->dpy, xfont); return NULL; } } else if (fontpattern) { if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font pattern.\n"); + fprintf(stderr, "error, cannot load font from pattern.\n"); return NULL; } } else { @@ -139,37 +135,14 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) font = ecalloc(1, sizeof(Fnt)); font->xfont = xfont; font->pattern = pattern; - font->ascent = xfont->ascent; - font->descent = xfont->descent; - font->h = font->ascent + font->descent; + font->h = xfont->ascent + xfont->descent; font->dpy = drw->dpy; return font; } -Fnt* -drw_font_create(Drw *drw, const char *fontname) -{ - return drw_font_xcreate(drw, fontname, NULL); -} - -void -drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) -{ - size_t i; - Fnt *font; - - for (i = 0; i < fontcount; i++) { - if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { - die("Font cache exhausted.\n"); - } else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) { - drw->fonts[drw->fontcount++] = font; - } - } -} - -void -drw_font_free(Fnt *font) +static void +xfont_free(Fnt *font) { if (!font) return; @@ -179,55 +152,98 @@ drw_font_free(Fnt *font) free(font); } -Clr * -drw_clr_create(Drw *drw, const char *clrname) +Fnt* +drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) { - Clr *clr; + Fnt *cur, *ret = NULL; + size_t i; + + if (!drw || !fonts) + return NULL; + + for (i = 1; i <= fontcount; i++) { + if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { + cur->next = ret; + ret = cur; + } + } + return (drw->fonts = ret); +} + +void +drw_fontset_free(Fnt *font) +{ + if (font) { + drw_fontset_free(font->next); + xfont_free(font); + } +} + +void +drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +{ + if (!drw || !dest || !clrname) + return; - clr = ecalloc(1, sizeof(Clr)); if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), DefaultColormap(drw->dpy, drw->screen), - clrname, &clr->rgb)) + clrname, dest)) die("error, cannot allocate color '%s'\n", clrname); - clr->pix = clr->rgb.pixel; +} - return clr; +/* 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) +{ + size_t i; + Clr *ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, &ret[i], clrnames[i]); + return ret; } void -drw_clr_free(Clr *clr) +drw_setfontset(Drw *drw, Fnt *set) { - free(clr); + if (drw) + drw->fonts = set; } void -drw_setscheme(Drw *drw, ClrScheme *scheme) +drw_setscheme(Drw *drw, Clr *scm) { - drw->scheme = scheme; + if (drw) + drw->scheme = scm; } void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int empty, int invert) +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) { - if (!drw->scheme) + if (!drw || !drw->scheme) return; - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw->scheme->fg->pix); + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); if (filled) - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, h + 1); - else if (empty) - XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); } int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int invert) +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { char buf[1024]; - int tx, ty, th; - Extnts tex; + int ty; + unsigned int ew; XftDraw *d = NULL; - Fnt *curfont, *nextfont; + Fnt *usedfont, *curfont, *nextfont; size_t i, len; - int utf8strlen, utf8charlen, render; + int utf8strlen, utf8charlen, render = x || y || w || h; long utf8codepoint = 0; const char *utf8str; FcCharSet *fccharset; @@ -236,66 +252,67 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex XftResult result; int charexists = 0; - if (!drw->scheme || !drw->fontcount) + if (!drw || (render && !drw->scheme) || !text || !drw->fonts) return 0; - if (!(render = x || y || w || h)) { + if (!render) { w = ~w; } else { - XSetForeground(drw->dpy, drw->gc, invert ? - drw->scheme->fg->pix : drw->scheme->bg->pix); + 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)); + x += lpad; + w -= lpad; } - curfont = drw->fonts[0]; + usedfont = drw->fonts; while (1) { utf8strlen = 0; utf8str = text; nextfont = NULL; while (*text) { utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); - for (i = 0; i < drw->fontcount; i++) { - charexists = charexists || XftCharExists(drw->dpy, drw->fonts[i]->xfont, utf8codepoint); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); if (charexists) { - if (drw->fonts[i] == curfont) { + if (curfont == usedfont) { utf8strlen += utf8charlen; text += utf8charlen; } else { - nextfont = drw->fonts[i]; + nextfont = curfont; } break; } } - if (!charexists || (nextfont && nextfont != curfont)) + if (!charexists || nextfont) break; else charexists = 0; } if (utf8strlen) { - drw_font_getexts(curfont, utf8str, utf8strlen, &tex); + drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); /* shorten text if necessary */ - for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (tex.w > w - drw->fonts[0]->h || w < drw->fonts[0]->h); len--) - drw_font_getexts(curfont, utf8str, len, &tex); + for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) + drw_font_getexts(usedfont, utf8str, len, &ew, NULL); if (len) { memcpy(buf, utf8str, len); buf[len] = '\0'; if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.'); + for (i = len; i && i > len - 3; buf[--i] = '.') + ; /* NOP */ if (render) { - th = curfont->ascent + curfont->descent; - ty = y + (h / 2) - (th / 2) + curfont->ascent; - tx = x + (h / 2); - XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : &drw->scheme->fg->rgb, curfont->xfont, tx, ty, (XftChar8 *)buf, len); + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)buf, len); } - x += tex.w; - w -= tex.w; + x += ew; + w -= ew; } } @@ -303,26 +320,21 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex break; } else if (nextfont) { charexists = 0; - curfont = nextfont; + usedfont = nextfont; } else { /* Regardless of whether or not a fallback font is found, the - * character must be drawn. - */ + * character must be drawn. */ charexists = 1; - if (drw->fontcount >= DRW_FONT_CACHE_SIZE) - continue; - fccharset = FcCharSetCreate(); FcCharSetAddChar(fccharset, utf8codepoint); - if (!drw->fonts[0]->pattern) { - /* Refer to the comment in drw_font_xcreate for more - * information. */ + if (!drw->fonts->pattern) { + /* Refer to the comment in xfont_create for more information. */ die("the first font in the cache must be loaded from a font string.\n"); } - fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); + fcpattern = FcPatternDuplicate(drw->fonts->pattern); FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); @@ -334,12 +346,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex FcPatternDestroy(fcpattern); if (match) { - curfont = drw_font_xcreate(drw, NULL, match); - if (curfont && XftCharExists(drw->dpy, curfont->xfont, utf8codepoint)) { - drw->fonts[drw->fontcount++] = curfont; + usedfont = xfont_create(drw, NULL, match); + if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { + for (curfont = drw->fonts; curfont->next; curfont = curfont->next) + ; /* NOP */ + curfont->next = usedfont; } else { - drw_font_free(curfont); - curfont = drw->fonts[0]; + xfont_free(usedfont); + usedfont = drw->fonts; } } } @@ -347,34 +361,40 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *tex if (d) XftDrawDestroy(d); - return x; + return x + (render ? w : 0); } void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { + if (!drw) + return; + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); XSync(drw->dpy, False); } +unsigned int +drw_fontset_getwidth(Drw *drw, const char *text) +{ + if (!drw || !drw->fonts || !text) + return 0; + return drw_text(drw, 0, 0, 0, 0, 0, text, 0); +} + void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { XGlyphInfo ext; + if (!font || !text) + return; + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); - tex->h = font->h; - tex->w = ext.xOff; -} - -unsigned int -drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) -{ - Extnts tex; - - drw_font_getexts(font, text, len, &tex); - - return tex.w; + if (w) + *w = ext.xOff; + if (h) + *h = font->h; } Cur * @@ -382,7 +402,9 @@ drw_cur_create(Drw *drw, int shape) { Cur *cur; - cur = ecalloc(1, sizeof(Cur)); + if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) + return NULL; + cur->cursor = XCreateFontCursor(drw->dpy, shape); return cur; @@ -393,6 +415,7 @@ drw_cur_free(Drw *drw, Cur *cursor) { if (!cursor) return; + XFreeCursor(drw->dpy, cursor->cursor); free(cursor); } diff --git a/dmenubar/drw.h b/dmenubar/drw.h index e3b8515..4c67419 100644 --- a/dmenubar/drw.h +++ b/dmenubar/drw.h @@ -1,29 +1,19 @@ /* See LICENSE file for copyright and license details. */ -#define DRW_FONT_CACHE_SIZE 32 - -typedef struct { - unsigned long pix; - XftColor rgb; -} Clr; typedef struct { Cursor cursor; } Cur; -typedef struct { +typedef struct Fnt { Display *dpy; - int ascent; - int descent; unsigned int h; XftFont *xfont; FcPattern *pattern; + struct Fnt *next; } Fnt; -typedef struct { - Clr *fg; - Clr *bg; - Clr *border; -} ClrScheme; +enum { ColFg, ColBg }; /* Clr scheme index */ +typedef XftColor Clr; typedef struct { unsigned int w, h; @@ -32,43 +22,36 @@ typedef struct { Window root; Drawable drawable; GC gc; - ClrScheme *scheme; - size_t fontcount; - Fnt *fonts[DRW_FONT_CACHE_SIZE]; + Clr *scheme; + Fnt *fonts; } Drw; -typedef struct { - unsigned int w; - unsigned int h; -} Extnts; - /* Drawable abstraction */ -Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); -void drw_resize(Drw *, unsigned int, unsigned int); -void drw_free(Drw *); +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); /* Fnt abstraction */ -Fnt *drw_font_create(Drw *, const char *); -void drw_load_fonts(Drw *, const char *[], size_t); -void drw_font_free(Fnt *); -void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); -unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int); +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +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); -/* Colour abstraction */ -Clr *drw_clr_create(Drw *, const char *); -void drw_clr_free(Clr *); +/* 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); /* Cursor abstraction */ -Cur *drw_cur_create(Drw *, int); -void drw_cur_free(Drw *, Cur *); +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); /* Drawing context manipulation */ -void drw_setfont(Drw *, Fnt *); -void drw_setscheme(Drw *, ClrScheme *); +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); /* Drawing functions */ -void drw_rect(Drw *, int, int, unsigned int, unsigned int, int, int, int); -int drw_text(Drw *, int, int, unsigned int, unsigned int, const char *, int); +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); /* Map functions */ -void drw_map(Drw *, Window, int, int, unsigned int, unsigned int); +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/dmenubar/util.h b/dmenubar/util.h index cded043..f633b51 100644 --- a/dmenubar/util.h +++ b/dmenubar/util.h @@ -4,5 +4,5 @@ #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) -void die(const char *errstr, ...); -void *ecalloc(size_t, size_t); +void die(const char *fmt, ...); +void *ecalloc(size_t nmemb, size_t size); From 1019ddd56b93a2ba02432e1ed1116ff970b54077 Mon Sep 17 00:00:00 2001 From: "S. Gilles" <sgilles@math.umd.edu> Date: Tue, 28 Jun 2016 01:11:50 -0400 Subject: [PATCH 523/590] fix: Do not crash on e.g. dmenu < /dev/null --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0e7b70b..e926eca 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -480,7 +480,7 @@ readstdin(void) } if (items) items[i].text = NULL; - inputw = TEXTW(items[imax].text); + inputw = items ? TEXTW(items[imax].text) : 0; lines = MIN(lines, i); } From 92e5d3b964e10d816baecd1dfd8afd5bae725fdd Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 28 Jun 2016 17:56:25 +0200 Subject: [PATCH 524/590] config.def.h: style improvement, use color Scheme enum --- dmenubar/config.def.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 5ac2af8..1edb647 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -7,11 +7,11 @@ 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[][2] = { -/* fg bg */ - { "#bbbbbb", "#222222" }, /* normal */ - { "#eeeeee", "#005577" }, /* selected */ - { "#000000", "#00ffff" }, /* out */ +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; From 8f22508821ee425043754e3bc1c3e335d6492fed Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Mon, 25 Jul 2016 11:33:25 +0200 Subject: [PATCH 525/590] Partially revert d76952c: fix items text width offset calculation Without this, we discard the item if it's longer than assigned width instead of truncating it. --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index e926eca..8e84fbd 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -81,10 +81,10 @@ calcoffsets(void) n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : TEXTW(next->text)) > n) + if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) break; for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : TEXTW(prev->left->text)) > n) + if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) break; } From b7238b05a65f68215fd0d9118b84370b731e5b11 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Tue, 26 Jul 2016 12:48:23 +0200 Subject: [PATCH 526/590] Print highlighted input text only on single match When the input text fully matches a single item, do not draw the item and highlight the input text to show that it matches an item in opposition to regular input text not matching anything. --- dmenubar/dmenu.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8e84fbd..b191486 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -130,7 +130,7 @@ drawmenu(void) { unsigned int curpos; struct item *item; - int x = 0, y = 0, w; + int x = 0, y = 0, w, inputscheme; drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, 0, 0, mw, mh, 1, 1); @@ -138,18 +138,27 @@ drawmenu(void) if (prompt && *prompt) { drw_setscheme(drw, scheme[SchemeSel]); x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); + x += 2; } /* draw input field */ w = (lines > 0 || !matches) ? mw - x : inputw; - drw_setscheme(drw, scheme[SchemeNorm]); + if (matches && !strcmp(text, curr->text)) + inputscheme = SchemeSel; + else + inputscheme = SchemeNorm; + drw_setscheme(drw, scheme[inputscheme]); + drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); drw_font_getexts(drw->fonts, text, cursor, &curpos, NULL); if ((curpos += lrpad / 2 - 1) < w) { - drw_setscheme(drw, scheme[SchemeNorm]); + drw_setscheme(drw, scheme[inputscheme]); drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); } + if (inputscheme == SchemeSel) + goto drawmap; + if (lines > 0) { /* draw vertical list */ for (item = curr; item != next; item = item->right) @@ -171,6 +180,7 @@ drawmenu(void) drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); } } +drawmap: drw_map(drw, win, 0, 0, mw, mh); } From 794fbe736bfbd3b60ba7464f41bb68480e85c11f Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 26 Jul 2016 23:02:34 +0200 Subject: [PATCH 527/590] Revert "Print highlighted input text only on single match" This reverts commit b7238b05a65f68215fd0d9118b84370b731e5b11. My bad, was working on the wrong branch and accidently pushed it... *facepalm* --- dmenubar/dmenu.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index b191486..8e84fbd 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -130,7 +130,7 @@ drawmenu(void) { unsigned int curpos; struct item *item; - int x = 0, y = 0, w, inputscheme; + int x = 0, y = 0, w; drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, 0, 0, mw, mh, 1, 1); @@ -138,27 +138,18 @@ drawmenu(void) if (prompt && *prompt) { drw_setscheme(drw, scheme[SchemeSel]); x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); - x += 2; } /* draw input field */ w = (lines > 0 || !matches) ? mw - x : inputw; - if (matches && !strcmp(text, curr->text)) - inputscheme = SchemeSel; - else - inputscheme = SchemeNorm; - drw_setscheme(drw, scheme[inputscheme]); - + drw_setscheme(drw, scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); drw_font_getexts(drw->fonts, text, cursor, &curpos, NULL); if ((curpos += lrpad / 2 - 1) < w) { - drw_setscheme(drw, scheme[inputscheme]); + drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); } - if (inputscheme == SchemeSel) - goto drawmap; - if (lines > 0) { /* draw vertical list */ for (item = curr; item != next; item = item->right) @@ -180,7 +171,6 @@ drawmenu(void) drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); } } -drawmap: drw_map(drw, win, 0, 0, mw, mh); } From 4faac60229ee5e7683f46953cb509ac762dda032 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 26 Jul 2016 23:13:06 +0200 Subject: [PATCH 528/590] fix crash if negative monitor (< -1) was passed for example: dmenu -m '-9001' --- dmenubar/dmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 8e84fbd..df51e76 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -541,7 +541,7 @@ setup(void) #ifdef XINERAMA if ((info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); - if (mon != -1 && mon < n) + if (mon >= 0 && mon < n) i = mon; else if (w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ @@ -558,7 +558,7 @@ setup(void) } } /* no focused window is on screen, so use pointer location instead */ - if (mon == -1 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for (i = 0; i < n; i++) if (INTERSECT(x, y, 1, 1, info[i])) break; From 804388e3869727f0dfc1176d97ce77d6c779997a Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 12 Aug 2016 14:39:30 +0200 Subject: [PATCH 529/590] die() consistency: always add newline --- dmenubar/dmenu.c | 8 ++++---- dmenubar/drw.c | 6 +++--- dmenubar/util.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index df51e76..3b05752 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -187,7 +187,7 @@ grabkeyboard(void) return; nanosleep(&ts, NULL); } - die("cannot grab keyboard\n"); + die("cannot grab keyboard"); } static void @@ -205,7 +205,7 @@ match(void) /* separate input text into tokens to be matched individually */ for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - die("cannot realloc %u bytes\n", tokn * sizeof *tokv); + die("cannot realloc %u bytes:", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; @@ -647,14 +647,14 @@ main(int argc, char *argv[]) if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); if (!(dpy = XOpenDisplay(NULL))) - die("cannot open display\n"); + die("cannot open display"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); drw = drw_create(dpy, screen, root, sw, sh); if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded.\n"); + die("no fonts could be loaded."); lrpad = drw->fonts->h; if (fast) { diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 95839c9..c1582e7 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -129,7 +129,7 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) return NULL; } } else { - die("no font specified.\n"); + die("no font specified."); } font = ecalloc(1, sizeof(Fnt)); @@ -188,7 +188,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname) if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), DefaultColormap(drw->dpy, drw->screen), clrname, dest)) - die("error, cannot allocate color '%s'\n", clrname); + die("error, cannot allocate color '%s'", clrname); } /* Wrapper to create color schemes. The caller has to call free(3) on the @@ -331,7 +331,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp if (!drw->fonts->pattern) { /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string.\n"); + die("the first font in the cache must be loaded from a font string."); } fcpattern = FcPatternDuplicate(drw->fonts->pattern); diff --git a/dmenubar/util.c b/dmenubar/util.c index 6b703e9..b0612af 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -27,6 +27,8 @@ die(const char *fmt, ...) { if (fmt[0] && fmt[strlen(fmt)-1] == ':') { fputc(' ', stderr); perror(NULL); + } else { + fputc('\n', stderr); } exit(1); From 156decd12705b08a75b8690ef991580d3fb07551 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sat, 8 Oct 2016 14:36:04 +0200 Subject: [PATCH 530/590] dmenu.1: fix -l option --- dmenubar/dmenu.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index d3ab805..f0e3bd7 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -7,9 +7,9 @@ dmenu \- dynamic menu .RB [ \-f ] .RB [ \-i ] .RB [ \-l +.IR lines ] .RB [ \-m .IR monitor ] -.IR lines ] .RB [ \-p .IR prompt ] .RB [ \-fn From 2aa4cd6f578f27ca46c52c1f7fe1b58d8454f656 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sat, 8 Oct 2016 14:42:53 +0200 Subject: [PATCH 531/590] dmenu.1: group single options --- dmenubar/dmenu.1 | 5 +---- dmenubar/dmenu.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index f0e3bd7..8bbd79d 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -3,9 +3,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-b ] -.RB [ \-f ] -.RB [ \-i ] +.RB [ \-bfiv ] .RB [ \-l .IR lines ] .RB [ \-m @@ -22,7 +20,6 @@ dmenu \- dynamic menu .IR color ] .RB [ \-sf .IR color ] -.RB [ \-v ] .P .BR dmenu_run " ..." .SH DESCRIPTION diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3b05752..ff74369 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -600,8 +600,8 @@ setup(void) static void usage(void) { - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color]\n", stderr); exit(1); } From aee768e103d1ab14c94773192b8bab7d51aa2abd Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sat, 8 Oct 2016 14:08:28 +0200 Subject: [PATCH 532/590] add embedding support with -w option --- dmenubar/dmenu.1 | 5 ++++ dmenubar/dmenu.c | 65 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 8bbd79d..9eab758 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -20,6 +20,8 @@ dmenu \- dynamic menu .IR color ] .RB [ \-sf .IR color ] +.RB [ \-w +.IR windowid ] .P .BR dmenu_run " ..." .SH DESCRIPTION @@ -75,6 +77,9 @@ 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. diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index ff74369..9278e91 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -34,8 +34,8 @@ struct item { }; static char text[BUFSIZ] = ""; +static char *embed; static int bh, mw, mh; -static int sw, sh; /* X display screen geometry width, height */ static int inputw = 0, promptw; static int lrpad; /* sum of left and right padding */ static size_t cursor; @@ -46,7 +46,7 @@ static int mon = -1, screen; static Atom clip, utf8; static Display *dpy; -static Window root, win; +static Window root, parentwin, win; static XIC xic; static Drw *drw; @@ -174,12 +174,31 @@ drawmenu(void) drw_map(drw, win, 0, 0, mw, mh); } +static void +grabfocus(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; + Window focuswin; + int i, revertwin; + + for (i = 0; i < 100; ++i) { + XGetInputFocus(dpy, &focuswin, &revertwin); + if (focuswin == win) + return; + XSetInputFocus(dpy, win, RevertToParent, CurrentTime); + nanosleep(&ts, NULL); + } + die("cannot grab focus"); +} + static void grabkeyboard(void) { struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; int i; + if (embed) + return; /* 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, @@ -497,6 +516,11 @@ run(void) if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); break; + case FocusIn: + /* regrab focus from parent window */ + if (ev.xfocus.window != win) + grabfocus(); + break; case KeyPress: keypress(&ev.xkey); break; @@ -539,7 +563,7 @@ setup(void) lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA - if ((info = XineramaQueryScreens(dpy, &n))) { + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); if (mon >= 0 && mon < n) i = mon; @@ -570,9 +594,12 @@ setup(void) } else #endif { + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); x = 0; - y = topbar ? 0 : sh - mh; - mw = sw; + y = topbar ? 0 : wa.height - mh; + mw = wa.width; } promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; inputw = MIN(inputw, mw/3); @@ -582,9 +609,8 @@ setup(void) swa.override_redirect = True; swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), + win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); /* open input methods */ @@ -593,6 +619,15 @@ setup(void) XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); + if (embed) { + XSelectInput(dpy, parentwin, FocusChangeMask); + if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { + for (i = 0; i < du && dws[i] != win; ++i) + XSelectInput(dpy, dws[i], FocusChangeMask); + XFree(dws); + } + grabfocus(); + } drw_resize(drw, mw, mh); drawmenu(); } @@ -601,13 +636,14 @@ static void usage(void) { fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color]\n", stderr); + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); exit(1); } int main(int argc, char *argv[]) { + XWindowAttributes wa; int i, fast = 0; for (i = 1; i < argc; i++) @@ -641,6 +677,8 @@ main(int argc, char *argv[]) colors[SchemeSel][ColBg] = argv[++i]; else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ colors[SchemeSel][ColFg] = argv[++i]; + else if (!strcmp(argv[i], "-w")) /* embedding window id */ + embed = argv[++i]; else usage(); @@ -650,9 +688,12 @@ main(int argc, char *argv[]) die("cannot open display"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); + if (!embed || !(parentwin = strtol(embed, NULL, 0))) + parentwin = root; + 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); if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); lrpad = drw->fonts->h; From b3a715ceb217066c11272737bc2938b4999bdeb5 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sat, 5 Nov 2016 11:36:42 +0100 Subject: [PATCH 533/590] die() on calloc failure thanks Markus Teich and David! --- dmenubar/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/util.c b/dmenubar/util.c index b0612af..fe044fc 100644 --- a/dmenubar/util.c +++ b/dmenubar/util.c @@ -12,7 +12,7 @@ ecalloc(size_t nmemb, size_t size) void *p; if (!(p = calloc(nmemb, size))) - perror(NULL); + die("calloc:"); return p; } From 2340d5c41f57ce832f78fc2df1f220f617261c1b Mon Sep 17 00:00:00 2001 From: Thomas Gardner <tmg@fastmail.com> Date: Fri, 25 Nov 2016 22:38:09 +1000 Subject: [PATCH 534/590] Xinerama: correct variable declarations in preprocessor conditional --- dmenubar/dmenu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 9278e91..1cfefcd 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -539,15 +539,16 @@ run(void) static void setup(void) { - int x, y; + int x, y, i = 0; + unsigned int du; XSetWindowAttributes swa; XIM xim; + Window w, dw, *dws; + XWindowAttributes wa; #ifdef XINERAMA XineramaScreenInfo *info; - Window w, pw, dw, *dws; - XWindowAttributes wa; - int a, j, di, n, i = 0, area = 0; - unsigned int du; + Window pw; + int a, j, di, n, area = 0; #endif /* init appearance */ From 7a5a9a64fb09d377e0fcda72dfa440422f92392a Mon Sep 17 00:00:00 2001 From: Andrew Gregory <andrew.gregory.8@gmail.com> Date: Wed, 7 Dec 2016 09:45:01 -0500 Subject: [PATCH 535/590] Revert "fix input text matching" This reverts commit a69a065b02c594b79b14ce72b088ab3df2533072. Using strncmp with the length of the user input turns it into a prefix match rather than an exact match as it's supposed to be. --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 1cfefcd..d605ab4 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -228,7 +228,7 @@ match(void) len = tokc ? strlen(tokv[0]) : 0; matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text); + textsize = strlen(text) + 1; for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) if (!fstrstr(item->text, tokv[i])) From ff69dad6def5025c0f26b93fe213765e20182245 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 2 May 2017 18:32:04 +0200 Subject: [PATCH 536/590] release 4.7 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 4d908a5..de3f1d9 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.6 +VERSION = 4.7 # paths PREFIX = /usr/local From fe7bd767e3e78d3b97a87f0b54481c5743b2dab4 Mon Sep 17 00:00:00 2001 From: Omar Sandoval <osandov@osandov.com> Date: Fri, 3 Nov 2017 09:49:10 -0700 Subject: [PATCH 537/590] Set class name on menu window WM_CLASS is a standard ICCCM property which is used to identify windows. Window managers and compositors use it to allow per-application configurable behavior. --- dmenubar/dmenu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d605ab4..85e5060 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -545,6 +545,7 @@ setup(void) XIM xim; Window w, dw, *dws; XWindowAttributes wa; + XClassHint ch = {"dmenu", "dmenu"}; #ifdef XINERAMA XineramaScreenInfo *info; Window pw; @@ -613,6 +614,7 @@ setup(void) win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + XSetClassHint(dpy, win, &ch); /* open input methods */ xim = XOpenIM(dpy, NULL, NULL, NULL); From 2b4ccf1ef43c99c37a6b82699fc311943d527c62 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 3 Nov 2017 21:05:29 +0100 Subject: [PATCH 538/590] init colors using SchemeLast this makes it slightly easier to add colors to schemes. --- dmenubar/dmenu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 85e5060..91330f1 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -553,9 +553,8 @@ setup(void) #endif /* init appearance */ - scheme[SchemeNorm] = drw_scm_create(drw, colors[SchemeNorm], 2); - scheme[SchemeSel] = drw_scm_create(drw, colors[SchemeSel], 2); - scheme[SchemeOut] = drw_scm_create(drw, colors[SchemeOut], 2); + for (j = 0; j < SchemeLast; j++) + scheme[j] = drw_scm_create(drw, colors[j], 2); clip = XInternAtom(dpy, "CLIPBOARD", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); From 442e9da11d1f2043602143cc099ad50e505b1381 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 3 Nov 2017 15:31:37 +0100 Subject: [PATCH 539/590] fix a possible free of a uninitialize variable in paste() --- dmenubar/dmenu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 91330f1..eae5685 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -467,10 +467,12 @@ paste(void) Atom da; /* we have been given the current selection, now insert it into input */ - XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p); - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); - XFree(p); + if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p) + == Success && p) { + insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); + XFree(p); + } drawmenu(); } From 10ffecd37719246a4729fd94c9302a131cc53856 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 3 Nov 2017 21:10:38 +0100 Subject: [PATCH 540/590] drw: drw_scm_create: use Clr type in this context XftColor is a too low-level type. --- dmenubar/drw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index c1582e7..c638323 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -200,7 +200,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) Clr *ret; /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(Clr)))) return NULL; for (i = 0; i < clrcount; i++) From 48cbe831f7c6dfbf22f53110b99e53b906344742 Mon Sep 17 00:00:00 2001 From: Vincent Carluer <vince@bitfu.io> Date: Thu, 4 Jan 2018 12:27:37 +0000 Subject: [PATCH 541/590] Instantiate j var outside #ifdef XINEMARA directive because it is used in loop outside directive --- dmenubar/dmenu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index eae5685..3c261c0 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -541,7 +541,7 @@ run(void) static void setup(void) { - int x, y, i = 0; + int x, y, i, j = 0; unsigned int du; XSetWindowAttributes swa; XIM xim; @@ -551,9 +551,8 @@ setup(void) #ifdef XINERAMA XineramaScreenInfo *info; Window pw; - int a, j, di, n, area = 0; + int a, di, n, area = 0; #endif - /* init appearance */ for (j = 0; j < SchemeLast; j++) scheme[j] = drw_scm_create(drw, colors[j], 2); From 81a97e2e20597cc4f49bfd434c8b7ff7fbadf09a Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Thu, 4 Jan 2018 23:45:49 +0100 Subject: [PATCH 542/590] Fix regression in 48cbe83 Reported by Jochen Sprickerhof, thanks! Applied patch with minor change (only initialize `i` for XINERAMA). --- dmenubar/dmenu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3c261c0..a246111 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -541,7 +541,7 @@ run(void) static void setup(void) { - int x, y, i, j = 0; + int x, y, i, j; unsigned int du; XSetWindowAttributes swa; XIM xim; @@ -565,6 +565,7 @@ setup(void) lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA + i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); if (mon >= 0 && mon < n) From 030e904de98d1ea88f5b8979d040049b3c628fc4 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Tue, 13 Mar 2018 17:15:09 +0100 Subject: [PATCH 543/590] add key bindings for moving to the word start or end Mod1+b/^Left and Mod1+f/^Right --- dmenubar/dmenu.1 | 12 ++++++++++++ dmenubar/dmenu.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index 9eab758..fbb3f76 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -100,6 +100,12 @@ Confirm input. Prints the input text to stdout and exits, returning success. .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 C\-a Home .TP @@ -160,6 +166,12 @@ Paste from primary X selection C\-Y Paste from X clipboard .TP +M\-b +Move cursor to the start of the current word +.TP +M\-f +Move cursor to the end of the current word +.TP M\-g Home .TP diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a246111..5e9c367 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -287,6 +287,22 @@ nextrune(int inc) return n; } +static void +movewordedge(int dir) +{ + if (dir < 0) { /* move cursor to the start of the word*/ + while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) + cursor = nextrune(-1); + } else { /* move cursor to the end of the word */ + while (text[cursor] && strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + while (text[cursor] && !strchr(worddelimiters, text[cursor])) + cursor = nextrune(+1); + } +} + static void keypress(XKeyEvent *ev) { @@ -334,6 +350,14 @@ keypress(XKeyEvent *ev) XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + case XK_Left: + movewordedge(-1); + ksym = NoSymbol; + break; + case XK_Right: + movewordedge(+1); + ksym = NoSymbol; + break; case XK_Return: case XK_KP_Enter: break; @@ -345,6 +369,14 @@ keypress(XKeyEvent *ev) } else if (ev->state & Mod1Mask) switch(ksym) { + case XK_b: + movewordedge(-1); + ksym = NoSymbol; + break; + case XK_f: + movewordedge(+1); + ksym = NoSymbol; + break; case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; case XK_h: ksym = XK_Up; break; @@ -359,6 +391,8 @@ keypress(XKeyEvent *ev) if (!iscntrl(*buf)) insert(buf, len); break; + case NoSymbol: + break; case XK_Delete: if (text[cursor] == '\0') return; From e63e924b0b7aa1b7d0043cbed921263b72a61696 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Wed, 14 Mar 2018 19:48:05 +0100 Subject: [PATCH 544/590] bump version to 4.8 --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index de3f1d9..50fe52c 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.7 +VERSION = 4.8 # paths PREFIX = /usr/local From 0d33e98f567353981daf04be667605af62fbbb75 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Thu, 15 Mar 2018 10:16:10 +0100 Subject: [PATCH 545/590] Update LICENSE Only "meaningful" commits and contributors who made changes over the years have been added. --- dmenubar/LICENSE | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 221603d..d0c6d64 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,13 +1,15 @@ MIT/X Consortium License © 2006-2014 Anselm R Garbe <anselm@garbe.us> -© 2010-2012 Connor Lane Smith <cls@lubutu.com> +© 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com> +© 2006-2007 Michał Janeczek <janeczek@gmail.com> +© 2007 Kris Maglione <jg@suckless.org> © 2009 Gottox <gottox@s01.de> © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> -© 2006-2008 Sander van Dijk <a dot h dot vandijk at gmail dot com> -© 2006-2007 Michał Janeczek <janeczek at gmail dot com> -© 2014-2015 Hiltjo Posthuma <hiltjo@codemadness.org> +© 2010-2012 Connor Lane Smith <cls@lubutu.com> +© 2014-2018 Hiltjo Posthuma <hiltjo@codemadness.org> +© 2015-2018 Quentin Rameau <quinq@fifth.space> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), From 4c8974afef21aeed38e23ebe9577219b03d7abf8 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 16 Mar 2018 16:51:22 +0100 Subject: [PATCH 546/590] Fix handling of input strings --- dmenubar/dmenu.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5e9c367..c852e92 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -308,13 +308,21 @@ keypress(XKeyEvent *ev) { char buf[32]; int len; - KeySym ksym = NoSymbol; + KeySym ksym; Status status; len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - if (status == XBufferOverflow) + switch (status) { + default: /* XLookupNone, XBufferOverflow */ return; - if (ev->state & ControlMask) + case XLookupChars: + goto insert; + case XLookupKeySym: + case XLookupBoth: + break; + } + + if (ev->state & ControlMask) { switch(ksym) { case XK_a: ksym = XK_Home; break; case XK_b: ksym = XK_Left; break; @@ -352,12 +360,10 @@ keypress(XKeyEvent *ev) return; case XK_Left: movewordedge(-1); - ksym = NoSymbol; - break; + goto draw; case XK_Right: movewordedge(+1); - ksym = NoSymbol; - break; + goto draw; case XK_Return: case XK_KP_Enter: break; @@ -367,16 +373,14 @@ keypress(XKeyEvent *ev) default: return; } - else if (ev->state & Mod1Mask) + } else if (ev->state & Mod1Mask) { switch(ksym) { case XK_b: movewordedge(-1); - ksym = NoSymbol; - break; + goto draw; case XK_f: movewordedge(+1); - ksym = NoSymbol; - break; + goto draw; case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; case XK_h: ksym = XK_Up; break; @@ -386,13 +390,14 @@ keypress(XKeyEvent *ev) default: return; } + } + switch(ksym) { default: +insert: if (!iscntrl(*buf)) insert(buf, len); break; - case NoSymbol: - break; case XK_Delete: if (text[cursor] == '\0') return; @@ -489,6 +494,8 @@ keypress(XKeyEvent *ev) match(); break; } + +draw: drawmenu(); } From 82c317ac48fcf6c63de960e219f9b77ac390d93b Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Mon, 19 Mar 2018 15:42:28 +0100 Subject: [PATCH 547/590] Handle IME input Thanks to nzl <uruabi@gmail.com> for the patch! --- dmenubar/dmenu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c852e92..314256f 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -552,7 +552,7 @@ run(void) XEvent ev; while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, win)) + if (XFilterEvent(&ev, None)) continue; switch(ev.type) { case Expose: @@ -664,6 +664,7 @@ setup(void) XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); + XSetInputFocus(dpy, win, RevertToParent, CurrentTime); if (embed) { XSelectInput(dpy, parentwin, FocusChangeMask); if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { @@ -729,6 +730,8 @@ main(int argc, char *argv[]) if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); + if (!XSetLocaleModifiers("")) + fputs("warning: no locale modifiers support\n", stderr); if (!(dpy = XOpenDisplay(NULL))) die("cannot open display"); screen = DefaultScreen(dpy); From a56e0595dce8f62f1fb541d080b0566e27b7c19e Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Thu, 22 Mar 2018 11:18:56 +0100 Subject: [PATCH 548/590] Makefile: bikesheddingly replace ${} with $() --- dmenubar/Makefile | 72 +++++++++++++++++++++++----------------------- dmenubar/config.mk | 14 ++++----- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index a7cd04f..daac40b 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -4,71 +4,71 @@ include config.mk SRC = drw.c dmenu.c stest.c util.c -OBJ = ${SRC:.c=.o} +OBJ = $(SRC:.c=.o) all: options dmenu stest options: @echo dmenu build options: - @echo "CFLAGS = ${CFLAGS}" - @echo "LDFLAGS = ${LDFLAGS}" - @echo "CC = ${CC}" + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "CC = $(CC)" .c.o: @echo CC $< - @${CC} -c ${CFLAGS} $< + @$(CC) -c $(CFLAGS) $< config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -${OBJ}: arg.h config.h config.mk drw.h +$(OBJ): arg.h config.h config.mk drw.h dmenu: dmenu.o drw.o util.o @echo CC -o $@ - @${CC} -o $@ dmenu.o drw.o util.o ${LDFLAGS} + @$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) stest: stest.o @echo CC -o $@ - @${CC} -o $@ stest.o ${LDFLAGS} + @$(CC) -o $@ stest.o $(LDFLAGS) clean: @echo cleaning - @rm -f dmenu stest ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz dist: clean @echo creating dist tarball - @mkdir -p dmenu-${VERSION} + @mkdir -p dmenu-$(VERSION) @cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \ - drw.h util.h dmenu_path dmenu_run stest.1 ${SRC} \ - dmenu-${VERSION} - @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} - @gzip dmenu-${VERSION}.tar - @rm -rf dmenu-${VERSION} + drw.h util.h dmenu_path dmenu_run stest.1 $(SRC) \ + dmenu-$(VERSION) + @tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) + @gzip dmenu-$(VERSION).tar + @rm -rf dmenu-$(VERSION) install: all - @echo installing executables to ${DESTDIR}${PREFIX}/bin - @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f dmenu dmenu_path dmenu_run stest ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu - @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_path - @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu_run - @chmod 755 ${DESTDIR}${PREFIX}/bin/stest - @echo installing manual pages 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" < stest.1 > ${DESTDIR}${MANPREFIX}/man1/stest.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/stest.1 + @echo installing executables to $(DESTDIR)$(PREFIX)/bin + @mkdir -p $(DESTDIR)$(PREFIX)/bin + @cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin + @chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu + @chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path + @chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run + @chmod 755 $(DESTDIR)$(PREFIX)/bin/stest + @echo installing manual pages 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" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 + @chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + @chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 uninstall: - @echo removing executables from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_path - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run - @rm -f ${DESTDIR}${PREFIX}/bin/stest - @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 - @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 - @rm -f ${DESTDIR}${MANPREFIX}/man1/stest.1 + @echo removing executables from $(DESTDIR)$(PREFIX)/bin + @rm -f $(DESTDIR)$(PREFIX)/bin/dmenu + @rm -f $(DESTDIR)$(PREFIX)/bin/dmenu_path + @rm -f $(DESTDIR)$(PREFIX)/bin/dmenu_run + @rm -f $(DESTDIR)$(PREFIX)/bin/stest + @echo removing manual page from $(DESTDIR)$(MANPREFIX)/man1 + @rm -f $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + @rm -f $(DESTDIR)$(MANPREFIX)/man1/stest.1 .PHONY: all options clean dist install uninstall diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 50fe52c..528704c 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -3,7 +3,7 @@ VERSION = 4.8 # paths PREFIX = /usr/local -MANPREFIX = ${PREFIX}/share/man +MANPREFIX = $(PREFIX)/share/man X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib @@ -16,16 +16,16 @@ XINERAMAFLAGS = -DXINERAMA FREETYPELIBS = -lfontconfig -lXft FREETYPEINC = /usr/include/freetype2 # OpenBSD (uncomment) -#FREETYPEINC = ${X11INC}/freetype2 +#FREETYPEINC = $(X11INC)/freetype2 # includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} +INCS = -I$(X11INC) -I$(FREETYPEINC) +LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) # flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} -LDFLAGS = -s ${LIBS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) +CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) +LDFLAGS = -s $(LIBS) # compiler and linker CC = cc From 2741751edcdc98b1542780014006442a91429080 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sun, 22 Apr 2018 14:18:34 +0200 Subject: [PATCH 549/590] Fix cursor drawn position with wide glyphs --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 314256f..d764658 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -144,7 +144,7 @@ drawmenu(void) drw_setscheme(drw, scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - drw_font_getexts(drw->fonts, text, cursor, &curpos, NULL); + curpos = TEXTW(text) - TEXTW(&text[cursor]); if ((curpos += lrpad / 2 - 1) < w) { drw_setscheme(drw, scheme[SchemeNorm]); drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); From 657e93e12f251379a8911a05a36c21c8aeb2e179 Mon Sep 17 00:00:00 2001 From: David Demelier <markand@malikania.fr> Date: Wed, 9 May 2018 21:27:29 +0200 Subject: [PATCH 550/590] Use bold for keyboard shortcuts in dmenu.1 Like dwm, use the same syntax for all keyboard shortcuts for consistency. --- dmenubar/dmenu.1 | 56 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index fbb3f76..c065087 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -106,88 +106,88 @@ Move cursor to the start of the current word .B Ctrl-Right Move cursor to the end of the current word .TP -C\-a +.B C\-a Home .TP -C\-b +.B C\-b Left .TP -C\-c +.B C\-c Escape .TP -C\-d +.B C\-d Delete .TP -C\-e +.B C\-e End .TP -C\-f +.B C\-f Right .TP -C\-g +.B C\-g Escape .TP -C\-h +.B C\-h Backspace .TP -C\-i +.B C\-i Tab .TP -C\-j +.B C\-j Return .TP -C\-J +.B C\-J Shift-Return .TP -C\-k +.B C\-k Delete line right .TP -C\-m +.B C\-m Return .TP -C\-M +.B C\-M Shift-Return .TP -C\-n +.B C\-n Down .TP -C\-p +.B C\-p Up .TP -C\-u +.B C\-u Delete line left .TP -C\-w +.B C\-w Delete word left .TP -C\-y +.B C\-y Paste from primary X selection .TP -C\-Y +.B C\-Y Paste from X clipboard .TP -M\-b +.B M\-b Move cursor to the start of the current word .TP -M\-f +.B M\-f Move cursor to the end of the current word .TP -M\-g +.B M\-g Home .TP -M\-G +.B M\-G End .TP -M\-h +.B M\-h Up .TP -M\-j +.B M\-j Page down .TP -M\-k +.B M\-k Page up .TP -M\-l +.B M\-l Down .SH SEE ALSO .IR dwm (1), From 815bb9663716c43f2baba567858571bcf973b6be Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 25 May 2018 12:04:22 +0200 Subject: [PATCH 551/590] Pledge on OpenBSD --- dmenubar/dmenu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d764658..7745947 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -24,6 +24,12 @@ #define LENGTH(X) (sizeof X / sizeof X[0]) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +#ifdef __OpenBSD__ +#include <unistd.h> +#else +#define pledge(a,b) 0 +#endif + /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ @@ -746,6 +752,9 @@ main(int argc, char *argv[]) die("no fonts could be loaded."); lrpad = drw->fonts->h; + if (pledge("stdio rpath", NULL) < 0) + die("pledge"); + if (fast) { grabkeyboard(); readstdin(); From 59f74541fbb0ccfb99d2d52cea4b8867542bc581 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 25 May 2018 13:03:25 +0200 Subject: [PATCH 552/590] code-style for pledge(2) feedback from Klemens, thanks --- dmenubar/dmenu.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 7745947..3b2f3ec 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -6,6 +6,9 @@ #include <string.h> #include <strings.h> #include <time.h> +#ifdef __OpenBSD__ +#include <unistd.h> +#endif #include <X11/Xlib.h> #include <X11/Xatom.h> @@ -24,12 +27,6 @@ #define LENGTH(X) (sizeof X / sizeof X[0]) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) -#ifdef __OpenBSD__ -#include <unistd.h> -#else -#define pledge(a,b) 0 -#endif - /* enums */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ @@ -752,8 +749,10 @@ main(int argc, char *argv[]) die("no fonts could be loaded."); lrpad = drw->fonts->h; +#ifdef __OpenBSD__ if (pledge("stdio rpath", NULL) < 0) die("pledge"); +#endif if (fast) { grabkeyboard(); From 44bb7157ec1c3fd138399159e53dabc1611a909e Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 25 May 2018 13:07:17 +0200 Subject: [PATCH 553/590] code-style for pledge: check the return code -1, not < 0 this is the proper idiom --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3b2f3ec..5c835dd 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -750,7 +750,7 @@ main(int argc, char *argv[]) lrpad = drw->fonts->h; #ifdef __OpenBSD__ - if (pledge("stdio rpath", NULL) < 0) + if (pledge("stdio rpath", NULL) == -1) die("pledge"); #endif From 79ec04f5160e76bd6c83aa2d0ae2786bf76bd68d Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sat, 2 Jun 2018 17:01:24 +0200 Subject: [PATCH 554/590] Do not strip at link stage Building with debug symbols is worthless unless LDFLAGS are manually adjusted as well. --- dmenubar/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 528704c..ae34ad8 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -25,7 +25,7 @@ LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) -LDFLAGS = -s $(LIBS) +LDFLAGS = $(LIBS) # compiler and linker CC = cc From 0cc4e2abd47b3d91cb709051cf8181f2458dfd45 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sat, 2 Jun 2018 17:09:01 +0200 Subject: [PATCH 555/590] Makefile: just show the compiler output Don't be fancy and just show the actual output so debugging is simpler. --- dmenubar/Makefile | 66 ++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index daac40b..a03a95c 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -15,60 +15,50 @@ options: @echo "CC = $(CC)" .c.o: - @echo CC $< - @$(CC) -c $(CFLAGS) $< + $(CC) -c $(CFLAGS) $< config.h: - @echo creating $@ from config.def.h - @cp config.def.h $@ + cp config.def.h $@ $(OBJ): arg.h config.h config.mk drw.h dmenu: dmenu.o drw.o util.o - @echo CC -o $@ - @$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) + $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) stest: stest.o - @echo CC -o $@ - @$(CC) -o $@ stest.o $(LDFLAGS) + $(CC) -o $@ stest.o $(LDFLAGS) clean: - @echo cleaning - @rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz + rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz dist: clean - @echo creating dist tarball - @mkdir -p dmenu-$(VERSION) - @cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \ - drw.h util.h dmenu_path dmenu_run stest.1 $(SRC) \ + mkdir -p dmenu-$(VERSION) + cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ + drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ dmenu-$(VERSION) - @tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) - @gzip dmenu-$(VERSION).tar - @rm -rf dmenu-$(VERSION) + tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) + gzip dmenu-$(VERSION).tar + rm -rf dmenu-$(VERSION) install: all - @echo installing executables to $(DESTDIR)$(PREFIX)/bin - @mkdir -p $(DESTDIR)$(PREFIX)/bin - @cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin - @chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu - @chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path - @chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run - @chmod 755 $(DESTDIR)$(PREFIX)/bin/stest - @echo installing manual pages 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" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 - @chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 - @chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run + chmod 755 $(DESTDIR)$(PREFIX)/bin/stest + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 uninstall: - @echo removing executables from $(DESTDIR)$(PREFIX)/bin - @rm -f $(DESTDIR)$(PREFIX)/bin/dmenu - @rm -f $(DESTDIR)$(PREFIX)/bin/dmenu_path - @rm -f $(DESTDIR)$(PREFIX)/bin/dmenu_run - @rm -f $(DESTDIR)$(PREFIX)/bin/stest - @echo removing manual page from $(DESTDIR)$(MANPREFIX)/man1 - @rm -f $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 - @rm -f $(DESTDIR)$(MANPREFIX)/man1/stest.1 + rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ + $(DESTDIR)$(PREFIX)/bin/dmenu_path\ + $(DESTDIR)$(PREFIX)/bin/dmenu_run\ + $(DESTDIR)$(PREFIX)/bin/stest\ + $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ + $(DESTDIR)$(MANPREFIX)/man1/stest.1 .PHONY: all options clean dist install uninstall From f11f715801c3aac32f6fe77b5c8072dca630902a Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Sat, 21 Jul 2018 12:47:43 +0200 Subject: [PATCH 556/590] dmenu_path: always use the cachedir --- dmenubar/dmenu_path | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path index 338bac4..3a7cda7 100644 --- a/dmenubar/dmenu_path +++ b/dmenubar/dmenu_path @@ -1,10 +1,10 @@ #!/bin/sh -cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"} -if [ -d "$cachedir" ]; then - cache=$cachedir/dmenu_run -else - cache=$HOME/.dmenu_cache # if no xdg dir, fall back to dotfile in ~ -fi + +cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}" +cache="$cachedir/dmenu_run" + +[ ! -e "$cachedir" ] && mkdir -p "$cachedir" + IFS=: if stest -dqr -n "$cache" $PATH; then stest -flx $PATH | sort -u | tee "$cache" From 1a708f0956c7902b20ab5d3c018ea8cd3be8d51e Mon Sep 17 00:00:00 2001 From: dok <dok@grehack.fr> Date: Sat, 26 Jan 2019 15:49:15 +0100 Subject: [PATCH 557/590] Use slow path if stdin is a tty If stdin is a tty and dmenu is ran with the fast option then it's impossible to close stdin because the keyboard is already grabbed. --- dmenubar/dmenu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 5c835dd..6b8f51b 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -6,9 +6,7 @@ #include <string.h> #include <strings.h> #include <time.h> -#ifdef __OpenBSD__ #include <unistd.h> -#endif #include <X11/Xlib.h> #include <X11/Xatom.h> @@ -754,7 +752,7 @@ main(int argc, char *argv[]) die("pledge"); #endif - if (fast) { + if (fast && !isatty(0)) { grabkeyboard(); readstdin(); } else { From baaa05517e08b1685cbfad9ba4bbd99c919caced Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 27 Jan 2019 15:28:02 +0100 Subject: [PATCH 558/590] dmenu.1: document improved fastgrab behaviour from previous patch --- dmenubar/dmenu.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 index c065087..323f93c 100644 --- a/dmenubar/dmenu.1 +++ b/dmenubar/dmenu.1 @@ -41,8 +41,8 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. dmenu appears at the bottom of the screen. .TP .B \-f -dmenu grabs the keyboard before reading stdin. This is faster, but will lock up -X until stdin reaches end\-of\-file. +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. From 44a6f6b19826bfa972eeb911b0c1d71d464baf02 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe <anselm@garbe.ca> Date: Sat, 2 Feb 2019 04:54:15 -0800 Subject: [PATCH 559/590] Prepared 4.9 release. --- dmenubar/LICENSE | 4 ++-- dmenubar/config.mk | 2 +- dmenubar/drw.c | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index d0c6d64..6ed8ad3 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -1,6 +1,6 @@ MIT/X Consortium License -© 2006-2014 Anselm R Garbe <anselm@garbe.us> +© 2006-2019 Anselm R Garbe <anselm@garbe.ca> © 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com> © 2006-2007 Michał Janeczek <janeczek@gmail.com> © 2007 Kris Maglione <jg@suckless.org> @@ -8,7 +8,7 @@ MIT/X Consortium License © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> © 2010-2012 Connor Lane Smith <cls@lubutu.com> -© 2014-2018 Hiltjo Posthuma <hiltjo@codemadness.org> +© 2014-2019 Hiltjo Posthuma <hiltjo@codemadness.org> © 2015-2018 Quentin Rameau <quinq@fifth.space> Permission is hereby granted, free of charge, to any person obtaining a diff --git a/dmenubar/config.mk b/dmenubar/config.mk index ae34ad8..0929b4a 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.8 +VERSION = 4.9 # paths PREFIX = /usr/local diff --git a/dmenubar/drw.c b/dmenubar/drw.c index c638323..8fd1ca4 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -132,6 +132,19 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) die("no font specified."); } + /* Do not allow using color fonts. This is a workaround for a BadLength + * error from Xft with color glyphs. Modelled on the Xterm workaround. See + * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 + * https://lists.suckless.org/dev/1701/30932.html + * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 + * and lots more all over the internet. + */ + FcBool iscol; + if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { + XftFontClose(drw->dpy, xfont); + return NULL; + } + font = ecalloc(1, sizeof(Fnt)); font->xfont = xfont; font->pattern = pattern; @@ -200,7 +213,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) Clr *ret; /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(Clr)))) + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) return NULL; for (i = 0; i < clrcount; i++) @@ -337,6 +350,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp fcpattern = FcPatternDuplicate(drw->fonts->pattern); FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); FcDefaultSubstitute(fcpattern); From f22148e512454d40ff995b5fd7ada209521e2a47 Mon Sep 17 00:00:00 2001 From: Quentin Rameau <quinq@fifth.space> Date: Mon, 4 Feb 2019 00:29:26 +0100 Subject: [PATCH 560/590] Close when the embedding window is destroyed --- dmenubar/LICENSE | 2 +- dmenubar/dmenu.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 6ed8ad3..9762166 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -9,7 +9,7 @@ MIT/X Consortium License © 2009 Evan Gates <evan.gates@gmail.com> © 2010-2012 Connor Lane Smith <cls@lubutu.com> © 2014-2019 Hiltjo Posthuma <hiltjo@codemadness.org> -© 2015-2018 Quentin Rameau <quinq@fifth.space> +© 2015-2019 Quentin Rameau <quinq@fifth.space> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 6b8f51b..f803149 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -556,6 +556,11 @@ run(void) if (XFilterEvent(&ev, None)) continue; switch(ev.type) { + case DestroyNotify: + if (ev.xdestroywindow.window != win) + break; + cleanup(); + exit(1); case Expose: if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); @@ -667,7 +672,7 @@ setup(void) XMapRaised(dpy, win); XSetInputFocus(dpy, win, RevertToParent, CurrentTime); if (embed) { - XSelectInput(dpy, parentwin, FocusChangeMask); + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { for (i = 0; i < du && dws[i] != win; ++i) XSelectInput(dpy, dws[i], FocusChangeMask); From 05ed021e3cb4fba02dfd6457e0c2a55e4555900d Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 12 Feb 2019 19:10:43 +0100 Subject: [PATCH 561/590] fix crash when XOpenIM returns NULL for example when IME variables are set, but the program is not started (yet). --- dmenubar/dmenu.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f803149..ae56f4f 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -664,8 +664,17 @@ setup(void) CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); XSetClassHint(dpy, win, &ch); - /* open input methods */ - xim = XOpenIM(dpy, NULL, NULL, NULL); + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) { + XSetLocaleModifiers("@im=local"); + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) { + XSetLocaleModifiers("@im="); + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed. Could not open input device.\n"); + } + } + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); From 5951711650dd81e4caafe78c92d36fac917adcc3 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 12 Feb 2019 22:13:58 +0100 Subject: [PATCH 562/590] make dmenu_path script executable (as dmenu_run is) --- dmenubar/dmenu_path | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 dmenubar/dmenu_path diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path old mode 100644 new mode 100755 From 8e3d6d75d22b75ee95c5c15cc8c7d340dc2098bb Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 12 Feb 2019 22:58:35 +0100 Subject: [PATCH 563/590] improve xopenim error message die() already prints a newline. --- dmenubar/dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index ae56f4f..3bfd74d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -671,7 +671,7 @@ setup(void) if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) { XSetLocaleModifiers("@im="); if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) - die("XOpenIM failed. Could not open input device.\n"); + die("XOpenIM failed: could not open input device"); } } From fbf7b4caf5fa4249455501d2cffed336b3fb5bc0 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Sun, 3 Mar 2019 13:08:54 +0100 Subject: [PATCH 564/590] revert IME support dmenu will not handle IME support (st will, atleast for now). revert parts of commit 82c317ac48fcf6c63de960e219f9b77ac390d93b this commit also broke input focus. --- dmenubar/dmenu.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3bfd74d..65f25ce 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -553,7 +553,7 @@ run(void) XEvent ev; while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, None)) + if (XFilterEvent(&ev, win)) continue; switch(ev.type) { case DestroyNotify: @@ -666,20 +666,13 @@ setup(void) /* input methods */ - if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) { - XSetLocaleModifiers("@im=local"); - if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) { - XSetLocaleModifiers("@im="); - if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) - die("XOpenIM failed: could not open input device"); - } - } + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); if (embed) { XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { @@ -745,8 +738,6 @@ main(int argc, char *argv[]) if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); - if (!XSetLocaleModifiers("")) - fputs("warning: no locale modifiers support\n", stderr); if (!(dpy = XOpenDisplay(NULL))) die("cannot open display"); screen = DefaultScreen(dpy); From 0439eaf6d3351d745212f60d0035d8573b9dbc22 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Thu, 11 Jun 2020 18:45:33 +0200 Subject: [PATCH 565/590] Fix memory leaks in drw Synced from dwm. Patch by Alex Flierl <shad0w73@freenet.de>, thanks. --- dmenubar/drw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dmenubar/drw.c b/dmenubar/drw.c index 8fd1ca4..4cdbcbe 100644 --- a/dmenubar/drw.c +++ b/dmenubar/drw.c @@ -95,6 +95,7 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); free(drw); } From f59218c5f4e457e27a6658012606f099a0c5c893 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Wed, 2 Sep 2020 18:30:56 +0200 Subject: [PATCH 566/590] bump version to 5.0 ... and bump LICENSE year. --- dmenubar/LICENSE | 2 +- dmenubar/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 9762166..3afd28e 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -8,7 +8,7 @@ MIT/X Consortium License © 2009 Markus Schnalke <meillo@marmaro.de> © 2009 Evan Gates <evan.gates@gmail.com> © 2010-2012 Connor Lane Smith <cls@lubutu.com> -© 2014-2019 Hiltjo Posthuma <hiltjo@codemadness.org> +© 2014-2020 Hiltjo Posthuma <hiltjo@codemadness.org> © 2015-2019 Quentin Rameau <quinq@fifth.space> Permission is hereby granted, free of charge, to any person obtaining a diff --git a/dmenubar/config.mk b/dmenubar/config.mk index 0929b4a..05d5a3e 100644 --- a/dmenubar/config.mk +++ b/dmenubar/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.9 +VERSION = 5.0 # paths PREFIX = /usr/local From df016717ca267bc3f9192dc847b445fff1abfa16 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:02:27 -0400 Subject: [PATCH 567/590] remove -l option --- dmenubar/config.def.h | 2 -- dmenubar/dmenu.c | 31 ++++++++----------------------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 1edb647..2c35585 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -13,8 +13,6 @@ static const char *colors[SchemeLast][2] = { [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 diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 65f25ce..c3b1522 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -76,16 +76,13 @@ calcoffsets(void) { int i, n; - if (lines > 0) - n = lines * bh; - else - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); + n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); /* calculate which items will begin the next page and previous page */ for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) + if ((i ? bh : MIN(TEXTW(next->text), n)) > n) break; for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) + if ((i ? bh : MIN(TEXTW(prev->left->text), n)) > n) break; } @@ -141,7 +138,7 @@ drawmenu(void) x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); } /* draw input field */ - w = (lines > 0 || !matches) ? mw - x : inputw; + w = (!matches) ? mw - x : inputw; drw_setscheme(drw, scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); @@ -151,11 +148,7 @@ drawmenu(void) drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); } - if (lines > 0) { - /* draw vertical list */ - for (item = curr; item != next; item = item->right) - drawitem(item, x, y += bh, mw - x); - } else if (matches) { + if (matches) { /* draw horizontal list */ x += inputw; w = TEXTW("<"); @@ -437,12 +430,10 @@ insert: calcoffsets(); break; case XK_Left: - if (cursor > 0 && (!sel || !sel->left || lines > 0)) { + if (cursor > 0 && (!sel || !sel->left)) { cursor = nextrune(-1); break; } - if (lines > 0) - return; /* fallthrough */ case XK_Up: if (sel && sel->left && (sel = sel->left)->right == curr) { @@ -477,8 +468,6 @@ insert: cursor = nextrune(+1); break; } - if (lines > 0) - return; /* fallthrough */ case XK_Down: if (sel && sel->right && (sel = sel->right) == next) { @@ -544,7 +533,6 @@ readstdin(void) if (items) items[i].text = NULL; inputw = items ? TEXTW(items[imax].text) : 0; - lines = MIN(lines, i); } static void @@ -609,8 +597,7 @@ setup(void) /* calculate menu geometry */ bh = drw->fonts->h + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; + mh = bh; #ifdef XINERAMA i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { @@ -689,7 +676,7 @@ setup(void) static void usage(void) { - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + fputs("usage: dmenu [-bfiv] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); exit(1); } @@ -715,8 +702,6 @@ main(int argc, char *argv[]) } else if (i + 1 == argc) usage(); /* these options take one argument */ - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ - lines = atoi(argv[++i]); else if (!strcmp(argv[i], "-m")) mon = atoi(argv[++i]); else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ From 12325c692df99814a6703113c5b3d89174220018 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:14:33 -0400 Subject: [PATCH 568/590] strip out keypress stuff --- dmenubar/dmenu.c | 204 +---------------------------------------------- 1 file changed, 3 insertions(+), 201 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index c3b1522..abae21e 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -171,6 +171,7 @@ drawmenu(void) static void grabfocus(void) { + return; struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; Window focuswin; int i, revertwin; @@ -188,6 +189,7 @@ grabfocus(void) static void grabkeyboard(void) { + return; struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; int i; @@ -297,198 +299,6 @@ movewordedge(int dir) } } -static void -keypress(XKeyEvent *ev) -{ - char buf[32]; - int len; - KeySym ksym; - Status status; - - len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - switch (status) { - default: /* XLookupNone, XBufferOverflow */ - return; - case XLookupChars: - goto insert; - case XLookupKeySym: - case XLookupBoth: - break; - } - - if (ev->state & ControlMask) { - switch(ksym) { - case XK_a: ksym = XK_Home; break; - case XK_b: ksym = XK_Left; break; - 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_g: ksym = XK_Escape; break; - case XK_h: ksym = XK_BackSpace; break; - case XK_i: ksym = XK_Tab; break; - case XK_j: /* fallthrough */ - case XK_J: /* fallthrough */ - case XK_m: /* fallthrough */ - case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; - case XK_n: ksym = XK_Down; break; - case XK_p: ksym = XK_Up; break; - - case XK_k: /* delete right */ - text[cursor] = '\0'; - match(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); - break; - case XK_w: /* delete word */ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - break; - case XK_y: /* paste selection */ - case XK_Y: - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); - return; - case XK_Left: - movewordedge(-1); - goto draw; - case XK_Right: - movewordedge(+1); - goto draw; - case XK_Return: - case XK_KP_Enter: - break; - case XK_bracketleft: - cleanup(); - exit(1); - default: - return; - } - } else if (ev->state & Mod1Mask) { - switch(ksym) { - case XK_b: - movewordedge(-1); - goto draw; - case XK_f: - movewordedge(+1); - goto draw; - case XK_g: ksym = XK_Home; break; - case XK_G: ksym = XK_End; break; - case XK_h: ksym = XK_Up; break; - case XK_j: ksym = XK_Next; break; - case XK_k: ksym = XK_Prior; break; - case XK_l: ksym = XK_Down; break; - default: - return; - } - } - - switch(ksym) { - default: -insert: - if (!iscntrl(*buf)) - insert(buf, len); - break; - case XK_Delete: - if (text[cursor] == '\0') - return; - cursor = nextrune(+1); - /* fallthrough */ - case XK_BackSpace: - if (cursor == 0) - return; - insert(NULL, nextrune(-1) - cursor); - break; - case XK_End: - if (text[cursor] != '\0') { - cursor = strlen(text); - break; - } - if (next) { - /* jump to end of list and position items in reverse */ - curr = matchend; - calcoffsets(); - curr = prev; - calcoffsets(); - while (next && (curr = curr->right)) - calcoffsets(); - } - sel = matchend; - break; - case XK_Escape: - cleanup(); - exit(1); - case XK_Home: - if (sel == matches) { - cursor = 0; - break; - } - sel = curr = matches; - calcoffsets(); - break; - case XK_Left: - if (cursor > 0 && (!sel || !sel->left)) { - cursor = nextrune(-1); - break; - } - /* fallthrough */ - case XK_Up: - if (sel && sel->left && (sel = sel->left)->right == curr) { - curr = prev; - calcoffsets(); - } - break; - case XK_Next: - if (!next) - return; - sel = curr = next; - calcoffsets(); - break; - case XK_Prior: - if (!prev) - return; - sel = curr = prev; - calcoffsets(); - break; - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if (!(ev->state & ControlMask)) { - cleanup(); - exit(0); - } - if (sel) - sel->out = 1; - break; - case XK_Right: - if (text[cursor] != '\0') { - cursor = nextrune(+1); - break; - } - /* fallthrough */ - case XK_Down: - if (sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - break; - case XK_Tab: - if (!sel) - return; - strncpy(text, sel->text, sizeof text - 1); - text[sizeof text - 1] = '\0'; - cursor = strlen(text); - match(); - break; - } - -draw: - drawmenu(); -} - static void paste(void) { @@ -558,9 +368,6 @@ run(void) if (ev.xfocus.window != win) grabfocus(); break; - case KeyPress: - keypress(&ev.xkey); - break; case SelectionNotify: if (ev.xselection.property == utf8) paste(); @@ -694,12 +501,7 @@ main(int argc, char *argv[]) exit(0); } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ topbar = 0; - else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = 1; - else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } else if (i + 1 == argc) + else if (i + 1 == argc) usage(); /* these options take one argument */ else if (!strcmp(argv[i], "-m")) From 742839139ec63a2933395064100c1510bda1a86e Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:18:07 -0400 Subject: [PATCH 569/590] tear out more stuff --- dmenubar/dmenu.c | 46 ++-------------------------------------------- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index abae21e..a136aad 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -168,41 +168,10 @@ drawmenu(void) drw_map(drw, win, 0, 0, mw, mh); } -static void -grabfocus(void) -{ - return; - struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; - Window focuswin; - int i, revertwin; - - for (i = 0; i < 100; ++i) { - XGetInputFocus(dpy, &focuswin, &revertwin); - if (focuswin == win) - return; - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - nanosleep(&ts, NULL); - } - die("cannot grab focus"); -} - static void grabkeyboard(void) { return; - struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; - int i; - - if (embed) - return; - /* 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) - return; - nanosleep(&ts, NULL); - } - die("cannot grab keyboard"); } static void @@ -363,11 +332,6 @@ run(void) if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); break; - case FocusIn: - /* regrab focus from parent window */ - if (ev.xfocus.window != win) - grabfocus(); - break; case SelectionNotify: if (ev.xselection.property == utf8) paste(); @@ -474,7 +438,6 @@ setup(void) XSelectInput(dpy, dws[i], FocusChangeMask); XFree(dws); } - grabfocus(); } drw_resize(drw, mw, mh); drawmenu(); @@ -544,13 +507,8 @@ main(int argc, char *argv[]) die("pledge"); #endif - if (fast && !isatty(0)) { - grabkeyboard(); - readstdin(); - } else { - readstdin(); - grabkeyboard(); - } + readstdin(); + setup(); run(); From 2098d061856659c369c29798264da0b95440110a Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:19:56 -0400 Subject: [PATCH 570/590] more stuff to the wind --- dmenubar/dmenu.c | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index a136aad..cd3ca1d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -99,17 +99,6 @@ cleanup(void) XCloseDisplay(dpy); } -static char * -cistrstr(const char *s, const char *sub) -{ - size_t len; - - for (len = strlen(sub); *s; s++) - if (!strncasecmp(s, sub, len)) - return (char *)s; - return NULL; -} - static int drawitem(struct item *item, int x, int y, int w) { @@ -241,33 +230,6 @@ insert(const char *str, ssize_t n) match(); } -static size_t -nextrune(int inc) -{ - ssize_t n; - - /* return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - -static void -movewordedge(int dir) -{ - if (dir < 0) { /* move cursor to the start of the word*/ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - } else { /* move cursor to the end of the word */ - while (text[cursor] && strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - while (text[cursor] && !strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - } -} - static void paste(void) { @@ -455,7 +417,7 @@ int main(int argc, char *argv[]) { XWindowAttributes wa; - int i, fast = 0; + int i; for (i = 1; i < argc; i++) /* these options take no arguments */ From bf7e480d1de2df8e544682c76d1509b72b2e16dc Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:24:45 -0400 Subject: [PATCH 571/590] MOAR GOOOORE --- dmenubar/dmenu.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index cd3ca1d..0981bd4 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -157,12 +157,6 @@ drawmenu(void) drw_map(drw, win, 0, 0, mw, mh); } -static void -grabkeyboard(void) -{ - return; -} - static void match(void) { From ef72d59495ce2961f854f4de7e60476d709194db Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:26:32 -0400 Subject: [PATCH 572/590] get rid of cursor --- dmenubar/dmenu.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 0981bd4..d8dc767 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -115,7 +115,6 @@ drawitem(struct item *item, int x, int y, int w) static void drawmenu(void) { - unsigned int curpos; struct item *item; int x = 0, y = 0, w; @@ -131,12 +130,6 @@ drawmenu(void) drw_setscheme(drw, scheme[SchemeNorm]); drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - curpos = TEXTW(text) - TEXTW(&text[cursor]); - if ((curpos += lrpad / 2 - 1) < w) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); - } - if (matches) { /* draw horizontal list */ x += inputw; From 700f7a9ed2e5fcbda8d427682df1619b67813404 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:28:01 -0400 Subject: [PATCH 573/590] remove paste --- dmenubar/dmenu.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index d8dc767..94345aa 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -217,24 +217,6 @@ insert(const char *str, ssize_t n) match(); } -static void -paste(void) -{ - char *p, *q; - int di; - unsigned long dl; - Atom da; - - /* 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) { - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); - XFree(p); - } - drawmenu(); -} - static void readstdin(void) { @@ -281,10 +263,6 @@ run(void) if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); break; - case SelectionNotify: - if (ev.xselection.property == utf8) - paste(); - break; case VisibilityNotify: if (ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); From 1bd26277079d931ce78d493c934170c9535cf92b Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:39:51 -0400 Subject: [PATCH 574/590] bloodshed everywhere etc --- dmenubar/dmenu.c | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 94345aa..af9fee5 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -39,7 +39,6 @@ static char *embed; static int bh, mw, mh; static int inputw = 0, promptw; static int lrpad; /* sum of left and right padding */ -static size_t cursor; static struct item *items = NULL; static struct item *matches, *matchend; static struct item *prev, *curr, *next, *sel; @@ -204,19 +203,6 @@ match(void) calcoffsets(); } -static void -insert(const char *str, ssize_t n) -{ - if (strlen(text) + n > sizeof text - 1) - return; - /* 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(); -} - static void readstdin(void) { @@ -245,32 +231,6 @@ readstdin(void) inputw = items ? TEXTW(items[imax].text) : 0; } -static void -run(void) -{ - XEvent ev; - - while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, win)) - continue; - switch(ev.type) { - case DestroyNotify: - if (ev.xdestroywindow.window != win) - break; - cleanup(); - exit(1); - case Expose: - if (ev.xexpose.count == 0) - drw_map(drw, win, 0, 0, mw, mh); - break; - case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - } -} - static void setup(void) { @@ -437,7 +397,7 @@ main(int argc, char *argv[]) readstdin(); setup(); - run(); + while(1); // bodge return 1; /* unreachable */ } From f6a750db086342e534c4085d3d05ea41b864623f Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 14:48:58 -0400 Subject: [PATCH 575/590] refinement --- dmenubar/dmenu.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index af9fee5..3f6111d 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -124,28 +124,7 @@ drawmenu(void) drw_setscheme(drw, scheme[SchemeSel]); x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); } - /* draw input field */ - w = (!matches) ? mw - x : inputw; - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - if (matches) { - /* draw horizontal list */ - x += inputw; - w = TEXTW("<"); - if (curr->left) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); - } - x += w; - for (item = curr; item != next; item = item->right) - x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">"))); - if (next) { - w = TEXTW(">"); - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); - } - } drw_map(drw, win, 0, 0, mw, mh); } From e5f89bd2c6fb41e508d7141697ce2f3d693bd382 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Tue, 11 May 2021 20:03:32 -0400 Subject: [PATCH 576/590] explanation and copyright (yuck) --- dmenubar/LICENSE | 1 + dmenubar/README | 11 +++-------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/dmenubar/LICENSE b/dmenubar/LICENSE index 3afd28e..8a92974 100644 --- a/dmenubar/LICENSE +++ b/dmenubar/LICENSE @@ -10,6 +10,7 @@ MIT/X Consortium License © 2010-2012 Connor Lane Smith <cls@lubutu.com> © 2014-2020 Hiltjo Posthuma <hiltjo@codemadness.org> © 2015-2019 Quentin Rameau <quinq@fifth.space> +© 2021 Deven Blake <trinity@trinity.moe> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/dmenubar/README b/dmenubar/README index a8fcdfe..2801cae 100644 --- a/dmenubar/README +++ b/dmenubar/README @@ -1,13 +1,13 @@ -dmenu - dynamic menu +dmenubar - dumb menu bar ==================== dmenu is an efficient dynamic menu for X. - +dmenubar is a hack of dmenu that displays a menu bar. +This is a work in progress. Doesn't suckless, suxmoar. Requirements ------------ In order to build dmenu you need the Xlib header files. - Installation ------------ Edit config.mk to match your local setup (dmenu is installed into @@ -17,8 +17,3 @@ Afterwards enter the following command to build and install dmenu (if necessary as root): make clean install - - -Running dmenu -------------- -See the man page for details. From aa74459a4eb561022f57db3408ce8ce77944a9fb Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sat, 15 May 2021 23:45:35 -0400 Subject: [PATCH 577/590] back at it --- dmenubar/dmenu.c | 62 ++---------------------------------------------- 1 file changed, 2 insertions(+), 60 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index 3f6111d..bf5a9e0 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -114,74 +114,17 @@ drawitem(struct item *item, int x, int y, int w) static void drawmenu(void) { - struct item *item; int x = 0, y = 0, w; - drw_setscheme(drw, scheme[SchemeNorm]); + drw_setscheme(drw, scheme[SchemeSel]); drw_rect(drw, 0, 0, mw, mh, 1, 1); - if (prompt && *prompt) { - drw_setscheme(drw, scheme[SchemeSel]); + if (prompt && *prompt) x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); - } drw_map(drw, win, 0, 0, mw, mh); } -static void -match(void) -{ - static char **tokv = NULL; - static int tokn = 0; - - char buf[sizeof text], *s; - int i, tokc = 0; - size_t len, textsize; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; - - strcpy(buf, text); - /* separate input text into tokens to be matched individually */ - for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) - if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - die("cannot realloc %u bytes:", tokn * sizeof *tokv); - len = tokc ? strlen(tokv[0]) : 0; - - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; - for (item = items; item && item->text; item++) { - for (i = 0; i < tokc; i++) - if (!fstrstr(item->text, tokv[i])) - break; - if (i != tokc) /* not all tokens match */ - continue; - /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(text, item->text, textsize)) - appenditem(item, &matches, &matchend); - else if (!fstrncmp(tokv[0], item->text, len)) - appenditem(item, &lprefix, &prefixend); - else - appenditem(item, &lsubstr, &substrend); - } - if (lprefix) { - if (matches) { - matchend->right = lprefix; - lprefix->left = matchend; - } else - matches = lprefix; - matchend = prefixend; - } - if (lsubstr) { - if (matches) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } else - matches = lsubstr; - matchend = substrend; - } - curr = sel = matches; - calcoffsets(); -} - static void readstdin(void) { @@ -277,7 +220,6 @@ setup(void) } promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; inputw = MIN(inputw, mw/3); - match(); /* create menu window */ swa.override_redirect = True; From 577c419c2a9f737c67412f29de7739c66c57b9b4 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sat, 15 May 2021 23:54:19 -0400 Subject: [PATCH 578/590] tear out a lot more --- dmenubar/dmenu.c | 64 ++---------------------------------------------- 1 file changed, 2 insertions(+), 62 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index bf5a9e0..f34423e 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -57,19 +57,6 @@ static Clr *scheme[SchemeLast]; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; -static void -appenditem(struct item *item, struct item **list, struct item **last) -{ - if (*last) - (*last)->right = item; - else - *list = item; - - item->left = *last; - item->right = NULL; - *last = item; -} - static void calcoffsets(void) { @@ -98,19 +85,6 @@ cleanup(void) XCloseDisplay(dpy); } -static int -drawitem(struct item *item, int x, int y, int w) -{ - if (item == sel) - drw_setscheme(drw, scheme[SchemeSel]); - else if (item->out) - drw_setscheme(drw, scheme[SchemeOut]); - else - drw_setscheme(drw, scheme[SchemeNorm]); - - return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -} - static void drawmenu(void) { @@ -125,34 +99,6 @@ drawmenu(void) drw_map(drw, win, 0, 0, mw, mh); } -static void -readstdin(void) -{ - char buf[sizeof text], *p; - size_t i, imax = 0, size = 0; - unsigned int tmpmax = 0; - - /* 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) - if (!(items = realloc(items, (size += BUFSIZ)))) - die("cannot realloc %u bytes:", size); - if ((p = strchr(buf, '\n'))) - *p = '\0'; - if (!(items[i].text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf) + 1); - items[i].out = 0; - drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); - if (tmpmax > inputw) { - inputw = tmpmax; - imax = i; - } - } - if (items) - items[i].text = NULL; - inputw = items ? TEXTW(items[imax].text) : 0; -} - static void setup(void) { @@ -281,13 +227,9 @@ main(int argc, char *argv[]) prompt = argv[++i]; else if (!strcmp(argv[i], "-fn")) /* font or font set */ fonts[0] = argv[++i]; - else if (!strcmp(argv[i], "-nb")) /* normal background color */ - colors[SchemeNorm][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ - colors[SchemeNorm][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-sb")) /* selected background color */ + else if (!strcmp(argv[i], "-b")) /* selected background color */ colors[SchemeSel][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ + else if (!strcmp(argv[i], "-f")) /* selected foreground color */ colors[SchemeSel][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; @@ -315,8 +257,6 @@ main(int argc, char *argv[]) die("pledge"); #endif - readstdin(); - setup(); while(1); // bodge From dd9ec127dc13ec4c8e22c4acbc47c81fff2d8e8c Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 00:24:38 -0400 Subject: [PATCH 579/590] FUNCTIONAL --- dmenubar/dmenu.c | 66 +++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/dmenubar/dmenu.c b/dmenubar/dmenu.c index f34423e..451f800 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenu.c @@ -26,22 +26,12 @@ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) /* enums */ -enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ +enum { Scheme, SchemeLast }; /* color schemes */ -struct item { - char *text; - struct item *left, *right; - int out; -}; - -static char text[BUFSIZ] = ""; static char *embed; static int bh, mw, mh; -static int inputw = 0, promptw; +static int inputw = 0; static int lrpad; /* sum of left and right padding */ -static struct item *items = NULL; -static struct item *matches, *matchend; -static struct item *prev, *curr, *next, *sel; static int mon = -1, screen; static Atom clip, utf8; @@ -57,21 +47,6 @@ static Clr *scheme[SchemeLast]; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; -static void -calcoffsets(void) -{ - int i, n; - - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); - /* calculate which items will begin the next page and previous page */ - for (i = 0, next = curr; next; next = next->right) - if ((i ? bh : MIN(TEXTW(next->text), n)) > n) - break; - for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i ? bh : MIN(TEXTW(prev->left->text), n)) > n) - break; -} - static void cleanup(void) { @@ -86,19 +61,25 @@ cleanup(void) } static void -drawmenu(void) +drawmenu(char *text) { int x = 0, y = 0, w; - drw_setscheme(drw, scheme[SchemeSel]); + drw_setscheme(drw, scheme[Scheme]); drw_rect(drw, 0, 0, mw, mh, 1, 1); - if (prompt && *prompt) - x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); + if (text && *text) + x = drw_text(drw, x, 0, textw(text), bh, lrpad / 2, text, 0); drw_map(drw, win, 0, 0, mw, mh); } +int +textw(char *text) +{ + return (text && *text) ? TEXTW(text) - lrpad / 4 : 0; +} + static void setup(void) { @@ -164,12 +145,11 @@ setup(void) y = topbar ? 0 : wa.height - mh; mw = wa.width; } - promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; inputw = MIN(inputw, mw/3); /* create menu window */ swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + swa.background_pixel = scheme[Scheme][ColBg].pixel; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, CopyFromParent, CopyFromParent, CopyFromParent, @@ -194,13 +174,13 @@ setup(void) } } drw_resize(drw, mw, mh); - drawmenu(); + //drawmenu(); } static void usage(void) { - fputs("usage: dmenu [-bfiv] [-p prompt] [-fn font] [-m monitor]\n" + fputs("usage: dmenu [-bfiv] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); exit(1); } @@ -210,6 +190,9 @@ main(int argc, char *argv[]) { XWindowAttributes wa; int i; + char text[text_s]; + for(i = 0; i < text_s; ++i) + text[i] = '\0'; for (i = 1; i < argc; i++) /* these options take no arguments */ @@ -223,14 +206,12 @@ main(int argc, char *argv[]) /* these options take one argument */ else if (!strcmp(argv[i], "-m")) mon = atoi(argv[++i]); - else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; else if (!strcmp(argv[i], "-fn")) /* font or font set */ fonts[0] = argv[++i]; else if (!strcmp(argv[i], "-b")) /* selected background color */ - colors[SchemeSel][ColBg] = argv[++i]; + colors[Scheme][ColBg] = argv[++i]; else if (!strcmp(argv[i], "-f")) /* selected foreground color */ - colors[SchemeSel][ColFg] = argv[++i]; + colors[Scheme][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; else @@ -258,7 +239,12 @@ main(int argc, char *argv[]) #endif setup(); - while(1); // bodge + do{ + /* fgets adds a newline which will be printable in some fonts */ + if(strlen(text) > 0) + text[strlen(text)-1] = '\0'; + drawmenu(text); + }while(fgets(text, text_s, stdin) != NULL); return 1; /* unreachable */ } From 87a70d203e23c5219f8d2735d21f7b804d74b7b4 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 00:41:18 -0400 Subject: [PATCH 580/590] rebranding because dmenu itself doesn't deserve this --- dmenubar/Makefile | 40 +++---- dmenubar/{README => README.md} | 23 ++-- dmenubar/config.def.h | 18 +-- dmenubar/dmenu.1 | 194 ------------------------------- dmenubar/dmenu_path | 13 --- dmenubar/dmenu_run | 2 - dmenubar/{dmenu.c => dmenubar.c} | 26 ++++- 7 files changed, 56 insertions(+), 260 deletions(-) rename dmenubar/{README => README.md} (50%) delete mode 100644 dmenubar/dmenu.1 delete mode 100755 dmenubar/dmenu_path delete mode 100755 dmenubar/dmenu_run rename dmenubar/{dmenu.c => dmenubar.c} (88%) diff --git a/dmenubar/Makefile b/dmenubar/Makefile index a03a95c..808804b 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,10 +3,10 @@ include config.mk -SRC = drw.c dmenu.c stest.c util.c +SRC = drw.c dmenubar.c stest.c util.c OBJ = $(SRC:.c=.o) -all: options dmenu stest +all: options dmenubar stest options: @echo dmenu build options: @@ -22,43 +22,39 @@ config.h: $(OBJ): arg.h config.h config.mk drw.h -dmenu: dmenu.o drw.o util.o - $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) +dmenubar: dmenubar.o drw.o util.o + $(CC) -o $@ dmenubar.o drw.o util.o $(LDFLAGS) stest: stest.o $(CC) -o $@ stest.o $(LDFLAGS) clean: - rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz + rm -f dmenubar stest $(OBJ) dmenubar-$(VERSION).tar.gz dist: clean - mkdir -p dmenu-$(VERSION) - cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ - drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ - dmenu-$(VERSION) - tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) - gzip dmenu-$(VERSION).tar - rm -rf dmenu-$(VERSION) + mkdir -p dmenubar-$(VERSION) + cp LICENSE Makefile README arg.h config.def.h config.mk dmenubar.1\ + drw.h util.h stest.1 $(SRC)\ + dmenubar-$(VERSION) + tar -cf dmenubar-$(VERSION).tar dmenubar-$(VERSION) + gzip dmenubar-$(VERSION).tar + rm -rf dmenubar-$(VERSION) install: all mkdir -p $(DESTDIR)$(PREFIX)/bin - cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run + cp -f dmenubar stest $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenubar chmod 755 $(DESTDIR)$(PREFIX)/bin/stest mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + sed "s/VERSION/$(VERSION)/g" < dmenubar.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenubar.1 sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenubar.1 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ - $(DESTDIR)$(PREFIX)/bin/dmenu_path\ - $(DESTDIR)$(PREFIX)/bin/dmenu_run\ + rm -f $(DESTDIR)$(PREFIX)/bin/dmenubar\ $(DESTDIR)$(PREFIX)/bin/stest\ - $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ + $(DESTDIR)$(MANPREFIX)/man1/dmenubar.1\ $(DESTDIR)$(MANPREFIX)/man1/stest.1 .PHONY: all options clean dist install uninstall diff --git a/dmenubar/README b/dmenubar/README.md similarity index 50% rename from dmenubar/README rename to dmenubar/README.md index 2801cae..361f21f 100644 --- a/dmenubar/README +++ b/dmenubar/README.md @@ -1,19 +1,22 @@ -dmenubar - dumb menu bar -==================== -dmenu is an efficient dynamic menu for X. -dmenubar is a hack of dmenu that displays a menu bar. -This is a work in progress. Doesn't suckless, suxmoar. +# dmenubar - dynamic menu bar + +dmenu is an efficient dynamic menu for X. +dmenubar is a HACK of dmenu that displays a menu bar. + +** There are no guarantees at any time that this project works or is stable. Please don't rely on it. ** + +Lemonbar is an excellent replacement. + +## Requirements -Requirements ------------- In order to build dmenu you need the Xlib header files. -Installation ------------- +## Installation + Edit config.mk to match your local setup (dmenu is installed into the /usr/local namespace by default). Afterwards enter the following command to build and install dmenu (if necessary as root): - make clean install +`make clean install` diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 2c35585..7dcc375 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -1,21 +1,13 @@ /* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ +/* Default settings; some 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 */ /* -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 int text_s = 1024; /* chars to be allocated for the text displayed in the bar */ static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeOut] = { "#000000", "#00ffff" }, + /* fg, bg */ + [Scheme] = { "#eeeeee", "#005577" }, }; - -/* - * Characters not considered part of a word while deleting words - * for example: " /?\"&[]" - */ -static const char worddelimiters[] = " "; diff --git a/dmenubar/dmenu.1 b/dmenubar/dmenu.1 deleted file mode 100644 index 323f93c..0000000 --- a/dmenubar/dmenu.1 +++ /dev/null @@ -1,194 +0,0 @@ -.TH DMENU 1 dmenu\-VERSION -.SH NAME -dmenu \- dynamic menu -.SH SYNOPSIS -.B dmenu -.RB [ \-bfiv ] -.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 -.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) diff --git a/dmenubar/dmenu_path b/dmenubar/dmenu_path deleted file mode 100755 index 3a7cda7..0000000 --- a/dmenubar/dmenu_path +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}" -cache="$cachedir/dmenu_run" - -[ ! -e "$cachedir" ] && mkdir -p "$cachedir" - -IFS=: -if stest -dqr -n "$cache" $PATH; then - stest -flx $PATH | sort -u | tee "$cache" -else - cat "$cache" -fi diff --git a/dmenubar/dmenu_run b/dmenubar/dmenu_run deleted file mode 100755 index 834ede5..0000000 --- a/dmenubar/dmenu_run +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & diff --git a/dmenubar/dmenu.c b/dmenubar/dmenubar.c similarity index 88% rename from dmenubar/dmenu.c rename to dmenubar/dmenubar.c index 451f800..1eb60ae 100644 --- a/dmenubar/dmenu.c +++ b/dmenubar/dmenubar.c @@ -1,4 +1,11 @@ /* See LICENSE file for copyright and license details. */ + +/* I'm not a very good C programmer and this isn't the best I can do. + * There are a lot of fragments here from Suckless' dmenu. I would + * recommend hacking on that instead. This is itself a total hack and + * not a pretty one, but it works and I'm at least proud of that. + * ~ trinity */ + #include <ctype.h> #include <locale.h> #include <stdio.h> @@ -27,6 +34,11 @@ /* enums */ enum { Scheme, SchemeLast }; /* color schemes */ +/* enumerated because Suckless has SchemeNorm, SchemeSel, etc. + * should be made into like one char *Scheme[2] */ +/* BTW SchemeLast is the size of an array of the schemes and it's used + * in this program for iteration. Assumes enums will be assigned + * 0,1,2,3... */ static char *embed; static int bh, mw, mh; @@ -75,11 +87,12 @@ drawmenu(char *text) } int -textw(char *text) +textw(char *text) /* figure out how to remove me */ { return (text && *text) ? TEXTW(text) - lrpad / 4 : 0; } +/* I don't know how anyting here works */ static void setup(void) { @@ -174,14 +187,13 @@ setup(void) } } drw_resize(drw, mw, mh); - //drawmenu(); } static void usage(void) { fputs("usage: dmenu [-bfiv] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); + " [-bc color] [-fc color] [-w windowid]\n", stderr); exit(1); } @@ -208,9 +220,9 @@ main(int argc, char *argv[]) mon = atoi(argv[++i]); else if (!strcmp(argv[i], "-fn")) /* font or font set */ fonts[0] = argv[++i]; - else if (!strcmp(argv[i], "-b")) /* selected background color */ + else if (!strcmp(argv[i], "-bc")) /* bg color */ colors[Scheme][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-f")) /* selected foreground color */ + else if (!strcmp(argv[i], "-fc")) /* fg color */ colors[Scheme][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; @@ -233,12 +245,14 @@ main(int argc, char *argv[]) die("no fonts could be loaded."); lrpad = drw->fonts->h; + /* ??? */ #ifdef __OpenBSD__ if (pledge("stdio rpath", NULL) == -1) die("pledge"); #endif setup(); + do{ /* fgets adds a newline which will be printable in some fonts */ if(strlen(text) > 0) @@ -246,5 +260,5 @@ main(int argc, char *argv[]) drawmenu(text); }while(fgets(text, text_s, stdin) != NULL); - return 1; /* unreachable */ + return 0; } From 6cc84675b59a7be71e45eeab906b87a7519f6993 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 00:52:07 -0400 Subject: [PATCH 581/590] LOL ONLY SORTA WORKS :SHRUG: --- dmenubar/dmenubar.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dmenubar/dmenubar.c b/dmenubar/dmenubar.c index 1eb60ae..ee1cd35 100644 --- a/dmenubar/dmenubar.c +++ b/dmenubar/dmenubar.c @@ -253,12 +253,17 @@ main(int argc, char *argv[]) setup(); - do{ + /* might seem elementary but i made this mistake: + * you can't just let it exit 0 when you hit EOF because then + * stuff like `printf "hello\n" | dmenubar` won't have time to + * be shown. */ + for(;;){ + fgets(text, text_s, stdin); /* fgets adds a newline which will be printable in some fonts */ if(strlen(text) > 0) text[strlen(text)-1] = '\0'; drawmenu(text); - }while(fgets(text, text_s, stdin) != NULL); + } - return 0; + return 1; /* unreachable */ } From c3e36e8049c257a2c32026d1cc5a1ebb13728755 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 09:59:02 -0400 Subject: [PATCH 582/590] tweaks, style conformance, s/dmenu/dmenubar/ in more places --- dmenubar/config.def.h | 13 +++++++++++-- dmenubar/dmenubar.c | 31 ++++++++++++++----------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index 7dcc375..b38faac 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -1,13 +1,22 @@ /* See LICENSE file for copyright and license details. */ /* Default settings; some can be overriden by command line. */ +/* if this is true, dmenubar will exit 0 when it receives EOF from + * standard input. otherwise it'll just keep reading until you pkill + * it. */ +#define BREAK_ON_EOF 0 + 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 int text_s = 1024; /* chars to be allocated for the text displayed in the bar */ + +/* chars to be allocated for the text displayed in the bar */ +static const int text_s = 1024; + static const char *colors[SchemeLast][2] = { /* fg, bg */ - [Scheme] = { "#eeeeee", "#005577" }, + [Scheme] = { "#eeeeee", "#005577" } }; diff --git a/dmenubar/dmenubar.c b/dmenubar/dmenubar.c index ee1cd35..d9c0673 100644 --- a/dmenubar/dmenubar.c +++ b/dmenubar/dmenubar.c @@ -26,6 +26,8 @@ #include "drw.h" #include "util.h" +#define BREAK_ON_EOF 0 + /* 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))) @@ -64,7 +66,6 @@ cleanup(void) { size_t i; - XUngrabKey(dpy, AnyKey, AnyModifier, root); for (i = 0; i < SchemeLast; i++) free(scheme[i]); drw_free(drw); @@ -102,7 +103,7 @@ setup(void) XIM xim; Window w, dw, *dws; XWindowAttributes wa; - XClassHint ch = {"dmenu", "dmenu"}; + XClassHint ch = {"dmenubar", "dmenubar"}; #ifdef XINERAMA XineramaScreenInfo *info; Window pw; @@ -192,8 +193,8 @@ setup(void) static void usage(void) { - fputs("usage: dmenu [-bfiv] [-fn font] [-m monitor]\n" - " [-bc color] [-fc color] [-w windowid]\n", stderr); + fputs("usage: dmenubar [-bv] [-fn font] [-m monitor]\n" + " [-cb color] [-cf color] [-w windowid]\n", stderr); exit(1); } @@ -203,13 +204,13 @@ main(int argc, char *argv[]) XWindowAttributes wa; int i; char text[text_s]; - for(i = 0; i < text_s; ++i) + for(i = 0; i < text_s; ++i) /* initialize text[] */ text[i] = '\0'; for (i = 1; i < argc; i++) /* these options take no arguments */ if (!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION); + puts("dmenuBAR-"VERSION); exit(0); } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ topbar = 0; @@ -220,9 +221,9 @@ main(int argc, char *argv[]) mon = atoi(argv[++i]); else if (!strcmp(argv[i], "-fn")) /* font or font set */ fonts[0] = argv[++i]; - else if (!strcmp(argv[i], "-bc")) /* bg color */ + else if (!strcmp(argv[i], "-cb")) /* bg color */ colors[Scheme][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-fc")) /* fg color */ + else if (!strcmp(argv[i], "-cf")) /* fg color */ colors[Scheme][ColFg] = argv[++i]; else if (!strcmp(argv[i], "-w")) /* embedding window id */ embed = argv[++i]; @@ -253,17 +254,13 @@ main(int argc, char *argv[]) setup(); - /* might seem elementary but i made this mistake: - * you can't just let it exit 0 when you hit EOF because then - * stuff like `printf "hello\n" | dmenubar` won't have time to - * be shown. */ - for(;;){ - fgets(text, text_s, stdin); + do { /* fgets adds a newline which will be printable in some fonts */ - if(strlen(text) > 0) + if (strlen(text) > 0) text[strlen(text)-1] = '\0'; drawmenu(text); - } + } while (fgets(text, text_s, stdin) != NULL || !BREAK_ON_EOF); - return 1; /* unreachable */ + cleanup(); + return 0; } From a690038da5fc5c3d80187c6286cfd1563efa2366 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 10:06:08 -0400 Subject: [PATCH 583/590] fix some compiler warnings --- dmenubar/dmenubar.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/dmenubar/dmenubar.c b/dmenubar/dmenubar.c index d9c0673..f8f46fa 100644 --- a/dmenubar/dmenubar.c +++ b/dmenubar/dmenubar.c @@ -26,8 +26,6 @@ #include "drw.h" #include "util.h" -#define BREAK_ON_EOF 0 - /* 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))) @@ -58,9 +56,6 @@ static Clr *scheme[SchemeLast]; #include "config.h" -static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -static char *(*fstrstr)(const char *, const char *) = strstr; - static void cleanup(void) { @@ -73,10 +68,16 @@ cleanup(void) XCloseDisplay(dpy); } +int +textw(char *text) /* figure out how to remove me */ +{ + return (text && *text) ? TEXTW(text) - lrpad / 4 : 0; +} + static void drawmenu(char *text) { - int x = 0, y = 0, w; + int x = 0; drw_setscheme(drw, scheme[Scheme]); drw_rect(drw, 0, 0, mw, mh, 1, 1); @@ -87,12 +88,6 @@ drawmenu(char *text) drw_map(drw, win, 0, 0, mw, mh); } -int -textw(char *text) /* figure out how to remove me */ -{ - return (text && *text) ? TEXTW(text) - lrpad / 4 : 0; -} - /* I don't know how anyting here works */ static void setup(void) From 74d16592bab856d3bfe1bece30108e75d0b81c0a Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 10:26:12 -0400 Subject: [PATCH 584/590] remove stest --- dmenubar/Makefile | 18 +++----- dmenubar/stest.1 | 90 -------------------------------------- dmenubar/stest.c | 109 ---------------------------------------------- 3 files changed, 5 insertions(+), 212 deletions(-) delete mode 100644 dmenubar/stest.1 delete mode 100644 dmenubar/stest.c diff --git a/dmenubar/Makefile b/dmenubar/Makefile index 808804b..989fbc9 100644 --- a/dmenubar/Makefile +++ b/dmenubar/Makefile @@ -3,10 +3,10 @@ include config.mk -SRC = drw.c dmenubar.c stest.c util.c +SRC = drw.c dmenubar.c util.c OBJ = $(SRC:.c=.o) -all: options dmenubar stest +all: options dmenubar options: @echo dmenu build options: @@ -25,16 +25,13 @@ $(OBJ): arg.h config.h config.mk drw.h dmenubar: dmenubar.o drw.o util.o $(CC) -o $@ dmenubar.o drw.o util.o $(LDFLAGS) -stest: stest.o - $(CC) -o $@ stest.o $(LDFLAGS) - clean: - rm -f dmenubar stest $(OBJ) dmenubar-$(VERSION).tar.gz + rm -f dmenubar $(OBJ) dmenubar-$(VERSION).tar.gz dist: clean mkdir -p dmenubar-$(VERSION) cp LICENSE Makefile README arg.h config.def.h config.mk dmenubar.1\ - drw.h util.h stest.1 $(SRC)\ + drw.h util.h $(SRC)\ dmenubar-$(VERSION) tar -cf dmenubar-$(VERSION).tar dmenubar-$(VERSION) gzip dmenubar-$(VERSION).tar @@ -42,19 +39,14 @@ dist: clean install: all mkdir -p $(DESTDIR)$(PREFIX)/bin - cp -f dmenubar stest $(DESTDIR)$(PREFIX)/bin + cp -f dmenubar $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenubar - chmod 755 $(DESTDIR)$(PREFIX)/bin/stest mkdir -p $(DESTDIR)$(MANPREFIX)/man1 sed "s/VERSION/$(VERSION)/g" < dmenubar.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenubar.1 - sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenubar.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/dmenubar\ - $(DESTDIR)$(PREFIX)/bin/stest\ $(DESTDIR)$(MANPREFIX)/man1/dmenubar.1\ - $(DESTDIR)$(MANPREFIX)/man1/stest.1 .PHONY: all options clean dist install uninstall diff --git a/dmenubar/stest.1 b/dmenubar/stest.1 deleted file mode 100644 index 2667d8a..0000000 --- a/dmenubar/stest.1 +++ /dev/null @@ -1,90 +0,0 @@ -.TH STEST 1 dmenu\-VERSION -.SH NAME -stest \- filter a list of files by properties -.SH SYNOPSIS -.B stest -.RB [ -abcdefghlpqrsuwx ] -.RB [ -n -.IR file ] -.RB [ -o -.IR file ] -.RI [ file ...] -.SH DESCRIPTION -.B stest -takes a list of files and filters by the files' properties, analogous to -.IR test (1). -Files which pass all tests are printed to stdout. If no files are given, stest -reads files from stdin. -.SH OPTIONS -.TP -.B \-a -Test hidden files. -.TP -.B \-b -Test that files are block specials. -.TP -.B \-c -Test that files are character specials. -.TP -.B \-d -Test that files are directories. -.TP -.B \-e -Test that files exist. -.TP -.B \-f -Test that files are regular files. -.TP -.B \-g -Test that files have their set-group-ID flag set. -.TP -.B \-h -Test that files are symbolic links. -.TP -.B \-l -Test the contents of a directory given as an argument. -.TP -.BI \-n " file" -Test that files are newer than -.IR file . -.TP -.BI \-o " file" -Test that files are older than -.IR file . -.TP -.B \-p -Test that files are named pipes. -.TP -.B \-q -No files are printed, only the exit status is returned. -.TP -.B \-r -Test that files are readable. -.TP -.B \-s -Test that files are not empty. -.TP -.B \-u -Test that files have their set-user-ID flag set. -.TP -.B \-v -Invert the sense of tests, only failing files pass. -.TP -.B \-w -Test that files are writable. -.TP -.B \-x -Test that files are executable. -.SH EXIT STATUS -.TP -.B 0 -At least one file passed all tests. -.TP -.B 1 -No files passed all tests. -.TP -.B 2 -An error occurred. -.SH SEE ALSO -.IR dmenu (1), -.IR test (1) diff --git a/dmenubar/stest.c b/dmenubar/stest.c deleted file mode 100644 index 7a7b0bc..0000000 --- a/dmenubar/stest.c +++ /dev/null @@ -1,109 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <sys/stat.h> - -#include <dirent.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "arg.h" -char *argv0; - -#define FLAG(x) (flag[(x)-'a']) - -static void test(const char *, const char *); -static void usage(void); - -static int match = 0; -static int flag[26]; -static struct stat old, new; - -static void -test(const char *path, const char *name) -{ - struct stat st, ln; - - if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ - && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ - && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ - && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ - && (!FLAG('e') || access(path, F_OK) == 0) /* exists */ - && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */ - && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */ - && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */ - && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */ - && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */ - && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */ - && (!FLAG('r') || access(path, R_OK) == 0) /* readable */ - && (!FLAG('s') || st.st_size > 0) /* not empty */ - && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */ - && (!FLAG('w') || access(path, W_OK) == 0) /* writable */ - && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */ - if (FLAG('q')) - exit(0); - match = 1; - puts(name); - } -} - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] " - "[-n file] [-o file] [file...]\n", argv0); - exit(2); /* like test(1) return > 1 on error */ -} - -int -main(int argc, char *argv[]) -{ - struct dirent *d; - char path[PATH_MAX], *line = NULL, *file; - size_t linesiz = 0; - ssize_t n; - DIR *dir; - int r; - - ARGBEGIN { - case 'n': /* newer than file */ - case 'o': /* older than file */ - file = EARGF(usage()); - if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old)))) - perror(file); - break; - default: - /* miscellaneous operators */ - if (strchr("abcdefghlpqrsuvwx", ARGC())) - FLAG(ARGC()) = 1; - else - usage(); /* unknown flag */ - } ARGEND; - - if (!argc) { - /* read list from stdin */ - while ((n = getline(&line, &linesiz, stdin)) > 0) { - if (n && line[n - 1] == '\n') - line[n - 1] = '\0'; - test(line, line); - } - free(line); - } else { - for (; argc; argc--, argv++) { - if (FLAG('l') && (dir = opendir(*argv))) { - /* test directory contents */ - while ((d = readdir(dir))) { - r = snprintf(path, sizeof path, "%s/%s", - *argv, d->d_name); - if (r >= 0 && (size_t)r < sizeof path) - test(path, d->d_name); - } - closedir(dir); - } else { - test(*argv, *argv); - } - } - } - return match ? 0 : 1; -} From 29554720167691b7f67bf3274eeb367b0fa4df41 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 11:29:23 -0400 Subject: [PATCH 585/590] real readme --- dmenubar/README.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/dmenubar/README.md b/dmenubar/README.md index 361f21f..23a8426 100644 --- a/dmenubar/README.md +++ b/dmenubar/README.md @@ -3,9 +3,34 @@ dmenu is an efficient dynamic menu for X. dmenubar is a HACK of dmenu that displays a menu bar. -** There are no guarantees at any time that this project works or is stable. Please don't rely on it. ** +## Why -Lemonbar is an excellent replacement. +lemonbar [can't do TTF fonts](https://github.com/LemonBoy/bar/issues/188). + +dmenubar intends to be a knockoff of lemonbar that can do TTF, basically. +I tore out a ton of the dmenu code, made stdin feed into the dmenu prompt, and +presto flavo. Code's not great but dmenubar.c (where most of the changes are) +is only ~300 lines so it could be worse. + +## You shouldn't use this + +If you use any features of lemonbar outside of the default settings you +probably won't be able to make dmenubar fit your workflow. + +The biggest issue is dmenubar draws *over* other windows the same way dmenu +does. I have my keybindings like this in sxhkd so I can pull up dmenubar and +then kill it when I'm done looking: + +``` +mod1 + i + ps x | grep dmenubar | grep -v grep && pkill dmenubar; \ + show_bar_stuff | /home/trinity/src/dmenubar/dmenubar -b + +mod1 + shift + i + pkill dmenubar +``` + +*Maybe* somebody will prefer this over how lemonbar does it? I don't know. ## Requirements From c41c548da059149bcff80520c807fe50b06cb1fd Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 11:31:37 -0400 Subject: [PATCH 586/590] one more thing --- dmenubar/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dmenubar/README.md b/dmenubar/README.md index 23a8426..f95c635 100644 --- a/dmenubar/README.md +++ b/dmenubar/README.md @@ -15,7 +15,9 @@ is only ~300 lines so it could be worse. ## You shouldn't use this If you use any features of lemonbar outside of the default settings you -probably won't be able to make dmenubar fit your workflow. +probably won't be able to make dmenubar fit your workflow. Cosmetically, dmenu +lets you change the font and colors and whether it's on the top or the bottom +of the screen and that's about it. The biggest issue is dmenubar draws *over* other windows the same way dmenu does. I have my keybindings like this in sxhkd so I can pull up dmenubar and From 5e0cfa53efde74b8b4bb6e18b5795c0f7f7a593f Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 11:32:24 -0400 Subject: [PATCH 587/590] minor fix --- dmenubar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenubar/README.md b/dmenubar/README.md index f95c635..3b79c97 100644 --- a/dmenubar/README.md +++ b/dmenubar/README.md @@ -1,7 +1,7 @@ # dmenubar - dynamic menu bar dmenu is an efficient dynamic menu for X. -dmenubar is a HACK of dmenu that displays a menu bar. +dmenubar is a hack on dmenu that displays a menu bar. ## Why From 2984ffe6e75b5201aa7e8da661172fb28d5c95c6 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Sun, 16 May 2021 12:34:38 -0400 Subject: [PATCH 588/590] add screenshot --- dmenubar/README.md | 1 + dmenubar/screenshot.png | Bin 0 -> 19093 bytes 2 files changed, 1 insertion(+) create mode 100644 dmenubar/screenshot.png diff --git a/dmenubar/README.md b/dmenubar/README.md index 3b79c97..92ab8a7 100644 --- a/dmenubar/README.md +++ b/dmenubar/README.md @@ -3,6 +3,7 @@ dmenu is an efficient dynamic menu for X. dmenubar is a hack on dmenu that displays a menu bar. +![Screenshot of dmenubar displaying "Pretty cool!", as input in the terminal.](screenshot.png) ## Why lemonbar [can't do TTF fonts](https://github.com/LemonBoy/bar/issues/188). diff --git a/dmenubar/screenshot.png b/dmenubar/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..1f12c1fbc76008a4a26eb84110705ebbd3422500 GIT binary patch literal 19093 zcmeHPdpOkT+aH5aIkYw^g<Z*R4r7<dag=Qpp#xD<bXW;7P8p{;sEvB9Y;95NFjA9p z8gdwnF(X@kONJdXIm{p-jhT@#hB>~|X7}~&+CSdwdVhOe`~I%s4`0vsdG6;ve(w8z z=HcoA9}msdn^uEBAkBSyzc~Z~smdRfjn%>OA3R}T`TO7EcJK33S63ez^Bo0&j6wUp z+2xlQ#Ac-Y_+3bn+UT8-<2rtBZas%u&2tdDzT9<xKX}tsea~jUzU@zcIoAw(2HW^) zmj7?Gjy;y%TaTEA+cJL~#T_{F`IXhDH8vbnS-&>(_>qL8zo{<Rg`Epa@xgNU3*_I} zB^QxL_>yoQ(IQ9+{+HO<#iqulJ9+#EsEWFdu^R@Y1pfWuWW}0t7)!M@`;UPSZ-%!U zgYuL=Oj(|LMdx<r!`R!OPjN(2M8V>)Qx|n+c(ITyAs`}O?s%Se-2G3Y?;j%9eF0S} zWbl&ki44AMKAi=f7qVPuOEa0NPYeu`r%c-?8dHpTY_#*(Mpl^xj{o+8`E0inO4>nA z?ndDyv^!4Wa67>-`pt8txh~&v2lXvKS;04k(znLqlQ4U<?0HE+^(i_h#VBs3x<vf+ zaJ{&zM4EKZ<KE#Bf3>auBPj-yrj#}bawbQxvY@21z4dpzb5mdC-!n`Q$7FEcjb*{6 zLMIEw#knNWB%VC+AR|9@-i6yZ)E_71*`S3`I(L|D)xJgM0e2Ao=q?zHnF!G*^K?TC zs$-_2)La(K&5U>t8BrwOBW_CDBO99`)cmasvaHx!O|M_uaV`ShGBP!?bX5?HfYAzx zf)r-Vle7}7@FJIK3yl^I>7Nz2F0L!dU%U-<cx{z39NV@u;v(9CCCzkDUl2#wOWlr~ z3mIGDdzwb1qfdCu#Ybx(Gn|9RARMkLz)t5#ZgC)vIlO%#579MaLx@T^J6Uh+NbJ6M zEtPXL7`*^<MMw(O4C_V~e72+Jdkf#Sss&5>wPmaU`*QSiU91=ZaeXz#l~T3w4uY4t z*rBC|ya7Csl@g2=h7CoH)YPKbrX`VyGa4CeUaO5gd*-{BBIuiaEd0);4Ex+(?(-&z zk#sD;6~&DsFXU%OHbh0q%%BM)5_;G1MxK@jHu?#Xi=K#(Ni#<Zp>O;l&eD6`LjE{( zp~jMj<M#^=DFK|c$M}HMaJ0p~i^`aOW9Bk>m1U0>gu>u5(EN<BOCLKo(TQ(Jn##&U zE#2xwks`81EsHTMC~q2%o(s*xH%SM3eW6^K$S7IN$QVSoE+sIcpDhJIXJ_4wqFJ!1 zYtAz$7JB}kjN^R4N_tfA<2@}Wp^z7xG-#@SUfks$5d02;C68Y8i7zBh*%*<g?5WNy zn}Dc+sxdR};**dR=egEwZmMo<7^wj*xV*G9bZwM3lDRYK&dQ+b-QFWsNnEJRc8X~` zSkO+Yu_2t7&V>c1j&RX-bK)Fxd}A|2i^@h*E^!(Jckw9xK0>aeQw_g~<f#3Fhs1_F zcF~K97MfsD**vR8PLMBpaV7vN%{0hcc*#x^yhQY_CpVuyWmmw6z+OVgx>N&XoZsGg z)6a{a4l8qN1Wg05xAf2^Y=hOvIo86KA^1Rl3g$#hk2yfu)>+^#rNqhfH8R%5;Fr<7 zYp_a2{CJKk)G$e!!*<%99TJKNN}Br;>v-XCTkqgq^@PaA`MBIIyvJ=?i#^?1E>Y4F z{Nk?*dq(<y9k_HbWz5s;7a7MljP%Zm2ZJ*c#%Jm$`uh{LA;4&Ut@1Op*qO{Cz^s-g z@K&VC8>k3s&3J$TWB^53moekI;Tt$98AYcKT!<q`z9?5khtsFvjy$o<X|^hZG=D`D zMV!6CwYY&s1PMF4M24~1?s_?2%Z3ap8zy`*n8<8S5+|_-C16%h%o!xy>PI6=3!DgD z&)G2<Z@+TFB3s_9F>;x+2}lMz?>%#QrQs@c&S_EZ-HhgSLu09MtoZqOFu#YmrFjIE z0i7R1BWVZQhozXLDNR`A&(K+Iqk8TMPSp^HC~-B>@1L@l&9;v;^qK^vEM9}4xTP>X zho_a9WQinh!ReK<nd{;#k+Bpc*txjJ%z3Wg$dPoWEtE{)YoNv7Pi=1QZWW+<h6;t0 zJV?Xhj8BeL1%mtd%(!+XiKlCnLRRC{(3MiC{OOs5#cE&K;$baj#PzmBfZwS+@H=@u z+buix?Ut#6cLP7w%Ubga1;h4?q{(z|19DueKq^__b{5FGe3>GgS~GV5BAnjGN{}v= z6$D?ZeOIrot4}8cp$4B06((c7x*LjlymGyz8dd-_@mCR@#QvonIro}46Vp4%qlzZ! zQ6%m{oDWpu&B{*cjgZYy?o`N9eme?ToS7iE@E_p#L!8GEy&kUo3X`Bjv3>SYGK+>c zTF@RL3lT=ig$x0O2tA8;X@66<*FR_*0KcnOKbJ>d))_|h{=6;@Uz{sj>a-KLe^nAp z9ED}K*ODRuxy{)7WU5h`VczfzhsaIBW^7rashyY3HyYqZsv8HdthDg}xK|%TXY+2* z#S@KYj4A!lRDNHCc#tvk&d+5zRsNpdo|#!!$Y};&PWXH!Yf9iPY11j-a!Wugxt#=q z<KXC7L%7StO^uoJUI3srwzdRwcTRljiz&fvr0xP_Pu=x87_*LuIKYD2dP+)(#~jBt z12(ZfC?73uwliDFPg>ZzhZ>X`g5*w)vZLBc0n~LiWVm^Q4BP7$R;E+AGI~voLB0Xd z{PdNIQQ5ZD+P;A+7K=xV*8{jQ?g>}&#lRS@8Ni)Ssj7^g!X5Vj$Wx)G^OsXgN0f&} zs(V{>69aeC*R5p8%|NBp7c;@Mi|^W~0jOBMOA7}XCMm;L&X%(rsq=8vD95A7MJ>vm zn|~c3#J4(uIvCu@y4S}&foy#eIO|^Jycp@v-JJ8$iiaqb<nIYhHvz-ywH|JuC|`U& za5(2PV-Q5S8wOys$OR0JPD!4)4=`8N+O(fR!%Ihd7)ENOA0kP&fb{q0%8gT4sqCov zvC%LfXRSRcD>d<Z4YcS&Ve|?kDThaPd{pgRS9Ml0yz|@u5EDgNa;6N3lg|N6SwEIj z|N4$SfV!K3>YwIm$YRHz1(^Q}4L>ZXlVtiO3qYwSTyCAH3twsZ0u-&{34Q?@mZ;ZG zQA{BptvHmXsuU=U4Ab9|2hfGy`VYoA(buU8+~ZK%TaO~xvGg;#03S#@tEAL0&|U_Z zT=lJr%IFT--VmT{H5kzF%(y>5q(Bq!4y6WOO%V~Qm7I0+;ab33V{4nkx|nJJ8BkiC znK1}YDl7${iAuPNp4f1d!$KKEXZ>UfAakw}V@9!r7mWjWr$mFnv(Y}408mNGS)=}! zQ(thEI1=#I5e?_fMP)$qZUMhAqr}3Ugp)S`YOpSL+X2d6OvnXn3rb5+_fw7*nDi7X z6Yiz>>;o9heT{`Wg~siPvI3UTIT{v=p9LC<>&sKFd406P4+?gfH#o5uFsw4T)fhy0 z1fv3@&r1#px%;QG0F3r*lN-^S5qkunwZO;nu;7R--f*%n1<gHRenkI)chNSG@6ft} z41fozTLim-f?Dow0qRH<yauHmEohcoXN_?33SfKdV!3%tE;i-^2n~KI=f4K-;|&nY zWVQNVO+6qn9A!e><_ak6^A8UL^zBA+<7-q6!?@o8!~U4n0Zob}r2QQLKrr&@J3t61 znC%cv$^rW7xeCffkcFhaK3mHNz*MIC2jf^3PlNzec&@^YZ_-m?`Ah3ZoBTxaR2ik3 zm8FnRJesx$GFh2Nl)$>WfmcD!)onw!0UA+XYi|7xbX?ea%zP;@(UiNxqL~HI^2rd@ zaBx*a!(+>6djKDS8gc-1em0b2D7*GfuO8s>O5is2{dOSjI57RAI9sn1IGchY3JmCQ z<w~U3X>q(r1TjeUlJQBG{Oul<BV^U5%A{bALA0uHOb=+%&(hW-!NY5Cmo^f4haj0p zq_oBcXzzltC(HEFAd8rJW`G<Y3<M=>P4G{vDVMZQ=9RI(?cvBGTVk8>36~I%*la`` z5s;`T^Xh%6D#^)ObeCUW)56f65Jt#^%~I`>llDpo?@yQ8QV=^j+X|mO#U1U4txAXf z8q0Y_0`OW@uUcx9mSaaxAp5V(plN|=Z*@l}+-;qu?E5TgSsVIgL#(8DtT{>6nlaQx zhhU#*0SH;Uya!yJV6TiI+uQ|m%<QWUPaZUZ@RoeGk7e$^wy-2_7yI<1RG`>BtL0dn zs4<PG+B+T7^ULa$0;rcay>~fcWioU#z~kg4!U4%=fx1mukwDL)yp;z?8H>vSa8|Wj z4t1+{5rGM=ywZ(d;)d|C$uYWI*W_RKiqkvYEI!Pa{ajWjI5E*FnAVz_6|F^2*k()S z$~Fw&wGG4ZPo;Vyj#9TmrkvaI8{@l9TH?&}=m9MG0l=ozx~2Sa+J<KQa?w(B;=MjZ zn~Hh46RBNvtIN|4kwaw9yn3GRP||}?T9a8=ov#3TKvG=-^9w`P%?6A*>$1l`p+YNp zKh$=ALTx-|GS>1z5X$z|pQ1GnO_^s?jW#C6l1@1}4As@vI7}zR)onh)YKaI-FS)CS z%ul!4sr<VJZ?94sQFhim5xoi!3AY>GM<mYRh->IeG5LW29aS;6v0jQy&a*uZeV!!L z?yW+@%O=|p5c3x>B6`Xa#~<Y7T5&1_Qd(*s?K1;v&6^5ywWx-tC&O?&`}1EX7IHiZ zvr@7)vl5M4(8KX=riR;3GjVf=xc!%=@aLIJ?X*<806)j?+N3yM?p}jb&(OT%BuU21 zi<i(<43ix)gM*F>#jH9>g=Ia_-|_<cG_N88{+sW?Q;!%Ggne8{ok;-k<v_H<ea$KE zj%t}+9bFJSU|B^I3^s*-8Lscq6o$y4!NLWEWq_{rk^{3qCX+^e#ke(*T43AY8`@39 z;@AV|!VXuGrka3@JXrSzDH3quq0=omKJ5#?mS)z8{-Y2^Q>}j}vZ^wj*C+I=<T4`q z+HA4t`*8_yhCv>)I%13G)cKvh748V$p6&s3dJOw8EP%VU3!l)z6>M}yvxl5AHC;8~ z(=C0C)5QWd*9-0Lm6zL}x5bmY2}O#h(vTv&QFG_4l%aRiSq))TVJnE4b-tBsj<jIl z5=i!m1fMo`T%e=xbc<;>&9%-fEYN~qEy}qnw9W7ETK0r+jXsspNr?UtRuN9L&;n)! z^+=AD##i&}7vsqbY^195!n3T-Q^!R=kSH3F4PgF4Y~S~uw@V`fC~?L7dWl%~X|=<L zD6=k*S09P9MU2ff(Xo;n4r=(|id!6wT%*xEmL;+);8^g+tkwr>3q$>|XESgwb|g}9 z>|R;r!ET3A_v!E3W^Aq|drjS$7h3augll`NWDj{q9C>e(wWNZ(a$$uuDl~B<CMk#7 zSj%sXvx+q0E+g*)?~@Nf!w&IW)*>}mwE!A1-6<T*vF(GEl4^s9veg#XCY&|3%nv-7 zC7kPY$iV;WR<A|Xs>w(T88UEpb~xARa$()nOy7`^DEB}MVHvi|ta^l4Fhlco8Rrd1 zMcu-qD9^rWdiS%yYxf0zHvYEiYxyb-BK|peE=^|3MDL2UVmDW#Nd(^z(pUo{_gS6q z^tZU=jAm}Jt3*(dS`pl|XZm3s3+L@g#qn>rv%Pbx0v$u~o$j20XzC#B=37ffWjrzr z*@yI`3-H=ljg(CV<NU1=GUQD2G1g(n?vB18lGpTF(~N_3k-+FdrBq@tSy96-LO;sJ ziE{eAwsp>&f%|M);F9{dJ#vzbr6*?eSxlVF8Aq^4?)!?`w%0Y&@cD8%N-2F`Al<?{ zCuhK(1b|2cTXc29YuL?ee#D^CvirfreS%jsFS$=!I<jztoBe8p@P^0pw7o1`rkXEp zxIG=YD!8<KZIE@MU@{^+_(Xinzs^`R`A*c<(Y25Ck-uKdk=~jN$P>|!7os!dVGuMN zT{y_{5(%s-kpb+}p=Af@5!|4``w6o2%m_R@+A8t|3@;YcEX?90B76Ms!}yWw3-B-M z=MS-w5&9`+VW<nU6dX&9o;zvN&^@}beA!sN7CpjjH(#5|nvWCPTK>8>rke?}*2}VA zQ#CNm-59rWj12XxK4@$?0Pd@9TaUTS+=rk_RknkrI2hylhI_INgkvXk5r6cB`|~hz z@-UBlV0E_bb7PSHQ77!~%~G?TPZ96HfNZlrgK{z3O?yc<uVno7nVpy6wFb(?mMcq) zo=?(#Hlq~4p)8czU~C~e#}J#-A8@%WV7hde;SESdCr#zW$gC%mNm@z34MXWrSErbd z&sYI7R0r5yvgv+0SF=)LH^@BAh1}})qgM)oYu><>9+BYfv3-31Nkj?&%mcrC&kYIQ zTXDaKiFkfwjy;;p&0^#VW!12N5M<wJqS}UL?nBl+CY=x1ttaUH!dt^m6Lod0+QZkT z6IZ?tY<u66G!C{>24s)MCk6Ga7p<N{7f>apE6cPrRN8grSz~O`&U2>$XICon%6Kvb zQ^LN|H8qWFkL87UC0>Yif{a<qZMm|b>-;qE2#Dh<Vy}AIp?22`@}g1z(K_rqA!M4o zkp~Ocl%r+B-Lz8T+JKX-9z|Y8XXR&79YIgL>fqCsT1#7=*5%pem&8kGOd1pAw2W;Z zcs;F}!&ljP#CzFymbdS5O#4c#Q(oOSEE^?^g|P!UA-XH~(NX_&5ec$FE+mG$debp% zTGi?aJQb>xdsm(cV96C79gN9f`Ch=F4yJ3R#476F$c?`)^2k<z->Fm10u-b2xx9b8 zVrPB>uvX=y%}V_%f!E2~>TmMa0~;uC)ka{0s;;E8v$*TO0PU2L(#y4gV%P0^3~2Lj zXZQSxlkeYRK<8HheAjrl8|d1(n$H1#?gp|`Ug<r?I`V@FkJ_Wx0fW|bliOHqJMhFw zrN30(`9##!yaiO`X{umwRoXvM3i$_A0K@4hjK1ume`$1ux|Y4=e-|SPbt%;K_aU$` z$)MZ*kGlX09Q%-_6@j^2uKYW5y#mJ+IQBQ<m;$>L*!8#dDGKaTV3z{B(*7BT28v)* z1fwDt6~Xw&A>{w315X8ZDX>d{T?*_{VAp^AXIl!WS3tc2>J?D0fO-Yg|Bi%;TOZ4} z0u-51kr@@4@gJBOpH^O_f<UWxy#K!dzq_d7B9r1G)4%Pqp91z3u&;pqe<18Dp#F~@ z?fvCs#huk<nEF55>sCPhe<;+a4G_re$aR;u1OEu&v8vQ4BJ1&*i2EG@Ao<t6JwD%5 J?ml_(zX3d_A+i7f literal 0 HcmV?d00001 From d12a7031af828feb0ac392402feee5a73537f92a Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Fri, 2 Jul 2021 19:13:22 -0400 Subject: [PATCH 589/590] alpine deps --- dmenubar/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dmenubar/README.md b/dmenubar/README.md index 92ab8a7..6702bdf 100644 --- a/dmenubar/README.md +++ b/dmenubar/README.md @@ -39,6 +39,12 @@ mod1 + shift + i In order to build dmenu you need the Xlib header files. +On Alpine Linux: + +``` +apk add libx11-dev libxinerama-dev libxft-dev +``` + ## Installation Edit config.mk to match your local setup (dmenu is installed into From da081c1b84bda2327b1b585e68344729d208c597 Mon Sep 17 00:00:00 2001 From: Deven Blake <blakedevendesu@gmail.com> Date: Fri, 2 Jul 2021 19:13:48 -0400 Subject: [PATCH 590/590] additional stdin passthrough option --- dmenubar/config.def.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dmenubar/config.def.h b/dmenubar/config.def.h index b38faac..ade02c0 100644 --- a/dmenubar/config.def.h +++ b/dmenubar/config.def.h @@ -6,7 +6,11 @@ * it. */ #define BREAK_ON_EOF 0 -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ +/* output stdin */ +static int stdin_passthrough = 1; + +/* -b option; if 0, dmenu appears at bottom */ +static int topbar = 1; /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = {