Compare commits

..

No commits in common. "16bf21ec367ebe53f98fa768c464094b1818a3fc" and "03b6df0414a32da893ecb9295c082ec67723c8f2" have entirely different histories.

8 changed files with 43 additions and 164 deletions

View File

@ -11,7 +11,10 @@ all: dmenu stest
.c.o: .c.o:
$(CC) -c $(CFLAGS) $< $(CC) -c $(CFLAGS) $<
$(OBJ): arg.h config.def.h config.mk drw.h config.h:
cp config.def.h $@
$(OBJ): arg.h config.h config.mk drw.h
dmenu: dmenu.o drw.o util.o dmenu: dmenu.o drw.o util.o
$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
@ -24,7 +27,7 @@ clean:
dist: clean dist: clean
mkdir -p dmenu-$(VERSION) mkdir -p dmenu-$(VERSION)
cp LICENSE Makefile dmenu_run.sh README arg.h config.def.h config.mk dmenu.1\ cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
drw.h util.h stest.1 $(SRC)\ drw.h util.h stest.1 $(SRC)\
dmenu-$(VERSION) dmenu-$(VERSION)
tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
@ -33,10 +36,9 @@ dist: clean
install: all install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f dmenu dmenu_run.sh stest $(DESTDIR)$(PREFIX)/bin cp -f dmenu stest $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run.sh
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
mkdir -p $(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
sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
@ -45,9 +47,8 @@ install: all
uninstall: uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
$(DESTDIR)$(PREFIX)/bin/dmenu_run\
$(DESTDIR)$(PREFIX)/bin/dmenu_run.sh\
$(DESTDIR)$(PREFIX)/bin/dmenu_path\ $(DESTDIR)$(PREFIX)/bin/dmenu_path\
$(DESTDIR)$(PREFIX)/bin/dmenu_run\
$(DESTDIR)$(PREFIX)/bin/stest\ $(DESTDIR)$(PREFIX)/bin/stest\
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
$(DESTDIR)$(MANPREFIX)/man1/stest.1 $(DESTDIR)$(MANPREFIX)/man1/stest.1

View File

@ -2,43 +2,24 @@
/* Default settings; can be overriden by command line. */ /* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
static const unsigned int alpha = 0xe3; /* Amount of opacity. 0xff is opaque */
static int centered = 1; /* -c option; centers dmenu on screen */
static int min_width = 1000; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */ /* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = { static const char *fonts[] = {
"monospace:size=17", "monospace:size=10"
"Noto Color Emoji:size=17"
}; };
static const char *prompt = NULL; /* -p option; prompt to the left of input field */ static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static const char *colors[SchemeLast][2] = { static const char *colors[SchemeLast][2] = {
/* fg bg */ /* fg bg */
[SchemeNorm] = { "#dddddd", "#222222" }, [SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#ffffff", "#ff0000" }, [SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#bc3d2f" }, [SchemeOut] = { "#000000", "#00ffff" },
[SchemeCaret] = { "#fe5e5e", "#222222" },
[SchemeBorder] = { "#dc0000", NULL },
}; };
/* -l and -g options; controls number of lines and columns in grid if > 0 */ /* -l and -g options; controls number of lines and columns in grid if > 0 */
static unsigned int lines = 9; static unsigned int lines = 9;
static unsigned int columns = 4; static unsigned int columns = 4;
static const unsigned int alphas[SchemeLast][2] = {
[SchemeNorm] = { OPAQUE, alpha },
[SchemeSel] = { OPAQUE, alpha },
[SchemeOut] = { OPAQUE, alpha },
[SchemeCaret] = { OPAQUE, OPAQUE },
[SchemeBorder] = { 0xf2, 0xf2 },
};
/* /*
* Characters not considered part of a word while deleting words * Characters not considered part of a word while deleting words
* for example: " /?\"&[]" * for example: " /?\"&[]"
*/ */
static const char worddelimiters[] = " "; static const char worddelimiters[] = " ";
/* Size of the window border */
static unsigned int border_width = 3;

View File

@ -21,7 +21,7 @@ FREETYPEINC = /usr/include/freetype2
# includes and libs # includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC) INCS = -I$(X11INC) -I$(FREETYPEINC)
LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lXrender LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
# flags # flags
CPPFLAGS = -D_DEFAULT_SOURCE -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)

View File

@ -42,9 +42,6 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
.B \-b .B \-b
dmenu appears at the bottom of the screen. dmenu appears at the bottom of the screen.
.TP .TP
.B \-c
dmenu appears centered on the screen.
.TP
.B \-f .B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This 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. is faster, but will lock up X until stdin reaches end\-of\-file.

112
dmenu.c
View File

@ -10,12 +10,10 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#ifdef XINERAMA #ifdef XINERAMA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif #endif
#include <X11/extensions/Xrender.h>
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
#include "drw.h" #include "drw.h"
@ -26,10 +24,8 @@
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
#define OPAQUE 0xffu
/* enums */ /* enums */
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeCaret, SchemeBorder, SchemeLast }; /* color schemes */ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
struct item { struct item {
char *text; char *text;
@ -57,16 +53,10 @@ static XIC xic;
static Drw *drw; static Drw *drw;
static Clr *scheme[SchemeLast]; static Clr *scheme[SchemeLast];
static int useargb = 0; #include "config.h"
static Visual *visual;
static int depth;
static Colormap cmap;
#include "config.def.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr; static char *(*fstrstr)(const char *, const char *) = strstr;
static void xinitvisual();
static unsigned int static unsigned int
textw_clamp(const char *str, unsigned int n) textw_clamp(const char *str, unsigned int n)
@ -106,15 +96,6 @@ calcoffsets(void)
break; break;
} }
static int
max_textw(void)
{
int len = 0;
for (struct item *item = items; item && item->text; item++)
len = MAX(TEXTW(item->text), len);
return len;
}
static void static void
cleanup(void) cleanup(void)
{ {
@ -183,7 +164,7 @@ drawmenu(void)
curpos = TEXTW(text) - TEXTW(&text[cursor]); curpos = TEXTW(text) - TEXTW(&text[cursor]);
if ((curpos += lrpad / 2 - 1) < w) { if ((curpos += lrpad / 2 - 1) < w) {
drw_setscheme(drw, scheme[SchemeCaret]); drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
} }
@ -700,7 +681,7 @@ setup(void)
#endif #endif
/* init appearance */ /* init appearance */
for (j = 0; j < SchemeLast; j++) for (j = 0; j < SchemeLast; j++)
scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2); scheme[j] = drw_scm_create(drw, colors[j], 2);
clip = XInternAtom(dpy, "CLIPBOARD", False); clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False);
@ -709,7 +690,6 @@ setup(void)
bh = drw->fonts->h + 2; bh = drw->fonts->h + 2;
lines = MAX(lines, 0); lines = MAX(lines, 0);
mh = (lines + 1) * bh; mh = (lines + 1) * bh;
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
#ifdef XINERAMA #ifdef XINERAMA
i = 0; i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
@ -736,16 +716,9 @@ setup(void)
if (INTERSECT(x, y, 1, 1, info[i]) != 0) if (INTERSECT(x, y, 1, 1, info[i]) != 0)
break; break;
if (centered) { x = info[i].x_org;
mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
x = info[i].x_org + ((info[i].width - mw) / 2); mw = info[i].width;
y = info[i].y_org + ((info[i].height - mh) / 2);
} else {
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
mw = info[i].width;
}
XFree(info); XFree(info);
} else } else
#endif #endif
@ -753,16 +726,9 @@ setup(void)
if (!XGetWindowAttributes(dpy, parentwin, &wa)) if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx", die("could not get embedding window attributes: 0x%lx",
parentwin); parentwin);
x = 0;
if (centered) { y = topbar ? 0 : wa.height - mh;
mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); mw = wa.width;
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
} else {
x = 0;
y = topbar ? 0 : wa.height - mh;
mw = wa.width;
}
} }
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
inputw = mw / 3; /* input width: ~33% of monitor width */ inputw = mw / 3; /* input width: ~33% of monitor width */
@ -770,16 +736,11 @@ setup(void)
/* create menu window */ /* create menu window */
swa.override_redirect = True; swa.override_redirect = True;
swa.background_pixel = 0; swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
swa.colormap = cmap;
// swa.border_pixel = scheme[SchemeBorder][ColFg].pixel;
swa.border_pixel = 0;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, root, x, y, mw, mh, border_width, win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
depth, CopyFromParent, visual, CopyFromParent, CopyFromParent, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa); CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
if (border_width)
XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColFg].pixel);
XSetClassHint(dpy, win, &ch); XSetClassHint(dpy, win, &ch);
/* input methods */ /* input methods */
@ -826,8 +787,6 @@ main(int argc, char *argv[])
topbar = 0; topbar = 0;
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
fast = 1; fast = 1;
else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
centered = 1;
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp; fstrncmp = strncasecmp;
fstrstr = cistrstr; fstrstr = cistrstr;
@ -856,8 +815,6 @@ main(int argc, char *argv[])
colors[SchemeSel][ColFg] = argv[++i]; colors[SchemeSel][ColFg] = argv[++i];
else if (!strcmp(argv[i], "-w")) /* embedding window id */ else if (!strcmp(argv[i], "-w")) /* embedding window id */
embed = argv[++i]; embed = argv[++i];
else if (!strcmp(argv[i], "-bw"))
border_width = atoi(argv[++i]); /* border width */
else else
usage(); usage();
@ -872,8 +829,7 @@ main(int argc, char *argv[])
if (!XGetWindowAttributes(dpy, parentwin, &wa)) if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx", die("could not get embedding window attributes: 0x%lx",
parentwin); parentwin);
xinitvisual(); drw = drw_create(dpy, screen, root, wa.width, wa.height);
drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded."); die("no fonts could be loaded.");
lrpad = drw->fonts->h; lrpad = drw->fonts->h;
@ -895,41 +851,3 @@ main(int argc, char *argv[])
return 1; /* unreachable */ return 1; /* unreachable */
} }
void
xinitvisual()
{
XVisualInfo *infos;
XRenderPictFormat *fmt;
int nitems;
int i;
XVisualInfo tpl = {
.screen = screen,
.depth = 32,
.class = TrueColor
};
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
visual = NULL;
for(i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
visual = infos[i].visual;
depth = infos[i].depth;
cmap = XCreateColormap(dpy, root, visual, AllocNone);
useargb = 1;
break;
}
}
XFree(infos);
if (! visual) {
visual = DefaultVisual(dpy, screen);
depth = DefaultDepth(dpy, screen);
cmap = DefaultColormap(dpy, screen);
}
}

View File

@ -1,13 +0,0 @@
#!/bin/bash
FILE="$HOME/.config/suckless_desktop/win_r.txt"
if [ ! -f "$FILE" ]; then
echo "File not found: $FILE" >&2
exit 1
fi
sed 's/|/'$'\t''/' "$FILE" | dmenu | {
IFS=$'\t' read -r col1 col2
[ -z "$col2" ] && exit 0
eval "$col2" 2>/dev/null || :
}

26
drw.c
View File

@ -47,7 +47,7 @@ utf8decode(const char *s_in, long *u, int *err)
} }
Drw * Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{ {
Drw *drw = ecalloc(1, sizeof(Drw)); Drw *drw = ecalloc(1, sizeof(Drw));
@ -56,11 +56,8 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h
drw->root = root; drw->root = root;
drw->w = w; drw->w = w;
drw->h = h; drw->h = h;
drw->visual = visual; drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->depth = depth; drw->gc = XCreateGC(dpy, root, 0, NULL);
drw->cmap = cmap;
drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw; return drw;
@ -76,7 +73,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h)
drw->h = h; drw->h = h;
if (drw->drawable) if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable); XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
} }
void void
@ -170,22 +167,21 @@ drw_fontset_free(Fnt *font)
} }
void void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{ {
if (!drw || !dest || !clrname) if (!drw || !dest || !clrname)
return; return;
if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest)) clrname, dest))
die("error, cannot allocate color '%s'", clrname); die("error, cannot allocate color '%s'", clrname);
dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
} }
/* Wrapper to create color schemes. The caller has to call free(3) on the /* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */ * returned color scheme when done using it. */
Clr * Clr *
drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount) drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{ {
size_t i; size_t i;
Clr *ret; Clr *ret;
@ -195,7 +191,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], si
return NULL; return NULL;
for (i = 0; i < clrcount; i++) for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); drw_clr_create(drw, &ret[i], clrnames[i]);
return ret; return ret;
} }
@ -254,7 +250,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
if (w < lpad) if (w < lpad)
return x + w; return x + w;
d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad; x += lpad;
w -= lpad; w -= lpad;
} }

9
drw.h
View File

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