Compare commits
6 Commits
lineheight
...
mydmenu
| Author | SHA1 | Date | |
|---|---|---|---|
| 16ef6d4581 | |||
| 8d3994989f | |||
| cf4bba27cd | |||
| 0769f9bc04 | |||
| d2589d8554 | |||
| 4e190b874c |
@ -2,6 +2,8 @@
|
||||
/* Default settings; can be overriden by command line. */
|
||||
|
||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||
static int centered = 0; /* -c option; centers dmenu on screen */
|
||||
static int min_width = 500; /* minimum width when centered */
|
||||
/* -fn option overrides fonts[0]; default X11 font or font set */
|
||||
static const char *fonts[] = {
|
||||
"monospace:size=10"
|
||||
@ -15,6 +17,7 @@ static const char *colors[SchemeLast][2] = {
|
||||
};
|
||||
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
||||
static unsigned int lines = 0;
|
||||
static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */
|
||||
|
||||
/*
|
||||
* Characters not considered part of a word while deleting words
|
||||
|
||||
29
config.h
Normal file
29
config.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
/* Default settings; can be overriden by command line. */
|
||||
|
||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||
static int centered = 0; /* -c option; centers dmenu on screen */
|
||||
static int min_width = 500; /* minimum width when centered */
|
||||
/* -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 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;
|
||||
static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */
|
||||
|
||||
/*
|
||||
* Characters not considered part of a word while deleting words
|
||||
* for example: " /?\"&[]"
|
||||
*/
|
||||
static const char worddelimiters[] = " ";
|
||||
|
||||
/* Size of the window border */
|
||||
static const unsigned int border_width = 5;
|
||||
6
dmenu.1
6
dmenu.1
@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
|
||||
.B \-b
|
||||
dmenu appears at the bottom of the screen.
|
||||
.TP
|
||||
.B \-c
|
||||
dmenu appears centered on 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.
|
||||
@ -50,6 +53,9 @@ dmenu matches menu items case insensitively.
|
||||
.BI \-l " lines"
|
||||
dmenu lists items vertically, with the given number of lines.
|
||||
.TP
|
||||
.BI \-h " height"
|
||||
dmenu uses a menu line of at least 'height' pixels tall, but no less than 8.
|
||||
.TP
|
||||
.BI \-m " monitor"
|
||||
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
|
||||
from 0.
|
||||
|
||||
124
dmenu.c
124
dmenu.c
@ -15,6 +15,7 @@
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
@ -24,6 +25,8 @@
|
||||
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
#define NUMBERSMAXDIGITS 100
|
||||
#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1
|
||||
|
||||
/* enums */
|
||||
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
|
||||
@ -34,6 +37,7 @@ struct item {
|
||||
int out;
|
||||
};
|
||||
|
||||
static char numbers[NUMBERSBUFSIZE] = "";
|
||||
static char text[BUFSIZ] = "";
|
||||
static char *embed;
|
||||
static int bh, mw, mh;
|
||||
@ -89,6 +93,15 @@ calcoffsets(void)
|
||||
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
|
||||
cleanup(void)
|
||||
{
|
||||
@ -126,12 +139,27 @@ drawitem(struct item *item, int x, int y, int w)
|
||||
return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
recalculatenumbers()
|
||||
{
|
||||
unsigned int numer = 0, denom = 0;
|
||||
struct item *item;
|
||||
if (matchend) {
|
||||
numer++;
|
||||
for (item = matchend; item && item->left; item = item->left)
|
||||
numer++;
|
||||
}
|
||||
for (item = items; item && item->text; item++)
|
||||
denom++;
|
||||
snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom);
|
||||
}
|
||||
|
||||
static void
|
||||
drawmenu(void)
|
||||
{
|
||||
unsigned int curpos;
|
||||
struct item *item;
|
||||
int x = 0, y = 0, w;
|
||||
int x = 0, y = 0, fh = drw->fonts->h, w;
|
||||
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
||||
@ -148,9 +176,10 @@ drawmenu(void)
|
||||
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);
|
||||
drw_rect(drw, x + curpos, 2 + (bh-fh)/2, 2, fh - 4, 1, 0);
|
||||
}
|
||||
|
||||
recalculatenumbers();
|
||||
if (lines > 0) {
|
||||
/* draw vertical list */
|
||||
for (item = curr; item != next; item = item->right)
|
||||
@ -165,13 +194,15 @@ drawmenu(void)
|
||||
}
|
||||
x += w;
|
||||
for (item = curr; item != next; item = item->right)
|
||||
x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">")));
|
||||
x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">") - TEXTW(numbers)));
|
||||
if (next) {
|
||||
w = TEXTW(">");
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
|
||||
drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, ">", 0);
|
||||
}
|
||||
}
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_text(drw, mw - TEXTW(numbers), 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0);
|
||||
drw_map(drw, win, 0, 0, mw, mh);
|
||||
}
|
||||
|
||||
@ -601,16 +632,23 @@ setup(void)
|
||||
int a, di, n, area = 0;
|
||||
#endif
|
||||
/* init appearance */
|
||||
for (j = 0; j < SchemeLast; j++)
|
||||
scheme[j] = drw_scm_create(drw, colors[j], 2);
|
||||
for (j = 0; j < SchemeLast; j++) {
|
||||
scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2);
|
||||
}
|
||||
for (j = 0; j < SchemeOut; ++j) {
|
||||
for (i = 0; i < 2; ++i)
|
||||
free(colors[j][i]);
|
||||
}
|
||||
|
||||
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
||||
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||
|
||||
/* calculate menu geometry */
|
||||
bh = drw->fonts->h + 2;
|
||||
bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */
|
||||
lines = MAX(lines, 0);
|
||||
mh = (lines + 1) * bh;
|
||||
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
|
||||
#ifdef XINERAMA
|
||||
i = 0;
|
||||
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
|
||||
@ -637,9 +675,16 @@ setup(void)
|
||||
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;
|
||||
if (centered) {
|
||||
mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
|
||||
x = info[i].x_org + ((info[i].width - mw) / 2);
|
||||
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);
|
||||
} else
|
||||
#endif
|
||||
@ -647,11 +692,17 @@ setup(void)
|
||||
if (!XGetWindowAttributes(dpy, parentwin, &wa))
|
||||
die("could not get embedding window attributes: 0x%lx",
|
||||
parentwin);
|
||||
x = 0;
|
||||
y = topbar ? 0 : wa.height - mh;
|
||||
mw = wa.width;
|
||||
|
||||
if (centered) {
|
||||
mw = MIN(MAX(max_textw() + promptw, min_width), 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;
|
||||
inputw = MIN(inputw, mw/3);
|
||||
match();
|
||||
|
||||
@ -690,10 +741,46 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
|
||||
" [-h height]\n"
|
||||
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
readxresources(void) {
|
||||
XrmInitialize();
|
||||
|
||||
char* xrm;
|
||||
if ((xrm = XResourceManagerString(drw->dpy))) {
|
||||
char *type;
|
||||
XrmDatabase xdb = XrmGetStringDatabase(xrm);
|
||||
XrmValue xval;
|
||||
|
||||
if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval))
|
||||
fonts[0] = strdup(xval.addr);
|
||||
else
|
||||
fonts[0] = strdup(fonts[0]);
|
||||
if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval))
|
||||
colors[SchemeNorm][ColBg] = strdup(xval.addr);
|
||||
else
|
||||
colors[SchemeNorm][ColBg] = strdup(colors[SchemeNorm][ColBg]);
|
||||
if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval))
|
||||
colors[SchemeNorm][ColFg] = strdup(xval.addr);
|
||||
else
|
||||
colors[SchemeNorm][ColFg] = strdup(colors[SchemeNorm][ColFg]);
|
||||
if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval))
|
||||
colors[SchemeSel][ColBg] = strdup(xval.addr);
|
||||
else
|
||||
colors[SchemeSel][ColBg] = strdup(colors[SchemeSel][ColBg]);
|
||||
if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval))
|
||||
colors[SchemeSel][ColFg] = strdup(xval.addr);
|
||||
else
|
||||
colors[SchemeSel][ColFg] = strdup(colors[SchemeSel][ColFg]);
|
||||
|
||||
XrmDestroyDatabase(xdb);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@ -709,6 +796,8 @@ main(int argc, char *argv[])
|
||||
topbar = 0;
|
||||
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
|
||||
fast = 1;
|
||||
else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
|
||||
centered = 1;
|
||||
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
|
||||
fstrncmp = strncasecmp;
|
||||
fstrstr = cistrstr;
|
||||
@ -723,6 +812,10 @@ 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], "-h")) { /* minimum height of one menu line */
|
||||
lineheight = atoi(argv[++i]);
|
||||
lineheight = MAX(lineheight,8); /* reasonable default in case of value too small/negative */
|
||||
}
|
||||
else if (!strcmp(argv[i], "-nb")) /* normal background color */
|
||||
colors[SchemeNorm][ColBg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
|
||||
@ -748,8 +841,11 @@ main(int argc, char *argv[])
|
||||
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)))
|
||||
readxresources();
|
||||
if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
|
||||
free(fonts[0]);
|
||||
lrpad = drw->fonts->h;
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user