Some patches from suckless.org

Diff list:
- dmenu-border-4.9.diff
- dmenu-caseinsensitive-20200523-db6093f.diff
- dmenu-center-20200111-8cd37e1.diff
- dmenu-highlight-4.9.diff
This commit is contained in:
Bazsalanszky 2020-08-17 17:34:02 +02:00
parent 9b38fda6fe
commit 906438d9e1
Signed by: Bazsalanszky
GPG key ID: 1B0B72C7139E2884
5 changed files with 125 additions and 12 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
*~
*.o
*.diff
dmenu
dmenu_path
dmenu_run
stest

View file

@ -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"
@ -11,6 +13,8 @@ static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" },
[SchemeSelHighlight] = { "#ffc978", "#005577" },
[SchemeNormHighlight] = { "#ffc978", "#222222" },
[SchemeOut] = { "#000000", "#00ffff" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
@ -21,3 +25,6 @@ static unsigned int lines = 0;
* for example: " /?\"&[]"
*/
static const char worddelimiters[] = " ";
/* Size of the window border */
static const unsigned int border_width = 5;

30
config.h Normal file
View file

@ -0,0 +1,30 @@
/* 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" },
[SchemeSelHighlight] = { "#ffc978", "#005577" },
[SchemeNormHighlight] = { "#ffc978", "#222222" },
[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
* for example: " /?\"&[]"
*/
static const char worddelimiters[] = " ";
/* Size of the window border */
static const unsigned int border_width = 5;

View file

@ -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.

90
dmenu.c
View file

@ -26,7 +26,7 @@
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */
struct item {
char *text;
@ -55,8 +55,9 @@ 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 char * cistrstr(const char *s, const char *sub);
static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
static char *(*fstrstr)(const char *, const char *) = cistrstr;
static void
appenditem(struct item *item, struct item **list, struct item **last)
@ -89,6 +90,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)
{
@ -113,6 +123,43 @@ cistrstr(const char *s, const char *sub)
return NULL;
}
static void
drawhighlights(struct item *item, int x, int y, int maxw)
{
char restorechar, tokens[sizeof text], *highlight, *token;
int indentx, highlightlen;
drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]);
strcpy(tokens, text);
for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
highlight = fstrstr(item->text, token);
while (highlight) {
// Move item str end, calc width for highlight indent, & restore
highlightlen = highlight - item->text;
restorechar = *highlight;
item->text[highlightlen] = '\0';
indentx = TEXTW(item->text);
item->text[highlightlen] = restorechar;
// Move highlight str end, draw highlight, & restore
restorechar = highlight[strlen(token)];
highlight[strlen(token)] = '\0';
if (indentx - (lrpad / 2) - 1 < maxw)
drw_text(
drw,
x + indentx - (lrpad / 2) - 1,
y,
MIN(maxw - indentx, TEXTW(highlight) - lrpad),
bh, 0, highlight, 0
);
highlight[strlen(token)] = restorechar;
if (strlen(highlight) - strlen(token) < strlen(token)) break;
highlight = fstrstr(highlight + strlen(token), token);
}
}
}
static int
drawitem(struct item *item, int x, int y, int w)
{
@ -123,7 +170,9 @@ drawitem(struct item *item, int x, int y, int w)
else
drw_setscheme(drw, scheme[SchemeNorm]);
return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
drawhighlights(item, x, y, w);
return r;
}
static void
@ -611,6 +660,7 @@ setup(void)
bh = drw->fonts->h + 2;
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 +687,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 +704,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();
@ -659,9 +722,10 @@ setup(void)
swa.override_redirect = True;
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
CopyFromParent, CopyFromParent, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
XSetClassHint(dpy, win, &ch);
@ -709,6 +773,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;