sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 22285bc9747c55ca8e8da2b219ae1300bf76220f
parent 4627ea15e615ed576187acc292a1f4bc48313b1b
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri, 17 Jun 2016 15:41:38 +0200

update dmenu patches

- remove patches that were merged upstream such as xft, monitor patch.
- remove pre-4.6 patches, update a few to 4.6 or git.
- remove legacy directory.
- remove some crappy patches, feel free to update against the latest 4.6 stable
  and add it again.

Diffstat:
Dtools.suckless.org/dmenu/patches/dmenu-4.1.1-xmms.diff | 130-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.2.1-tok.diff | 101-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4-follow-focus.diff | 21---------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4-tok.diff | 103-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4.1-multisel.diff | 60------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.4.1-xft.diff | 405-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-fuzzymatch.diff | 135-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-hide-single-newline.diff | 12------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-monarg.diff | 101-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-mouse-support.diff | 142-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-xft-debian.diff | 418-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-xft-improved.diff | 425-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-4.5-xft.diff | 418-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/dmenu-4.6-fuzzymatch.diff | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support.diff | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtools.suckless.org/dmenu/patches/dmenu-default-height.png | 0
Dtools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff | 135-------------------------------------------------------------------------------
Mtools.suckless.org/dmenu/patches/dmenu-git-incremental.diff | 78+++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-git-xft.diff | 450-------------------------------------------------------------------------------
Mtools.suckless.org/dmenu/patches/dmenu-instant.diff | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Dtools.suckless.org/dmenu/patches/dmenu-ms_nl.diff | 79-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-tip-history.diff | 149-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-tip-incremental.diff | 62--------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff | 110-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/dmenu_xmms.diff | 133-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/follow-focus.md | 12------------
Mtools.suckless.org/dmenu/patches/fuzzymatch.md | 5++---
Dtools.suckless.org/dmenu/patches/history.md | 32--------------------------------
Mtools.suckless.org/dmenu/patches/incremental.md | 1-
Dtools.suckless.org/dmenu/patches/legacy/allow-kp_decimal-in-dmenu.patch | 12------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu-4.0-paste.diff | 27---------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu-4.0-vertical_meillo.diff | 221-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu_path-cls.c | 100-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu_path.c | 376-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/legacy/dmenu_path.md | 11-----------
Dtools.suckless.org/dmenu/patches/legacy/index.md | 4----
Dtools.suckless.org/dmenu/patches/legacy/kp_decimal.md | 14--------------
Dtools.suckless.org/dmenu/patches/legacy/paste.md | 23-----------------------
Dtools.suckless.org/dmenu/patches/legacy/vertical.md | 14--------------
Dtools.suckless.org/dmenu/patches/monarg.md | 17-----------------
Mtools.suckless.org/dmenu/patches/mouse-support.md | 4++--
Dtools.suckless.org/dmenu/patches/multisel.md | 12------------
Dtools.suckless.org/dmenu/patches/multiselect_and_newline.md | 19-------------------
Mtools.suckless.org/dmenu/patches/non_blocking_stdin.md | 1-
Dtools.suckless.org/dmenu/patches/xft.md | 29-----------------------------
Dtools.suckless.org/dmenu/patches/xmms-like_pattern_matching.md | 34----------------------------------
Dtools.suckless.org/dmenu/patches/xrdb.diff | 85-------------------------------------------------------------------------------
Dtools.suckless.org/dmenu/patches/xrdb.md | 16----------------
48 files changed, 391 insertions(+), 4705 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.1.1-xmms.diff b/tools.suckless.org/dmenu/patches/dmenu-4.1.1-xmms.diff @@ -1,130 +0,0 @@ ---- dmenu-4.1.1/config.def.h 2010-08-04 14:21:27.468630995 +0100 -+++ dmenu-4.1.1/config.def.h 2010-08-04 15:33:31.475940022 +0100 -@@ -7,3 +7,4 @@ - static const char *selbgcolor = "#0066ff"; - static const char *selfgcolor = "#ffffff"; - static unsigned int spaceitem = 30; /* px between menu items */ -+static unsigned int maxtokens = 16; /* max. tokens for pattern matching */ ---- dmenu-4.1.1/dmenu.1 2010-08-04 14:21:27.468630995 +0100 -+++ dmenu-4.1.1/dmenu.1 2010-08-04 15:18:35.557920858 +0100 -@@ -12,6 +12,7 @@ - .RB [ \-p " <prompt>"] - .RB [ \-sb " <color>"] - .RB [ \-sf " <color>"] -+.RB [ \-xs ] - .RB [ \-v ] - .SH DESCRIPTION - .SS Overview -@@ -49,6 +50,9 @@ - .B \-sf <color> - defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). - .TP -+.B \-xs -+xmms-like pattern matching. -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE ---- dmenu-4.1.1/dmenu.c 2010-08-04 14:21:27.468630995 +0100 -+++ dmenu-4.1.1/dmenu.c 2010-08-04 15:18:35.557920858 +0100 -@@ -75,6 +75,7 @@ - /* variables */ - static char *maxname = NULL; - static char *prompt = NULL; -+static char **tokens = NULL; - static char text[4096]; - static int cmdw = 0; - static int promptw = 0; -@@ -84,6 +85,7 @@ - static unsigned int mw, mh; - static unsigned int numlockmask = 0; - static Bool running = True; -+static Bool xmms = False; - static Display *dpy; - static DC dc; - static Item *allitems = NULL; /* first of all items */ -@@ -578,22 +580,55 @@ - drawmenu(); - } - -+unsigned int tokenize(char *pat, char **tok) -+{ -+ unsigned int i = 0; -+ char tmp[4096] = {0}; -+ -+ strncpy(tmp, pat, strlen(pat)); -+ tok[0] = strtok(tmp, " "); -+ -+ while(tok[i] && i < maxtokens) -+ tok[++i] = strtok(NULL, " "); -+ return i; -+} -+ - void - match(char *pattern) { -- unsigned int plen; -+ unsigned int plen, tokencnt = 0; -+ char append = 0; - Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - - if(!pattern) - return; -- plen = strlen(pattern); -+ -+ if(!xmms) -+ tokens[(tokencnt = 1)-1] = pattern; -+ else -+ if(!(tokencnt = tokenize(pattern, tokens))) -+ tokens[(tokencnt = 1)-1] = ""; - item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; -- for(i = allitems; i; i = i->next) -- if(!fstrncmp(pattern, i->text, plen + 1)) -+ for(i = allitems; i; i = i->next) { -+ for(int j = 0; j < tokencnt; ++j) { -+ plen = strlen(tokens[j]); -+ if(!fstrncmp(tokens[j], i->text, plen + 1)) -+ append = !append || append > 1 ? 1 : append; -+ else if(!fstrncmp(tokens[j], i->text, plen )) -+ append = !append || append > 2 ? 2 : append; -+ else if(fstrstr(i->text, tokens[j])) -+ append = append > 0 && append < 3 ? append : 3; -+ else { -+ append = 0; -+ break; -+ } -+ } -+ if(append == 1) - appenditem(i, &lexact, &exactend); -- else if(!fstrncmp(pattern, i->text, plen)) -+ else if(append == 2) - appenditem(i, &lprefix, &prefixend); -- else if(fstrstr(i->text, pattern)) -+ else if(append == 3) - appenditem(i, &lsubstr, &substrend); -+ } - if(lexact) { - item = lexact; - itemend = exactend; -@@ -748,6 +783,7 @@ - if(prompt) - promptw = MIN(textw(prompt), mw / 5); - text[0] = '\0'; -+ tokens = malloc((xmms?maxtokens:1)*sizeof(char*)); - match(text); - XMapRaised(dpy, win); - } -@@ -806,11 +842,13 @@ - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } -+ else if(!strcmp(argv[i], "-xs")) -+ xmms = True; - 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"); -+ " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-xs] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.2.1-tok.diff b/tools.suckless.org/dmenu/patches/dmenu-4.2.1-tok.diff @@ -1,101 +0,0 @@ ---- a/dmenu.1 2010-12-28 17:26:44.368974910 +0000 -+++ b/dmenu.1 2010-12-28 17:28:41.902912662 +0000 -@@ -5,6 +5,7 @@ dmenu \- dynamic menu - .B dmenu - .RB [ \-b ] - .RB [ \-i ] -+.RB [ \-t ] - .RB [ \-l - .IR lines ] - .RB [ \-m -@@ -50,6 +51,9 @@ dmenu appears at the bottom of the scree - .B \-i - dmenu matches menu items case insensitively. - .TP -+.B \-t -+dmenu uses space separated tokens to match menu items. -+.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP ---- a/dmenu.c 2010-12-28 17:26:44.368974910 +0000 -+++ b/dmenu.c 2010-12-28 17:53:30.548303785 +0000 -@@ -30,7 +30,8 @@ static char *fstrstr(const char *s, cons - static void grabkeyboard(void); - static void insert(const char *s, ssize_t n); - static void keypress(XKeyEvent *ev); --static void match(void); -+static void matchstr(void); -+static void matchtok(void); - static size_t nextrune(int incr); - static void paste(void); - static void readstdin(void); -@@ -62,6 +63,7 @@ static Item *prev, *curr, *next; - static Window root, win; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -+static void (*match)(void) = matchstr; - - int - main(int argc, char *argv[]) { -@@ -78,6 +80,8 @@ main(int argc, char *argv[]) { - topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; -+ else if(!strcmp(argv[i], "-t")) -+ match = matchtok; - else if(i == argc-1) - usage(); - /* double flags */ -@@ -368,7 +372,7 @@ keypress(XKeyEvent *ev) { - } - - void --match(void) { -+matchstr(void) { - size_t len; - Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - -@@ -407,6 +411,33 @@ match(void) { - calcoffsets(); - } - -+void -+matchtok(void) { -+ char buf[sizeof text]; -+ char **tokv, *s; -+ int tokc, i; -+ Item *item, *end; -+ -+ tokc = 0; -+ tokv = NULL; -+ strcpy(buf, text); -+ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) -+ if(!(tokv = realloc(tokv, ++tokc * sizeof *tokv))) -+ eprintf("cannot realloc %u bytes\n", tokc * sizeof *tokv); -+ -+ matches = end = NULL; -+ for(item = items; item; item = item->next) { -+ for(i = 0; i < tokc; i++) -+ if(!fstrstr(item->text, tokv[i])) -+ break; -+ if(i == tokc) -+ appenditem(item, &matches, &end); -+ } -+ free(tokv); -+ curr = prev = next = sel = matches; -+ calcoffsets(); -+} -+ - size_t - nextrune(int incr) { - size_t n, len; -@@ -536,7 +567,7 @@ setup(void) { - - void - usage(void) { -- fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-i] [-t] [-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/tools.suckless.org/dmenu/patches/dmenu-4.4-follow-focus.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4-follow-focus.diff @@ -1,21 +0,0 @@ -diff -r f6b31468f983 dmenu.c ---- a/dmenu.c Sun Jul 24 20:04:58 2011 +0100 -+++ b/dmenu.c Tue Aug 02 23:22:00 2011 +0200 -@@ -492,11 +492,14 @@ - mh = (lines + 1) * bh; - #ifdef XINERAMA - if((info = XineramaQueryScreens(dc->dpy, &n))) { -- int i, di; -- unsigned int du; -+ int i, revert; - Window dw; -+ XWindowAttributes wa; -+ Window chi; - -- XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); -+ XGetInputFocus(dc->dpy, &dw, &revert); -+ XGetWindowAttributes(dc->dpy, dw, &wa); -+ XTranslateCoordinates(dc->dpy, wa.root, wa.root, wa.x, wa.y, &x, &y, &chi); - 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; diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4-tok.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4-tok.diff @@ -1,103 +0,0 @@ -diff -r f6b31468f983 dmenu.1 ---- a/dmenu.1 Sun Jul 24 20:04:58 2011 +0100 -+++ b/dmenu.1 Mon Sep 12 10:43:11 2011 +0100 -@@ -6,6 +6,7 @@ - .RB [ \-b ] - .RB [ \-f ] - .RB [ \-i ] -+.RB [ \-t ] - .RB [ \-l - .IR lines ] - .RB [ \-p -@@ -48,6 +49,9 @@ - .B \-i - dmenu matches menu items case insensitively. - .TP -+.B \-t -+dmenu uses space\-separated tokens to match menu items. -+.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -diff -r f6b31468f983 dmenu.c ---- a/dmenu.c Sun Jul 24 20:04:58 2011 +0100 -+++ b/dmenu.c Mon Sep 12 10:43:11 2011 +0100 -@@ -30,7 +30,8 @@ - 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 matchstr(Bool sub); -+static void matchtok(Bool sub); - static size_t nextrune(int inc); - static void paste(void); - static void readstdin(void); -@@ -61,6 +62,7 @@ - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; -+static void (*match)(Bool) = matchstr; - - int - main(int argc, char *argv[]) { -@@ -81,6 +83,8 @@ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } -+ else if(!strcmp(argv[i], "-t")) -+ match = matchtok; - else if(i+1 == argc) - usage(); - /* double flags */ -@@ -362,7 +366,7 @@ - } - - void --match(Bool sub) { -+matchstr(Bool sub) { - size_t len = strlen(text); - Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - Item *item, *lnext; -@@ -402,6 +406,33 @@ - calcoffsets(); - } - -+void -+matchtok(Bool sub) { -+ char buf[sizeof text]; -+ char **tokv, *s; -+ int tokc, i; -+ Item *item, *end; -+ -+ tokc = 0; -+ tokv = NULL; -+ strcpy(buf, text); -+ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) -+ if(!(tokv = realloc(tokv, ++tokc * sizeof *tokv))) -+ eprintf("cannot realloc %u bytes\n", tokc * sizeof *tokv); -+ -+ matches = end = NULL; -+ for(item = items; item->text; item++) { -+ for(i = 0; i < tokc; i++) -+ if(!fstrstr(item->text, tokv[i])) -+ break; -+ if(i == tokc) -+ appenditem(item, &matches, &end); -+ } -+ free(tokv); -+ curr = prev = next = sel = matches; -+ calcoffsets(); -+} -+ - size_t - nextrune(int inc) { - ssize_t n; -@@ -532,7 +563,7 @@ - - void - usage(void) { -- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-f] [-i] [-t] [-l lines] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4.1-multisel.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4.1-multisel.diff @@ -1,60 +0,0 @@ -diff -r bebcf140b8a9 dmenu.1 ---- a/dmenu.1 Wed Oct 26 14:16:12 2011 +0100 -+++ b/dmenu.1 Thu Oct 27 12:56:43 2011 -0700 -@@ -85,2 +85,5 @@ - .TP -+.B Ctrl-Return -+Confirm selection. Prints the selected item to stdout and continues. -+.TP - .B Shift\-Return (Ctrl\-Shift\-j) -diff -r bebcf140b8a9 dmenu.c ---- a/dmenu.c Wed Oct 26 14:16:12 2011 +0100 -+++ b/dmenu.c Thu Oct 27 12:56:43 2011 -0700 -@@ -24,2 +24,3 @@ - Item *left, *right; -+ Bool out; - }; -@@ -51,2 +52,4 @@ - static const char *selfgcolor = "#ffffff"; -+static const char *outbgcolor = "#00ffff"; -+static const char *outfgcolor = "#000000"; - static unsigned int lines = 0; -@@ -54,2 +57,3 @@ - static unsigned long selcol[ColLast]; -+static unsigned long outcol[ColLast]; - static Atom clip, utf8; -@@ -187,3 +191,4 @@ - dc->y += dc->h; -- drawtext(dc, item->text, (item == sel) ? selcol : normcol); -+ drawtext(dc, item->text, (item == sel) ? selcol : -+ (item->out) ? outcol : normcol); - } -@@ -199,3 +204,4 @@ - 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); - } -@@ -280,2 +286,5 @@ - return; -+ case XK_Return: -+ case XK_KP_Enter: -+ break; - default: -@@ -352,3 +361,6 @@ - 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: -@@ -468,2 +480,3 @@ - eprintf("cannot strdup %u bytes:", strlen(buf)+1); -+ items[i].out = False; - if(strlen(items[i].text) > max) -@@ -519,2 +532,4 @@ - selcol[ColFG] = getcolor(dc, selfgcolor); -+ outcol[ColBG] = getcolor(dc, outbgcolor); -+ outcol[ColFG] = getcolor(dc, outfgcolor); - diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.4.1-xft.diff b/tools.suckless.org/dmenu/patches/dmenu-4.4.1-xft.diff @@ -1,405 +0,0 @@ ---- a/dmenu.c 2011-09-19 11:48:13.000000000 +0200 -+++ b/dmenu.c 2011-12-31 00:48:16.000000000 +0200 -@@ -16,6 +16,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 DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -25,6 +26,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -49,10 +51,12 @@ static const char *normbgcolor = "#ccccc - static const char *normfgcolor = "#000000"; - static const char *selbgcolor = "#0066ff"; - static const char *selfgcolor = "#ffffff"; --static unsigned long normcol[ColLast]; --static unsigned long selcol[ColLast]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -102,7 +106,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -115,7 +121,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return EXIT_FAILURE; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -158,6 +165,16 @@ cistrstr(const char *s, const char *sub) - } - - void -+cleanup(void) { -+ Item *itm; -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -165,7 +182,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -175,7 +192,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, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - dc->w = mw - dc->x; -@@ -301,7 +318,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -337,7 +355,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -449,7 +468,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) -+ while(running && !XNextEvent(dc->dpy, &ev)) - switch(ev.type) { - case Expose: - if(ev.xexpose.count == 0) -@@ -479,11 +498,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- 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 */ ---- a/draw.c 2011-09-19 11:48:13.000000000 +0200 -+++ b/draw.c 2011-12-31 01:44:39.000000000 +0200 -@@ -9,9 +9,6 @@ - - #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) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig - 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)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - 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) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - 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))) { -+ missing = NULL; -+ 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; -+ } else 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; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - 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))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } ---- a/draw.h 2011-09-19 11:48:13.000000000 +0200 -+++ b/draw.h 2011-12-31 00:28:01.000000000 +0200 -@@ -1,9 +1,6 @@ - /* 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 }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - 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 drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); ---- a/dmenu.1 2011-09-19 11:48:13.000000000 +0200 -+++ b/dmenu.1 2011-12-30 23:23:44.000000000 +0200 -@@ -55,7 +55,7 @@ - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. ---- a/config.mk 2011-12-30 23:23:44.000000000 +0200 -+++ b/config.mk 2011-12-30 23:23:44.000000000 +0200 -@@ -12,9 +12,13 @@ - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/local/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS+= -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-fuzzymatch.diff @@ -1,135 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..19c5cb6 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -22,6 +22,7 @@ typedef struct Item Item; - struct Item { - char *text; - Item *left, *right; -+ int distance; - }; - - static void appenditem(Item *item, Item **list, Item **last); -@@ -221,6 +222,86 @@ grabkeyboard(void) { - eprintf("cannot grab keyboard\n"); - } - -+int -+compare_distance(const void *a, const void *b) { -+ Item const *da = *(Item **) a; -+ Item const *db = *(Item **) b; -+ if(!db) -+ return 1; -+ if(!da) -+ return -1; -+ return da->distance - db->distance; -+} -+ -+void -+fuzzymatch(void) { -+ /* bang - we have so much memory */ -+ Item *item; -+ Item **fuzzymatches = NULL; -+ char c; -+ int number_of_matches = 0, i, pidx, sidx, eidx; -+ int text_len = strlen(text), itext_len; -+ -+ matches = matchend = NULL; -+ -+ /* suppress compiler warning for unused match function */ -+ if(0) -+ match(); -+ -+ /* walk through all items */ -+ for(item = items; item && item->text; item++) { -+ if(text_len) { -+ itext_len = strlen(item->text); -+ pidx = 0; -+ sidx = eidx = -1; -+ /* walk through item text */ -+ for(i = 0; i < itext_len && (c = item->text[i]); i++) { -+ /* fuzzy match pattern */ -+ if(text[pidx] == c) { -+ if(sidx == -1) -+ sidx = i; -+ pidx++; -+ if(pidx == text_len) { -+ eidx = i; -+ break; -+ } -+ } -+ } -+ /* build list of matches */ -+ if(eidx != -1) { -+ /* compute distance */ -+ /* factor in 30% of sidx and distance between eidx and total -+ * text length .. let's see how it works */ -+ item->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; -+ appenditem(item, &matches, &matchend); -+ number_of_matches++; -+ } -+ } -+ else -+ appenditem(item, &matches, &matchend); -+ } -+ -+ if(number_of_matches) { -+ /* initialize array with matches */ -+ if(!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(Item*)))) -+ eprintf("cannot realloc %u bytes:", number_of_matches * sizeof(Item*)); -+ for(i = 0, item = matches; item && i < number_of_matches; i++, item = item->right) { -+ fuzzymatches[i] = item; -+ } -+ /* sort matches according to distance */ -+ qsort(fuzzymatches, number_of_matches, sizeof(Item*), compare_distance); -+ /* rebuild list of matches */ -+ matches = matchend = NULL; -+ for(i = 0, item = fuzzymatches[i]; i < number_of_matches && item && \ -+ item->text; i++, item = fuzzymatches[i]) { -+ appenditem(item, &matches, &matchend); -+ } -+ free(fuzzymatches); -+ } -+ curr = sel = matches; -+ calcoffsets(); -+} -+ - void - insert(const char *str, ssize_t n) { - if(strlen(text) + n > sizeof text - 1) -@@ -230,7 +311,7 @@ insert(const char *str, ssize_t n) { - if(n > 0) - memcpy(&text[cursor], str, n); - cursor += n; -- match(); -+ fuzzymatch(); - } - - void -@@ -260,7 +341,7 @@ keypress(XKeyEvent *ev) { - - case XK_k: /* delete right */ - text[cursor] = '\0'; -- match(); -+ fuzzymatch(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); -@@ -379,7 +460,7 @@ keypress(XKeyEvent *ev) { - return; - strncpy(text, sel->text, sizeof text); - cursor = strlen(text); -- match(); -+ fuzzymatch(); - break; - } - drawmenu(); -@@ -578,7 +659,7 @@ setup(void) { - } - promptw = prompt ? textw(dc, prompt) : 0; - inputw = MIN(inputw, mw/3); -- match(); -+ fuzzymatch(); - - /* create menu window */ - swa.override_redirect = True; diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-hide-single-newline.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-hide-single-newline.diff @@ -1,12 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..4b76da5 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -482,6 +482,7 @@ readstdin(void) { - } - if(items) - items[i].text = NULL; -+ if (i == 1 && items[0].text[0] == '\0') items = realloc(items, 0); - inputw = maxstr ? textw(dc, maxstr) : 0; - lines = MIN(lines, i); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-monarg.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-monarg.diff @@ -1,101 +0,0 @@ -diff --git a/dmenu.1 b/dmenu.1 -index 0784cd9..a0b488b 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -12,6 +12,8 @@ dmenu \- dynamic menu - .IR prompt ] - .RB [ \-fn - .IR font ] -+.RB [ \-m -+.IR monitor ] - .RB [ \-nb - .IR color ] - .RB [ \-nf -@@ -55,6 +57,9 @@ defines the prompt to be displayed to the left of the input field. - .BI \-fn " font" - defines the font or font set used. - .TP -+.BI \-m " monitor" -+defines what monitor to run dmenu on. -+.TP - .BI \-nb " color" - defines the normal background color. - .IR #RGB , -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..fb2f096 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -60,6 +60,7 @@ static Item *matches, *matchend; - static Item *prev, *curr, *next, *sel; - static Window win; - static XIC xic; -+static int mon = -1; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; -@@ -90,6 +91,8 @@ main(int argc, char *argv[]) { - lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; -+ else if(!strcmp(argv[i], "-m")) /* monitor index */ -+ mon = atoi(argv[++i]); - else if(!strcmp(argv[i], "-fn")) /* font or font set */ - font = argv[++i]; - else if(!strcmp(argv[i], "-nb")) /* normal background color */ -@@ -544,25 +547,29 @@ setup(void) { - XWindowAttributes wa; - - 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) { -- area = a; -- i = j; -- } -+ if(mon > -1 && mon < n) -+ i = mon; -+ else { -+ 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) { -+ area = a; -+ 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; - } -- /* 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); -@@ -601,7 +608,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); - } diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-mouse-support.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-mouse-support.diff @@ -1,142 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 3962801..a75bf80 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -25,6 +25,7 @@ struct Item { - }; - - static void appenditem(Item *item, Item **list, Item **last); -+static void buttonpress(XEvent *e); - static void calcoffsets(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); -@@ -389,6 +390,109 @@ keypress(XKeyEvent *ev) { - } - - void -+buttonpress(XEvent *e) { -+ int curpos; -+ Item *item; -+ XButtonPressedEvent *ev = &e->xbutton; -+ -+ if(ev->window != win) -+ return; -+ -+ /* right-click: exit */ -+ if(ev->button == Button3) -+ exit(EXIT_FAILURE); -+ -+ dc->x = 0; -+ dc->y = 0; -+ dc->h = bh; -+ -+ if(prompt && *prompt) { -+ dc->w = promptw; -+ dc->x = dc->w; -+ } -+ /* input field */ -+ dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; -+ if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w); -+ -+ /* left-click on input: clear input, -+ * NOTE: if there is no left-arrow the space for < is reserved so -+ * add that to the input width */ -+ if(ev->button == Button1 && -+ ((lines <= 0 && ev->x >= 0 && ev->x <= dc->x + dc->w + -+ ((!prev || !curr->left) ? textw(dc, "<") : 0)) || -+ (lines > 0 && ev->y >= dc->y && ev->y <= dc->y + dc->h))) { -+ insert(NULL, 0 - cursor); -+ drawmenu(); -+ return; -+ } -+ /* middle-mouse click: paste selection */ -+ if(ev->button == Button2) { -+ XConvertSelection(dc->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, -+ utf8, utf8, win, CurrentTime); -+ drawmenu(); -+ return; -+ } -+ /* scroll up */ -+ if(ev->button == Button4 && prev) { -+ sel = curr = prev; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ /* scroll down */ -+ if(ev->button == Button5 && next) { -+ sel = curr = next; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ if(ev->button != Button1) -+ return; -+ if(lines > 0) { -+ /* vertical list: left-click on item */ -+ dc->w = mw - dc->x; -+ for(item = curr; item != next; item = item->right) { -+ dc->y += dc->h; -+ if(ev->y >= dc->y && ev->y <= (dc->y + dc->h)) { -+ puts(item->text); -+ exit(EXIT_SUCCESS); -+ } -+ } -+ } -+ else if(matches) { -+ /* left-click on left arrow */ -+ dc->x += inputw; -+ dc->w = textw(dc, "<"); -+ if(prev && curr->left) { -+ if(ev->x >= dc->x && ev->x <= dc->x + dc->w) { -+ sel = curr = prev; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ } -+ /* horizontal list: left-click on item */ -+ for(item = curr; item != next; item = item->right) { -+ dc->x += dc->w; -+ dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); -+ if(ev->x >= dc->x && ev->x <= (dc->x + dc->w)) { -+ puts(item->text); -+ exit(EXIT_SUCCESS); -+ } -+ } -+ /* left-click on right arrow */ -+ dc->w = textw(dc, ">"); -+ dc->x = mw - dc->w; -+ if(next && ev->x >= dc->x && ev->x <= dc->x + dc->w) { -+ sel = curr = next; -+ calcoffsets(); -+ drawmenu(); -+ return; -+ } -+ } -+} -+ -+void - match(void) { - static char **tokv = NULL; - static int tokn = 0; -@@ -497,6 +601,9 @@ run(void) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -+ case ButtonPress: -+ buttonpress(&ev); -+ break; - case Expose: - if(ev.xexpose.count == 0) - mapdc(dc, win, mw, mh); -@@ -586,7 +693,8 @@ setup(void) { - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = normcol[ColBG]; -- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; -+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | -+ ButtonPressMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, - DefaultVisual(dc->dpy, screen), diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-debian.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-debian.diff @@ -1,418 +0,0 @@ -diff -upr a/config.mk b/config.mk ---- a/config.mk 2012-01-10 19:03:22.000000000 +0200 -+++ b/config.mk 2012-01-10 19:03:38.000000000 +0200 -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff -upr a/dmenu.1 b/dmenu.1 ---- a/dmenu.1 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.1 2012-01-10 19:14:23.000000000 +0200 -@@ -53,7 +53,7 @@ dmenu lists items vertically, with the g - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff -upr a/dmenu.c b/dmenu.c ---- a/dmenu.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.c 2012-01-10 19:24:39.000000000 +0200 -@@ -17,6 +17,7 @@ - * 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 DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -26,6 +27,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbb - 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]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom clip, utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -167,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -178,7 +194,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, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -321,7 +337,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -490,7 +508,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -524,11 +542,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -582,7 +595,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff -upr a/draw.c b/draw.c ---- a/draw.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.c 2012-01-10 19:14:23.000000000 +0200 -@@ -9,9 +9,6 @@ - - #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) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig - 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)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - 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) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - 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))) { -+ missing = NULL; -+ 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; -+ } else 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; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - 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))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff -upr a/draw.h b/draw.h ---- a/draw.h 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.h 2012-01-10 19:14:23.000000000 +0200 -@@ -1,9 +1,6 @@ - /* 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 }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - 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 drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-improved.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-xft-improved.diff @@ -1,425 +0,0 @@ -diff --git a/config.mk b/config.mk -index 92a5e63..9cff5db 100644 ---- a/config.mk -+++ b/config.mk -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/dmenu.1 b/dmenu.1 -index 0784cd9..f29ca36 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -53,7 +53,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 or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff --git a/dmenu.c b/dmenu.c -index 4ea95f8..b4549ef 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -17,6 +17,7 @@ - * 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 DEFFONT "monospace-9" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -26,6 +27,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -50,10 +52,12 @@ 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]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom clip, utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) { - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -167,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -177,8 +193,9 @@ drawmenu(void) { - /* draw input field */ - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); -+ dc->x += 2; - if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -321,7 +338,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -359,7 +377,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -490,7 +509,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -524,11 +543,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -582,7 +596,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff --git a/draw.c b/draw.c -index 76f0c54..81b991c 100644 ---- a/draw.c -+++ b/draw.c -@@ -9,9 +9,6 @@ - - #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) { -@@ -23,7 +20,7 @@ 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]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - 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)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - 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) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - 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))) { -+ missing = NULL; -+ 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; -+ } else 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; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - 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))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.xOff; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff --git a/draw.h b/draw.h -index 43a57bf..1b4f21a 100644 ---- a/draw.h -+++ b/draw.h -@@ -1,9 +1,6 @@ - /* 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 }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - 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 drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.5-xft.diff b/tools.suckless.org/dmenu/patches/dmenu-4.5-xft.diff @@ -1,418 +0,0 @@ -diff -upr a/config.mk b/config.mk ---- a/config.mk 2012-01-10 19:03:22.000000000 +0200 -+++ b/config.mk 2012-01-10 19:03:38.000000000 +0200 -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/local/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff -upr a/dmenu.1 b/dmenu.1 ---- a/dmenu.1 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.1 2012-01-10 19:14:23.000000000 +0200 -@@ -53,7 +53,7 @@ dmenu lists items vertically, with the g - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff -upr a/dmenu.c b/dmenu.c ---- a/dmenu.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/dmenu.c 2012-01-10 19:24:39.000000000 +0200 -@@ -17,6 +17,7 @@ - * 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 DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -26,6 +27,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -50,10 +52,12 @@ static const char *normfgcolor = "#bbbbb - 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]; -+static ColorSet *normcol; -+static ColorSet *selcol; - static Atom clip, utf8; - static Bool topbar = True; -+static Bool running = True; -+static int ret = 0; - static DC *dc; - static Item *items = NULL; - static Item *matches, *matchend; -@@ -104,7 +108,9 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); - - if(fast) { - grabkeyboard(); -@@ -117,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -160,6 +167,15 @@ cistrstr(const char *s, const char *sub) - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -167,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt) { - dc->w = promptw; -@@ -178,7 +194,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, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -321,7 +337,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -359,7 +376,8 @@ keypress(XKeyEvent *ev) { - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -- exit(EXIT_SUCCESS); -+ ret = EXIT_SUCCESS; -+ running = False; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); -@@ -490,7 +508,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -524,11 +542,6 @@ setup(void) { - XineramaScreenInfo *info; - #endif - -- normcol[ColBG] = getcolor(dc, normbgcolor); -- normcol[ColFG] = getcolor(dc, normfgcolor); -- selcol[ColBG] = getcolor(dc, selbgcolor); -- selcol[ColFG] = getcolor(dc, selfgcolor); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -582,7 +595,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff -upr a/draw.c b/draw.c ---- a/draw.c 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.c 2012-01-10 19:14:23.000000000 +0200 -@@ -9,9 +9,6 @@ - - #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) { -@@ -23,7 +20,7 @@ drawrect(DC *dc, int x, int y, unsigned - } - - void --drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsig - 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)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - 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) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if (!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - if(dc->font.set) - XFreeFontSet(dc->dpy, dc->font.set); -- if(dc->font.xfont) -+ if(dc->font.xfont) - XFreeFont(dc->dpy, dc->font.xfont); -- if(dc->canvas) -+ if(dc->canvas) - XFreePixmap(dc->dpy, dc->canvas); -- XFreeGC(dc->dpy, dc->gc); -- XCloseDisplay(dc->dpy); -- free(dc); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - 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))) { -+ missing = NULL; -+ 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; -+ } else 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; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - 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))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff -upr a/draw.h b/draw.h ---- a/draw.h 2012-01-10 19:14:19.000000000 +0200 -+++ b/draw.h 2012-01-10 19:14:23.000000000 +0200 -@@ -1,9 +1,6 @@ - /* 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 }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - 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 drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-fuzzymatch.diff @@ -0,0 +1,145 @@ +From f5caf807c884f92e6f07ad8b461334343287eca3 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 15:09:30 +0200 +Subject: [PATCH] fuzzy match, fix off-by-one in previous patch. + +--- + dmenu.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 83 insertions(+), 4 deletions(-) + +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..b4a6f70 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -32,6 +32,7 @@ struct item { + char *text; + struct item *left, *right; + int out; ++ int distance; + }; + + static char text[BUFSIZ] = ""; +@@ -253,6 +254,84 @@ match(void) + calcoffsets(); + } + ++static int ++compare_distance(const void *a, const void *b) ++{ ++ struct item const *da = *(struct item **) a; ++ struct item const *db = *(struct item **) b; ++ ++ if (!db) ++ return 1; ++ if (!da) ++ return -1; ++ return da->distance - db->distance; ++} ++ ++static void ++fuzzymatch(void) ++{ ++ struct item *item; ++ struct item **fuzzymatches = NULL; ++ char c; ++ int number_of_matches = 0, i, pidx, sidx, eidx; ++ int text_len = strlen(text), itext_len; ++ ++ matches = matchend = NULL; ++ ++ /* walk through all items */ ++ for (item = items; item && item->text; item++) { ++ if (text_len) { ++ itext_len = strlen(item->text); ++ pidx = 0; ++ sidx = eidx = -1; ++ /* walk through item text */ ++ for (i = 0; i < itext_len && (c = item->text[i]); i++) { ++ /* fuzzy match pattern */ ++ if (text[pidx] == c) { ++ if (sidx == -1) ++ sidx = i; ++ pidx++; ++ if (pidx == text_len) { ++ eidx = i; ++ break; ++ } ++ } ++ } ++ /* build list of matches */ ++ if (eidx != -1) { ++ /* compute distance */ ++ /* factor in 30% of sidx and distance between eidx and total ++ * text length .. let's see how it works */ ++ item->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; ++ appenditem(item, &matches, &matchend); ++ number_of_matches++; ++ } ++ } ++ else ++ appenditem(item, &matches, &matchend); ++ } ++ ++ if (number_of_matches) { ++ /* initialize array with matches */ ++ if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*)))) ++ die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item *)); ++ for (i = 0, item = matches; item && i < number_of_matches; i++, item = item->right) ++ fuzzymatches[i] = item; ++ ++ /* sort matches according to distance */ ++ qsort(fuzzymatches, number_of_matches, sizeof(struct item *), compare_distance); ++ /* rebuild list of matches */ ++ matches = matchend = NULL; ++ for (i = 0, item = fuzzymatches[0]; i < number_of_matches && item && \ ++ item->text; item = fuzzymatches[i], i++) ++ appenditem(item, &matches, &matchend); ++ ++ free(fuzzymatches); ++ } ++ curr = sel = matches; ++ calcoffsets(); ++} ++ + static void + insert(const char *str, ssize_t n) + { +@@ -263,7 +342,7 @@ insert(const char *str, ssize_t n) + if (n > 0) + memcpy(&text[cursor], str, n); + cursor += n; +- match(); ++ fuzzymatch(); + } + + static size_t +@@ -308,7 +387,7 @@ keypress(XKeyEvent *ev) + + case XK_k: /* delete right */ + text[cursor] = '\0'; +- match(); ++ fuzzymatch(); + break; + case XK_u: /* delete left */ + insert(NULL, 0 - cursor); +@@ -444,7 +523,7 @@ keypress(XKeyEvent *ev) + strncpy(text, sel->text, sizeof text - 1); + text[sizeof text - 1] = '\0'; + cursor = strlen(text); +- match(); ++ fuzzymatch(); + break; + } + drawmenu(); +@@ -586,7 +665,7 @@ setup(void) + } + promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; + inputw = MIN(inputw, mw/3); +- match(); ++ fuzzymatch(); + + /* create menu window */ + swa.override_redirect = True; +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support.diff b/tools.suckless.org/dmenu/patches/dmenu-4.6-mouse-support.diff @@ -0,0 +1,143 @@ +From cb154e0e93819cba9fee70f108dc95a168ab664e Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 14:44:16 +0200 +Subject: [PATCH] dmenu mouse support + +--- + dmenu.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 105 insertions(+), 1 deletion(-) + +diff --git a/dmenu.c b/dmenu.c +index e0c2f80..7907ae9 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -451,6 +451,106 @@ keypress(XKeyEvent *ev) + } + + static void ++buttonpress(XEvent *e) ++{ ++ int curpos; ++ struct item *item; ++ XButtonPressedEvent *ev = &e->xbutton; ++ int x = 0, y = 0, h = bh, w; ++ ++ if (ev->window != win) ++ return; ++ ++ /* right-click: exit */ ++ if (ev->button == Button3) ++ exit(1); ++ ++ if (prompt && *prompt) ++ x += promptw; ++ ++ /* input field */ ++ w = (lines > 0 || !matches) ? mw - x : inputw; ++ if ((curpos = TEXTNW(text, cursor) + bh / 2 - 2) < w) ++ ; ++ ++ /* left-click on input: clear input, ++ * NOTE: if there is no left-arrow the space for < is reserved so ++ * add that to the input width */ ++ if (ev->button == Button1 && ++ ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + ++ ((!prev || !curr->left) ? TEXTW("<") : 0)) || ++ (lines > 0 && ev->y >= y && ev->y <= y + h))) { ++ insert(NULL, -cursor); ++ drawmenu(); ++ return; ++ } ++ /* middle-mouse click: paste selection */ ++ if (ev->button == Button2) { ++ XConvertSelection(drw->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, ++ utf8, utf8, win, CurrentTime); ++ drawmenu(); ++ return; ++ } ++ /* scroll up */ ++ if (ev->button == Button4 && prev) { ++ sel = curr = prev; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ /* scroll down */ ++ if (ev->button == Button5 && next) { ++ sel = curr = next; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ if (ev->button != Button1) ++ return; ++ if (lines > 0) { ++ /* vertical list: left-click on item */ ++ w = mw - x; ++ for (item = curr; item != next; item = item->right) { ++ y += h; ++ if (ev->y >= y && ev->y <= y + h) { ++ puts(item->text); ++ exit(0); ++ } ++ } ++ } else if (matches) { ++ /* left-click on left arrow */ ++ x += inputw; ++ w = TEXTW("<"); ++ if (prev && curr->left) { ++ if (ev->x >= x && ev->x <= x + w) { ++ sel = curr = prev; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ } ++ /* horizontal list: left-click on item */ ++ for (item = curr; item != next; item = item->right) { ++ x += w; ++ w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); ++ if (ev->x >= x && ev->x <= x + w) { ++ puts(item->text); ++ exit(0); ++ } ++ } ++ /* left-click on right arrow */ ++ w = TEXTW(">"); ++ x = mw - w; ++ if (next && ev->x >= x && ev->x <= x + w) { ++ sel = curr = next; ++ calcoffsets(); ++ drawmenu(); ++ return; ++ } ++ } ++} ++ ++static void + paste(void) + { + char *p, *q; +@@ -500,6 +600,9 @@ run(void) + if (XFilterEvent(&ev, win)) + continue; + switch(ev.type) { ++ case ButtonPress: ++ buttonpress(&ev); ++ break; + case Expose: + if (ev.xexpose.count == 0) + drw_map(drw, win, 0, 0, mw, mh); +@@ -591,7 +694,8 @@ setup(void) + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm].bg->pix; +- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; ++ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | ++ ButtonPressMask; + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, + DefaultDepth(dpy, screen), CopyFromParent, + DefaultVisual(dpy, screen), +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-default-height.png b/tools.suckless.org/dmenu/patches/dmenu-default-height.png Binary files differ. diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff b/tools.suckless.org/dmenu/patches/dmenu-git-20151020-fuzzymatch.diff @@ -1,135 +0,0 @@ -diff --git a/dmenu.c b/dmenu.c -index 4f22ffe..c2fc3ee 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -33,6 +33,7 @@ struct item { - char *text; - struct item *left, *right; - bool out; -+ int distance; - }; - - static char text[BUFSIZ] = ""; -@@ -254,6 +255,86 @@ match(void) - calcoffsets(); - } - -+int -+compare_distance(const void *a, const void *b) -+{ -+ struct item *da = *(struct item **) a; -+ struct item *db = *(struct item **) b; -+ -+ if (!db) -+ return 1; -+ if (!da) -+ return -1; -+ -+ return da->distance - db->distance; -+} -+ -+void -+fuzzymatch(void) -+{ -+ /* bang - we have so much memory */ -+ struct item *it; -+ struct item **fuzzymatches = NULL; -+ char c; -+ int number_of_matches = 0, i, pidx, sidx, eidx; -+ int text_len = strlen(text), itext_len; -+ -+ matches = matchend = NULL; -+ -+ /* walk through all items */ -+ for (it = items; it && it->text; it++) { -+ if (text_len) { -+ itext_len = strlen(it->text); -+ pidx = 0; -+ sidx = eidx = -1; -+ /* walk through item text */ -+ for (i = 0; i < itext_len && (c = it->text[i]); i++) { -+ /* fuzzy match pattern */ -+ if (text[pidx] == c) { -+ if(sidx == -1) -+ sidx = i; -+ pidx++; -+ if (pidx == text_len) { -+ eidx = i; -+ break; -+ } -+ } -+ } -+ /* build list of matches */ -+ if (eidx != -1) { -+ /* compute distance */ -+ /* factor in 30% of sidx and distance between eidx and total -+ * text length .. let's see how it works */ -+ it->distance = eidx - sidx + (itext_len - eidx + sidx) / 3; -+ appenditem(it, &matches, &matchend); -+ number_of_matches++; -+ } -+ } else { -+ appenditem(it, &matches, &matchend); -+ } -+ } -+ -+ if (number_of_matches) { -+ /* initialize array with matches */ -+ if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*)))) -+ die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*)); -+ for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) { -+ fuzzymatches[i] = it; -+ } -+ /* sort matches according to distance */ -+ qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance); -+ /* rebuild list of matches */ -+ matches = matchend = NULL; -+ for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && \ -+ it->text; i++, it = fuzzymatches[i]) { -+ appenditem(it, &matches, &matchend); -+ } -+ free(fuzzymatches); -+ } -+ curr = sel = matches; -+ calcoffsets(); -+} -+ - static void - insert(const char *str, ssize_t n) - { -@@ -264,7 +345,7 @@ insert(const char *str, ssize_t n) - if (n > 0) - memcpy(&text[cursor], str, n); - cursor += n; -- match(); -+ fuzzymatch(); - } - - static size_t -@@ -309,7 +390,7 @@ keypress(XKeyEvent *ev) - - case XK_k: /* delete right */ - text[cursor] = '\0'; -- match(); -+ fuzzymatch(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); -@@ -443,7 +524,7 @@ keypress(XKeyEvent *ev) - strncpy(text, sel->text, sizeof text - 1); - text[sizeof text - 1] = '\0'; - cursor = strlen(text); -- match(); -+ fuzzymatch(); - break; - } - drawmenu(); -@@ -585,7 +666,7 @@ setup(void) - } - promptw = (prompt && *prompt) ? TEXTW(prompt) : 0; - inputw = MIN(inputw, mw/3); -- match(); -+ fuzzymatch(); - - /* create menu window */ - swa.override_redirect = True; diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-incremental.diff b/tools.suckless.org/dmenu/patches/dmenu-git-incremental.diff @@ -1,70 +1,82 @@ +From 38914e7a39b12ba1001b5464e6d96d1d15e73634 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 15:33:50 +0200 +Subject: [PATCH] incremental mode: dmenu outputs text each time a key is + pressed. + +--- + config.def.h | 1 + + dmenu.1 | 4 ++++ + dmenu.c | 8 +++++++- + 3 files changed, 12 insertions(+), 1 deletion(-) + diff --git a/config.def.h b/config.def.h -index dcffd38..b879e9f 100644 +index dcffd38..994f3a5 100644 --- a/config.def.h +++ b/config.def.h @@ -2,6 +2,7 @@ /* Default settings; can be overriden by command line. */ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -+static int incremental = 0; /* -r option; if 1, dmenu outputs during input */ ++static int incremental = 0; /* -r option; if 1, outputs text each time a key is pressed */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" diff --git a/dmenu.1 b/dmenu.1 -index d3ab805..044f955 100644 +index d3ab805..e5bf42f 100644 --- a/dmenu.1 +++ b/dmenu.1 -@@ -6,6 +6,7 @@ dmenu \- dynamic menu - .RB [ \-b ] - .RB [ \-f ] - .RB [ \-i ] +@@ -18,6 +18,7 @@ dmenu \- dynamic menu + .IR color ] + .RB [ \-nf + .IR color ] +.RB [ \-r ] - .RB [ \-l - .RB [ \-m - .IR monitor ] -@@ -48,6 +49,9 @@ X until stdin reaches end\-of\-file. - .B \-i - dmenu matches menu items case insensitively. + .RB [ \-sb + .IR color ] + .RB [ \-sf +@@ -58,6 +59,9 @@ from 0. + .BI \-p " prompt" + defines the prompt to be displayed to the left of the input field. .TP +.B \-r +dmenu outputs text each time a key is pressed. +.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. + .BI \-fn " font" + defines the font or font set used. .TP diff --git a/dmenu.c b/dmenu.c -index e0c2f80..100ab10 100644 +index e0c2f80..7f1be56 100644 --- a/dmenu.c +++ b/dmenu.c -@@ -447,6 +447,11 @@ keypress(XKeyEvent *ev) +@@ -447,6 +447,10 @@ keypress(XKeyEvent *ev) match(); break; } -+ if(incremental) { -+ fprintf(stdout, "%s\n", text); ++ if (incremental) { ++ puts(text); + fflush(stdout); + } -+ drawmenu(); } -@@ -610,7 +615,7 @@ setup(void) - static void +@@ -611,7 +615,7 @@ static void usage(void) { -- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" -+ fputs("usage: dmenu [-b] [-f] [-i] [-r] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + 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); ++ " [-nb color] [-nf color] [-r] [-sb color] [-sf color] [-v]\n", stderr); exit(1); } -@@ -632,7 +637,9 @@ main(int argc, char *argv[]) + +@@ -629,6 +633,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], "-r")) /* incremental */ ++ incremental = 1; else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; -- } else if (i + 1 == argc) -+ } else if (!strcmp(argv[i], "-r")) /* outputs during input */ -+ incremental = 1; -+ else if (i + 1 == argc) - usage(); - /* these options take one argument */ - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-git-xft.diff b/tools.suckless.org/dmenu/patches/dmenu-git-xft.diff @@ -1,450 +0,0 @@ -diff --git a/config.mk b/config.mk -index c0d466b..04e2dce 100644 ---- a/config.mk -+++ b/config.mk -@@ -12,9 +12,13 @@ X11LIB = /usr/X11R6/lib - XINERAMALIBS = -lXinerama - XINERAMAFLAGS = -DXINERAMA - -+# Xft, comment if you don't want it -+XFTINC = -I/usr/include/freetype2 -+XFTLIBS = -lXft -lXrender -lfreetype -lz -lfontconfig -+ - # includes and libs --INCS = -I${X11INC} --LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -+INCS = -I${X11INC} ${XFTINC} -+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} - - # flags - CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -diff --git a/dmenu.1 b/dmenu.1 -index 2897ab1..d06b484 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -58,7 +58,7 @@ dmenu is displayed on the monitor supplied. - defines the prompt to be displayed to the left of the input field. - .TP - .BI \-fn " font" --defines the font or font set used. -+defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (a xft font) - .TP - .BI \-nb " color" - defines the normal background color. -diff --git a/dmenu.c b/dmenu.c -index 94c70de..cc6dedf 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -17,6 +17,7 @@ - * 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 DEFFONT "fixed" /* xft example: "Monospace-11" */ - - typedef struct Item Item; - struct Item { -@@ -27,6 +28,7 @@ struct Item { - - static void appenditem(Item *item, Item **list, Item **last); - static void calcoffsets(void); -+static void cleanup(void); - static char *cistrstr(const char *s, const char *sub); - static void drawmenu(void); - static void grabkeyboard(void); -@@ -44,9 +46,9 @@ 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 ColorSet *normcol; -+static ColorSet *selcol; -+static ColorSet *outcol; - static Atom clip, utf8; - static DC *dc; - static Item *items = NULL; -@@ -55,6 +57,8 @@ static Item *prev, *curr, *next, *sel; - static Window win; - static XIC xic; - static int mon = -1; -+static Bool running = True; -+static int ret = EXIT_SUCCESS; - - #include "config.h" - -@@ -103,7 +107,10 @@ main(int argc, char *argv[]) { - usage(); - - dc = initdc(); -- initfont(dc, font); -+ initfont(dc, font ? font : DEFFONT); -+ normcol = initcolor(dc, normfgcolor, normbgcolor); -+ selcol = initcolor(dc, selfgcolor, selbgcolor); -+ outcol = initcolor(dc, outfgcolor, outbgcolor); - - if(fast) { - grabkeyboard(); -@@ -116,7 +123,8 @@ main(int argc, char *argv[]) { - setup(); - run(); - -- return 1; /* unreachable */ -+ cleanup(); -+ return ret; - } - - void -@@ -159,6 +167,15 @@ cistrstr(const char *s, const char *sub) { - } - - void -+cleanup(void) { -+ freecol(dc, normcol); -+ freecol(dc, selcol); -+ XDestroyWindow(dc->dpy, win); -+ XUngrabKeyboard(dc->dpy, CurrentTime); -+ freedc(dc); -+} -+ -+void - drawmenu(void) { - int curpos; - Item *item; -@@ -166,7 +183,7 @@ drawmenu(void) { - dc->x = 0; - dc->y = 0; - dc->h = bh; -- drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); -+ drawrect(dc, 0, 0, mw, mh, True, normcol->BG); - - if(prompt && *prompt) { - dc->w = promptw; -@@ -177,7 +194,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, True, FG(dc, normcol)); -+ drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -281,9 +298,12 @@ keypress(XKeyEvent *ev) { - return; - case XK_Return: - case XK_KP_Enter: -+ ret = EXIT_SUCCESS; -+ running = False; - break; - case XK_bracketleft: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - default: - return; - } -@@ -330,7 +350,8 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- exit(EXIT_FAILURE); -+ ret = EXIT_FAILURE; -+ running = False; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -368,8 +389,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)) { -+ ret = EXIT_SUCCESS; -+ running = False; -+ } - if(sel) - sel->out = True; - break; -@@ -505,7 +528,7 @@ void - run(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) { -+ while(running && !XNextEvent(dc->dpy, &ev)) { - if(XFilterEvent(&ev, win)) - continue; - switch(ev.type) { -@@ -539,13 +562,6 @@ setup(void) { - XineramaScreenInfo *info; - #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); -- - clip = XInternAtom(dc->dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - -@@ -601,7 +617,7 @@ setup(void) { - - /* create menu window */ - swa.override_redirect = True; -- swa.background_pixel = normcol[ColBG]; -+ swa.background_pixel = normcol->BG; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc->dpy, screen), CopyFromParent, -diff --git a/draw.c b/draw.c -index 76f0c54..09e66ea 100644 ---- a/draw.c -+++ b/draw.c -@@ -9,9 +9,6 @@ - - #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) { -@@ -23,7 +20,7 @@ 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]) { -+drawtext(DC *dc, const char *text, ColorSet *col) { - char buf[BUFSIZ]; - size_t mn, n = strlen(text); - -@@ -35,19 +32,24 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { - 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)); -+ drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); - drawtextn(dc, buf, mn, col); - } - - void --drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { -+drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { - 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) -+ XSetForeground(dc->dpy, dc->gc, col->FG); -+ if(dc->font.xft_font) { -+ if(!dc->xftdraw) -+ eprintf("error, xft drawable does not exist"); -+ XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, -+ dc->font.xft_font, x, y, (unsigned char*)text, n); -+ } else if(dc->font.set) { - XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); -- else { -+ } else { - XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); - XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); - } -@@ -69,16 +71,33 @@ eprintf(const char *fmt, ...) { - } - - void -+freecol(DC *dc, ColorSet *col) { -+ if(col) { -+ if(&col->FG_xft) -+ XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); -+ free(col); -+ } -+} -+ -+void - freedc(DC *dc) { -+ if(dc->font.xft_font) { -+ XftFontClose(dc->dpy, dc->font.xft_font); -+ XftDrawDestroy(dc->xftdraw); -+ } - 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); -+ if(dc->gc) -+ XFreeGC(dc->dpy, dc->gc); -+ if(dc->dpy) -+ XCloseDisplay(dc->dpy); -+ if(dc) -+ free(dc); - } - - unsigned long -@@ -91,6 +110,20 @@ getcolor(DC *dc, const char *colstr) { - return color.pixel; - } - -+ColorSet * -+initcolor(DC *dc, const char * foreground, const char * background) { -+ ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); -+ if(!col) -+ eprintf("error, cannot allocate memory for color set"); -+ col->BG = getcolor(dc, background); -+ col->FG = getcolor(dc, foreground); -+ if(dc->font.xft_font) -+ if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), -+ DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) -+ eprintf("error, cannot allocate xft font color '%s'\n", foreground); -+ return col; -+} -+ - DC * - initdc(void) { - DC *dc; -@@ -109,39 +142,33 @@ initdc(void) { - - 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))) { -+ missing = NULL; -+ 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; -+ } else 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.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); -+ 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; -+ } else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { -+ dc->font.ascent = dc->font.xft_font->ascent; -+ dc->font.descent = dc->font.xft_font->descent; -+ dc->font.width = dc->font.xft_font->max_advance_width; -+ } else { -+ eprintf("cannot load font '%s'\n", fontstr); - } - if(missing) - XFreeStringList(missing); -- return dc->font.set || dc->font.xfont; -+ dc->font.height = dc->font.ascent + dc->font.descent; -+ return; - } - - void -@@ -151,20 +178,29 @@ mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { - - void - resizedc(DC *dc, unsigned int w, unsigned int h) { -+ int screen = DefaultScreen(dc->dpy); - 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))); -+ DefaultDepth(dc->dpy, screen)); -+ if(dc->font.xft_font && !(dc->xftdraw)) { -+ dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); -+ if(!(dc->xftdraw)) -+ eprintf("error, cannot create xft drawable\n"); -+ } - } - - int - textnw(DC *dc, const char *text, size_t len) { -- if(dc->font.set) { -+ if(dc->font.xft_font) { -+ XGlyphInfo gi; -+ XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); -+ return gi.width; -+ } else if(dc->font.set) { - XRectangle r; -- - XmbTextExtents(dc->font.set, text, len, NULL, &r); - return r.width; - } -diff --git a/draw.h b/draw.h -index 43a57bf..1b4f21a 100644 ---- a/draw.h -+++ b/draw.h -@@ -1,9 +1,6 @@ - /* 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 }; -+#include <X11/Xft/Xft.h> - - typedef struct { - int x, y, w, h; -@@ -11,6 +8,7 @@ typedef struct { - Display *dpy; - GC gc; - Pixmap canvas; -+ XftDraw *xftdraw; - struct { - int ascent; - int descent; -@@ -18,15 +16,24 @@ typedef struct { - int width; - XFontSet set; - XFontStruct *xfont; -+ XftFont *xft_font; - } font; - } DC; /* draw context */ - -+typedef struct { -+ unsigned long FG; -+ XftColor FG_xft; -+ unsigned long BG; -+} ColorSet; -+ - 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 drawtext(DC *dc, const char *text, ColorSet *col); -+void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col); -+void freecol(DC *dc, ColorSet *col); - void eprintf(const char *fmt, ...); - void freedc(DC *dc); - unsigned long getcolor(DC *dc, const char *colstr); -+ColorSet *initcolor(DC *dc, const char *foreground, const char *background); - DC *initdc(void); - void initfont(DC *dc, const char *fontstr); - void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); diff --git a/tools.suckless.org/dmenu/patches/dmenu-instant.diff b/tools.suckless.org/dmenu/patches/dmenu-instant.diff @@ -1,34 +1,58 @@ +From e95c945f9a6afe486782962dfe2dd81c00c05781 Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 17 Jun 2016 13:24:21 +0200 +Subject: [PATCH] dmenu instant match: end dmenu immediately if there is one + match left. + +--- + config.def.h | 1 + + dmenu.1 | 4 ++++ + dmenu.c | 7 +++++++ + 3 files changed, 12 insertions(+) + diff --git a/config.def.h b/config.def.h -index 4e5e3e7..22ef78b 100644 +index dcffd38..b06f1d5 100644 --- a/config.def.h +++ b/config.def.h -@@ -4,6 +4,8 @@ - /* Default settings; can be overrided by command line. */ +@@ -2,6 +2,7 @@ + /* Default settings; can be overriden by command line. */ - static Bool topbar = True; /* -b option; if False, dmenu appears at bottom */ -+static Bool instant = False; /* -n option; if True, dmenu ends immediately */ -+ /* on a distinct match */ + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static int instant = 0; /* -n option; if 1, dmenu ends immediately on a distinct match */ /* -fn option overrides fonts[0]; default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" +diff --git a/dmenu.1 b/dmenu.1 +index d3ab805..f0aa123 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -10,6 +10,7 @@ dmenu \- dynamic menu + .RB [ \-m + .IR monitor ] + .IR lines ] ++.RB [ \-n ] + .RB [ \-p + .IR prompt ] + .RB [ \-fn +@@ -55,6 +56,9 @@ dmenu lists items vertically, with the given number of lines. + dmenu is displayed on the monitor number supplied. Monitor numbers are starting + from 0. + .TP ++.BI \-n ++instant match, end dmenu if there is only one match left. ++.TP + .BI \-p " prompt" + defines the prompt to be displayed to the left of the input field. + .TP diff --git a/dmenu.c b/dmenu.c -index f0bc176..a357692 100644 +index e0c2f80..0c41d46 100644 --- a/dmenu.c +++ b/dmenu.c -@@ -93,6 +93,8 @@ main(int argc, char *argv[]) { - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } -+ else if(!strcmp(argv[i], "-n")) /* instant match */ -+ instant = !instant; - else if(i+1 == argc) - usage(); - /* these options take one argument */ -@@ -511,6 +513,11 @@ match(void) { +@@ -250,6 +250,11 @@ match(void) matchend = substrend; } curr = sel = matches; -+ if(instant && matches && matches==matchend && !lsubstr) { ++ if (instant && matches && matches == matchend && !lsubstr) { + puts(matches->text); + cleanup(); + exit(0); @@ -36,3 +60,15 @@ index f0bc176..a357692 100644 calcoffsets(); } +@@ -632,6 +637,8 @@ main(int argc, char *argv[]) + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; ++ } else if (!strcmp(argv[i], "-n")) { /* instant match */ ++ instant = !instant; + } else if (i + 1 == argc) + usage(); + /* these options take one argument */ +-- +2.8.3 + diff --git a/tools.suckless.org/dmenu/patches/dmenu-ms_nl.diff b/tools.suckless.org/dmenu/patches/dmenu-ms_nl.diff @@ -1,79 +0,0 @@ -diff -up dmenu-4.0/dmenu.1 dmenu-4.0_ms_nl/dmenu.1 ---- dmenu-4.0/dmenu.1 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_ms_nl/dmenu.1 2009-11-19 23:01:15.000000000 +0100 -@@ -11,6 +11,8 @@ dmenu \- dynamic menu - .RB [ \-p " <prompt>"] - .RB [ \-sb " <color>"] - .RB [ \-sf " <color>"] -+.RB [ \-ms ] -+.RB [ \-nl ] - .RB [ \-v ] - .SH DESCRIPTION - .SS Overview -@@ -44,6 +46,12 @@ defines the selected background color (# - .B \-sf <color> - defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). - .TP -+.B \-ms -+multi-select; selecting an item and pressing return won't terminate dmenu. -+.TP -+.B \-nl -+seperates standard output by newlines. -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE -diff -up dmenu-4.0/dmenu.c dmenu-4.0_ms_nl/dmenu.c ---- dmenu-4.0/dmenu.c 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_ms_nl/dmenu.c 2009-11-19 23:04:59.000000000 +0100 -@@ -69,6 +69,7 @@ static int textw(const char *text); - /* variables */ - static char *maxname = NULL; - static char *prompt = NULL; -+static char *nl = ""; - static char text[4096]; - static int cmdw = 0; - static int promptw = 0; -@@ -77,6 +78,7 @@ static int screen; - static unsigned int mw, mh; - static unsigned int numlockmask = 0; - static Bool running = True; -+static Bool multiselect = False; - static Display *dpy; - static DC dc; - static Item *allitems = NULL; /* first of all items */ -@@ -448,13 +450,13 @@ kpress(XKeyEvent * e) { - break; - case XK_Return: - if((e->state & ShiftMask) && *text) -- fprintf(stdout, "%s", text); -+ fprintf(stdout, "%s%s", text, nl); - else if(sel) -- fprintf(stdout, "%s", sel->text); -+ fprintf(stdout, "%s%s", sel->text, nl); - else if(*text) -- fprintf(stdout, "%s", text); -+ fprintf(stdout, "%s%s", text, nl); - fflush(stdout); -- running = False; -+ running = multiselect; - break; - case XK_Right: - if(!(sel && sel->right)) -@@ -694,11 +696,15 @@ main(int argc, char *argv[]) { - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } -+ else if(!strcmp(argv[i], "-ms")) -+ multiselect = True; -+ else if(!strcmp(argv[i], "-nl")) -+ nl = "\n"; - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); - else - eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" -- " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); -+ " [-p <prompt>] [-sb <color>] [-sf <color>] [-ms] [-nl] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) diff --git a/tools.suckless.org/dmenu/patches/dmenu-tip-history.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-history.diff @@ -1,149 +0,0 @@ -diff -r 23bd778df432 dmenu.1 ---- a/dmenu.1 Fri Aug 20 19:57:13 2010 +0100 -+++ b/dmenu.1 Sat Aug 28 18:34:49 2010 +0100 -@@ -19,6 +19,8 @@ - .IR color ] - .RB [ \-sf - .IR color ] -+.RB [ \-hist -+.IR "<filename>" ] - .RB [ \-v ] - .P - .BR dmenu_run " ..." -@@ -72,6 +74,9 @@ - .BI \-sf " color" - defines the selected foreground color. - .TP -+.BI \-hist " <histfile>" -+the file to use for history -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE -diff -r 23bd778df432 dmenu.c ---- a/dmenu.c Fri Aug 20 19:57:13 2010 +0100 -+++ b/dmenu.c Sat Aug 28 18:34:49 2010 +0100 -@@ -16,6 +16,8 @@ - #define MIN(a,b) ((a) < (b) ? (a) : (b)) - #define MAX(a,b) ((a) > (b) ? (a) : (b)) - -+#define HIST_SIZE 20 -+ - typedef struct Item Item; - struct Item { - char *text; -@@ -33,7 +35,7 @@ - static void match(void); - static size_t nextrune(int incr); - static void paste(void); --static void readstdin(void); -+static void readitems(void); - static void run(void); - static void setup(void); - static void usage(void); -@@ -60,8 +62,37 @@ - static Item *prev, *curr, *next; - static Window root, win; - -+static char hist[HIST_SIZE][1024]; -+static char *histfile = NULL; -+static int hcnt = 0; -+ - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - -+static int -+writehistory(char *command) { -+ int i = 0; -+ FILE *f; -+ -+ if(!histfile || strlen(command) <= 0) -+ return 0; -+ -+ if((f = fopen(histfile, "w"))) { -+ fputs(command, f); -+ fputc('\n', f); -+ for(; i < hcnt; i++) { -+ if(strcmp(command, hist[i]) != 0) { -+ fputs(hist[i], f); -+ fputc('\n', f); -+ } -+ } -+ fclose(f); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ - void - appenditem(Item *item, Item **list, Item **last) { - if(!*last) -@@ -296,6 +327,7 @@ - case XK_KP_Enter: - fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); - fflush(stdout); -+ writehistory( (sel == NULL) ? text : sel->text); - exit(EXIT_SUCCESS); - case XK_Right: - if(cursor < len) { -@@ -385,9 +417,10 @@ - } - - void --readstdin(void) { -+readitems(void) { - char buf[sizeof text], *p; - Item *item, **end; -+ FILE *f; - - for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { - if((p = strchr(buf, '\n'))) -@@ -399,6 +432,22 @@ - item->next = item->left = item->right = NULL; - inputw = MAX(inputw, dc_textw(dc, item->text)); - } -+ -+ if(histfile && (f = fopen(histfile, "r"))) { -+ for(; fgets(buf, sizeof buf, f); *end = item, end = &item->next) { -+ if((p = strchr(buf, '\n'))) -+ *p = '\0'; -+ 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); -+ item->next = item->left = item->right = NULL; -+ inputw = MAX(inputw, dc_textw(dc, item->text)); -+ -+ strncpy(hist[hcnt++], buf, (strlen(buf) <= 1024) ? strlen(buf): 1024 ); -+ } -+ fclose(f); -+ } - } - - void -@@ -490,7 +539,7 @@ - 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); -+ " [-nf color] [-sb color] [-sf color] [-hist histfile] [-v]\n", stderr); - exit(EXIT_FAILURE); - } - -@@ -526,12 +575,14 @@ - selbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sf")) - selfgcolor = argv[++i]; -+ else if(!strcmp(argv[i], "-hist")) -+ histfile = argv[++i]; - else - usage(); - - dc = dc_init(); - dc_font(dc, font); -- readstdin(); -+ readitems(); - setup(); - run(); - diff --git a/tools.suckless.org/dmenu/patches/dmenu-tip-incremental.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-incremental.diff @@ -1,62 +0,0 @@ -diff -r a79e4a9cb167 dmenu.1 ---- a/dmenu.1 Sat Nov 20 09:25:08 2010 +0000 -+++ b/dmenu.1 Sat Nov 20 18:51:43 2010 +0000 -@@ -5,6 +5,7 @@ - .B dmenu - .RB [ \-b ] - .RB [ \-i ] -+.RB [ \-r ] - .RB [ \-l - .IR lines ] - .RB [ \-m -@@ -50,6 +51,9 @@ - .B \-i - dmenu matches menu items case insensitively. - .TP -+.B \-r -+dmenu outputs text each time a key is pressed. -+.TP - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -diff -r a79e4a9cb167 dmenu.c ---- a/dmenu.c Sat Nov 20 09:25:08 2010 +0000 -+++ b/dmenu.c Sat Nov 20 18:51:43 2010 +0000 -@@ -54,7 +54,7 @@ - static unsigned long normcol[ColLast]; - static unsigned long selcol[ColLast]; - static Atom utf8; --static Bool topbar = True; -+static Bool topbar = True, incremental = False; - static DC *dc; - static Item *items = NULL; - static Item *matches, *sel; -@@ -78,6 +78,8 @@ - topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; -+ else if(!strcmp(argv[i], "-r")) -+ incremental = 1; - else if(i == argc-1) - usage(); - /* double flags */ -@@ -364,6 +366,10 @@ - match(); - break; - } -+ if(incremental) { -+ fprintf(stdout, "%s\n", text); -+ fflush(stdout); -+ } - drawmenu(); - } - -@@ -536,7 +542,7 @@ - - void - usage(void) { -- fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" -+ fputs("usage: dmenu [-b] [-i] [-r] [-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/tools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff @@ -1,110 +0,0 @@ -diff -r 2b9683c50723 dmenu.c ---- a/dmenu.c Wed Dec 01 20:25:10 2010 +0000 -+++ b/dmenu.c Tue Dec 07 17:32:54 2010 +0100 -@@ -4,6 +4,8 @@ - #include <stdlib.h> - #include <string.h> - #include <unistd.h> -+#include <fcntl.h> -+#include <sys/select.h> - #include <X11/Xlib.h> - #include <X11/Xatom.h> - #include <X11/Xutil.h> -@@ -34,6 +36,7 @@ - static size_t nextrune(int incr); - static void paste(void); - static void readstdin(void); -+static void readXEvent(void); - static void run(void); - static void setup(void); - static void usage(void); -@@ -59,6 +62,7 @@ - static Item *items = NULL; - static Item *matches, *sel; - static Item *prev, *curr, *next; -+static Item **end = &items; - static Window root, win; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -@@ -102,7 +106,6 @@ - - dc = initdc(); - initfont(dc, font); -- readstdin(); - setup(); - run(); - -@@ -433,9 +436,9 @@ - void - readstdin(void) { - char buf[sizeof text], *p; -- Item *item, **end; -+ Item *item; - -- for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { -+ while (fgets(buf, sizeof buf, stdin)) { - if((p = strchr(buf, '\n'))) - *p = '\0'; - if(!(item = malloc(sizeof *item))) -@@ -444,14 +447,17 @@ - eprintf("cannot strdup %u bytes\n", strlen(buf)+1); - item->next = item->left = item->right = NULL; - inputw = MAX(inputw, textw(dc, item->text)); -+ *end = item; -+ end = &item->next; - } -+ match(); - } - - void --run(void) { -+readXEvent(void) { - XEvent ev; - -- while(!XNextEvent(dc->dpy, &ev)) -+ while(XPending(dc->dpy) && !XNextEvent(dc->dpy, &ev)) - switch(ev.type) { - case Expose: - if(ev.xexpose.count == 0) -@@ -472,6 +478,32 @@ - } - - void -+run(void) { -+ fd_set fds; -+ int x11_fd, n, nfds, flags; -+ -+ flags = fcntl(STDIN_FILENO, F_GETFL); -+ flags |= O_NONBLOCK; -+ fcntl(STDIN_FILENO, F_SETFL, flags); -+ -+ x11_fd = XConnectionNumber(dc->dpy); -+ nfds = MAX(STDIN_FILENO, x11_fd) + 1; -+ while(1) { -+ FD_ZERO(&fds); -+ if (!feof(stdin)) -+ FD_SET(STDIN_FILENO, &fds); -+ FD_SET(x11_fd, &fds); -+ n = select(nfds, &fds, NULL, NULL, NULL); -+ if(n < 0) -+ eprintf("cannot select\n"); -+ if (FD_ISSET(STDIN_FILENO, &fds)) -+ readstdin(); -+ if (FD_ISSET(x11_fd, &fds)) -+ readXEvent(); -+ } -+} -+ -+void - setup(void) { - int x, y, screen; - XSetWindowAttributes wa; -@@ -531,7 +563,7 @@ - promptw = prompt ? textw(dc, prompt) : 0; - XMapRaised(dc->dpy, win); - text[0] = '\0'; -- match(); -+ drawmenu(); - } - - void diff --git a/tools.suckless.org/dmenu/patches/dmenu_xmms.diff b/tools.suckless.org/dmenu/patches/dmenu_xmms.diff @@ -1,133 +0,0 @@ -diff -up dmenu-4.0/config.h dmenu-4.0_xmms/config.h ---- dmenu-4.0/config.h 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_xmms/config.h 2009-11-19 21:31:17.000000000 +0100 -@@ -7,3 +7,4 @@ static const char *normfgcolor = "#00000 - static const char *selbgcolor = "#0066ff"; - static const char *selfgcolor = "#ffffff"; - static unsigned int spaceitem = 30; /* px between menu items */ -+static unsigned int maxtokens = 16; /* max. tokens for pattern matching */ -diff -up dmenu-4.0/dmenu.1 dmenu-4.0_xmms/dmenu.1 ---- dmenu-4.0/dmenu.1 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_xmms/dmenu.1 2009-11-19 21:14:24.000000000 +0100 -@@ -11,6 +11,7 @@ dmenu \- dynamic menu - .RB [ \-p " <prompt>"] - .RB [ \-sb " <color>"] - .RB [ \-sf " <color>"] -+.RB [ \-xs ] - .RB [ \-v ] - .SH DESCRIPTION - .SS Overview -@@ -44,6 +45,9 @@ defines the selected background color (# - .B \-sf <color> - defines the selected foreground color (#RGB, #RRGGBB, and color names are supported). - .TP -+.B \-xs -+xmms-like pattern matching. -+.TP - .B \-v - prints version information to standard output, then exits. - .SH USAGE -diff -up dmenu-4.0/dmenu.c dmenu-4.0_xmms/dmenu.c ---- dmenu-4.0/dmenu.c 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-4.0_xmms/dmenu.c 2009-11-19 21:56:30.000000000 +0100 -@@ -69,6 +69,7 @@ static int textw(const char *text); - /* variables */ - static char *maxname = NULL; - static char *prompt = NULL; -+static char **tokens = NULL; - static char text[4096]; - static int cmdw = 0; - static int promptw = 0; -@@ -77,6 +78,7 @@ static int screen; - static unsigned int mw, mh; - static unsigned int numlockmask = 0; - static Bool running = True; -+static Bool xmms = False; - static Display *dpy; - static DC dc; - static Item *allitems = NULL; /* first of all items */ -@@ -475,22 +477,55 @@ kpress(XKeyEvent * e) { - drawmenu(); - } - -+unsigned int tokenize(char *pat, char **tok) -+{ -+ unsigned int i = 0; -+ char tmp[4096] = {0}; -+ -+ strncpy(tmp, pat, strlen(pat)); -+ tok[0] = strtok(tmp, " "); -+ -+ while(tok[i] && i < maxtokens) -+ tok[++i] = strtok(NULL, " "); -+ return i; -+} -+ - void - match(char *pattern) { -- unsigned int plen; -+ unsigned int plen, tokencnt = 0; -+ char append = 0; - Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - - if(!pattern) - return; -- plen = strlen(pattern); -+ -+ if(!xmms) -+ tokens[(tokencnt = 1)-1] = pattern; -+ else -+ if(!(tokencnt = tokenize(pattern, tokens))) -+ tokens[(tokencnt = 1)-1] = ""; - item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; -- for(i = allitems; i; i = i->next) -- if(!fstrncmp(pattern, i->text, plen + 1)) -+ for(i = allitems; i; i = i->next) { -+ for(int j = 0; j < tokencnt; ++j) { -+ plen = strlen(tokens[j]); -+ if(!fstrncmp(tokens[j], i->text, plen + 1)) -+ append = !append || append > 1 ? 1 : append; -+ else if(!fstrncmp(tokens[j], i->text, plen )) -+ append = !append || append > 2 ? 2 : append; -+ else if(fstrstr(i->text, tokens[j])) -+ append = append > 0 && append < 3 ? append : 3; -+ else { -+ append = 0; -+ break; -+ } -+ } -+ if(append == 1) - appenditem(i, &lexact, &exactend); -- else if(!fstrncmp(pattern, i->text, plen)) -+ else if(append == 2) - appenditem(i, &lprefix, &prefixend); -- else if(fstrstr(i->text, pattern)) -+ else if(append == 3) - appenditem(i, &lsubstr, &substrend); -+ } - if(lexact) { - item = lexact; - itemend = exactend; -@@ -643,6 +678,7 @@ setup(Bool topbar) { - if(promptw > mw / 5) - promptw = mw / 5; - text[0] = 0; -+ tokens = malloc((xmms?maxtokens:1)*sizeof(char*)); - match(text); - XMapRaised(dpy, win); - } -@@ -694,11 +730,13 @@ main(int argc, char *argv[]) { - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; - } -+ else if(!strcmp(argv[i], "-xs")) -+ xmms = True; - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); - else - eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" -- " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); -+ " [-p <prompt>] [-sb <color>] [-sf <color>] [-xs] [-v]\n"); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); - if(!(dpy = XOpenDisplay(NULL))) diff --git a/tools.suckless.org/dmenu/patches/follow-focus.md b/tools.suckless.org/dmenu/patches/follow-focus.md @@ -1,12 +0,0 @@ -Follow input focus -================== - -With this patch dmenu will show up on the monitor which has input focus. - -Download --------- -* [dmenu-4.4-follow-focus.diff](dmenu-4.4-follow-focus.diff) - -Author ------- -* Pascal Wittmann - <mail@pascal-wittmann.de> diff --git a/tools.suckless.org/dmenu/patches/fuzzymatch.md b/tools.suckless.org/dmenu/patches/fuzzymatch.md @@ -10,11 +10,10 @@ non-consecutive portions of the string to be matched. Download -------- -* [dmenu-4.5-fuzzymatch.diff](dmenu-4.5-fuzzymatch.diff) -* [dmenu-git-20151020-fuzzymatch.diff](dmenu-git-20151020-fuzzymatch.diff) +* [dmenu-4.6-fuzzymatch.diff](dmenu-4.6-fuzzymatch.diff) Authors ------ * Jan Christoph Ebersbach - jceb@e-jc.de -* Laslo Hunhold - dev@frign.de (dmenu-4.5, dmenu-git-20151020 ports) +* Laslo Hunhold - dev@frign.de (dmenu-4.6) diff --git a/tools.suckless.org/dmenu/patches/history.md b/tools.suckless.org/dmenu/patches/history.md @@ -1,32 +0,0 @@ -History -======= - -Description ------------ - -A patch to have dmenu do "smart" history. It will re-order the options in a -history file based on frequency of use, with the most used heading to the -top. This is best in conjunction with the history patch to surf. In surf, I -have "^G" point to: - - dmenu -hist /home/peterjh/.dmenu.history -b -l 10 < ~/.surf/history - -Enjoy! - -Download --------- - -* [dmenu-tip-history.diff](dmenu-tip-history.diff) (3545) (20091216) - -Author ------- - -* Peter John Hartman (wart_) <[http://antiopus.trilidun.org/durandus/](http://antiopus.trilidun.org/durandus/)> - -Note ----- - -As an alternative to the patch above, the following script is meant to replace -`dmenu_run` : it handles the command history in a similar way as the patch and -can be used with an unpatched dmenu 4.6. -[dmenu_run_history](http://tools.suckless.org/dmenu/scripts/dmenu_run_with_command_history) diff --git a/tools.suckless.org/dmenu/patches/incremental.md b/tools.suckless.org/dmenu/patches/incremental.md @@ -14,5 +14,4 @@ This is useful as an incremental search feature, for example in surf's config.h: Download -------- -* [dmenu-tip-incremental.diff](dmenu-tip-incremental.diff) * [dmenu-git-incremental.diff](dmenu-git-incremental.diff) diff --git a/tools.suckless.org/dmenu/patches/legacy/allow-kp_decimal-in-dmenu.patch b/tools.suckless.org/dmenu/patches/legacy/allow-kp_decimal-in-dmenu.patch @@ -1,12 +0,0 @@ -diff -r 4684b2cf4eab dmenu.c ---- a/dmenu.c Sat Dec 05 16:52:53 2009 +0000 -+++ b/dmenu.c Sun Dec 13 20:50:57 2009 +0000 -@@ -395,6 +395,8 @@ - ksym = XK_Return; - else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) - ksym = (ksym - XK_KP_0) + XK_0; -+ else if(ksym == XK_KP_Decimal) -+ ksym = XK_period; - } - if(IsFunctionKey(ksym) || IsKeypadKey(ksym) - || IsMiscFunctionKey(ksym) || IsPFKey(ksym) diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-paste.diff b/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-paste.diff @@ -1,27 +0,0 @@ -diff -r f48e2b63129e dmenu.c ---- a/dmenu.c Tue Oct 27 14:38:03 2009 -0700 -+++ b/dmenu.c Thu Oct 29 13:14:21 2009 -0700 -@@ -389,6 +389,23 @@ - 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) { diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-vertical_meillo.diff b/tools.suckless.org/dmenu/patches/legacy/dmenu-4.0-vertical_meillo.diff @@ -1,221 +0,0 @@ -# dmenu-4.0 vertical patch -# -# assembled by meillo@marmaro.de -# -# this is a minimal version of fresch's patch -# http://schiewek.net/fresch/dmenu-3.9-fresch-3.diff -# http://bbs.archlinux.org/viewtopic.php?id=54086 - - -diff -up dmenu-4.0/config.mk dmenu-v/config.mk ---- dmenu-4.0/config.mk 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-v/config.mk 2009-06-03 10:48:35.000000000 +0200 -@@ -1,5 +1,5 @@ - # dmenu version --VERSION = 4.0 -+VERSION = 4.0-vertical - - # Customize below to fit your system - -diff -up dmenu-4.0/dmenu.1 dmenu-v/dmenu.1 ---- dmenu-4.0/dmenu.1 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-v/dmenu.1 2009-06-03 12:54:25.000000000 +0200 -@@ -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 inse - .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 ke - 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 -up dmenu-4.0/dmenu.c dmenu-v/dmenu.c ---- dmenu-4.0/dmenu.c 2009-04-18 13:50:04.000000000 +0200 -+++ dmenu-v/dmenu.c 2009-06-03 12:31:00.000000000 +0200 -@@ -47,10 +47,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); -@@ -88,6 +90,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 = 0; -+static void (*calcoffsets)(void) = calcoffsetsh; -+static void (*drawmenu)(void) = drawmenuh; - - void - appenditem(Item *i, Item **list, Item **last) { -@@ -101,7 +107,7 @@ appenditem(Item *i, Item **list, Item ** - } - - void --calcoffsets(void) { -+calcoffsetsh(void) { - int tw; - unsigned int w; - -@@ -127,6 +133,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 +197,7 @@ cleanup(void) { - } - - void --drawmenu(void) { -+drawmenuh(void) { - Item *i; - - dc.x = 0; -@@ -212,6 +238,39 @@ drawmenu(void) { - } - - 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]; - int i, x, y, h, len, olen; -@@ -222,8 +281,8 @@ drawtext(const char *text, unsigned long - 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--); -@@ -426,6 +485,7 @@ kpress(XKeyEvent * e) { - calcoffsets(); - break; - case XK_Left: -+ case XK_Up: - if(!(sel && sel->left)) - return; - sel=sel->left; -@@ -457,6 +517,7 @@ kpress(XKeyEvent * e) { - running = False; - break; - case XK_Right: -+ case XK_Down: - if(!(sel && sel->right)) - return; - sel=sel->right; -@@ -598,6 +659,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 +738,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]; - } -@@ -697,7 +765,7 @@ main(int argc, char *argv[]) { - else if(!strcmp(argv[i], "-v")) - eprint("dmenu-"VERSION", © 2006-2008 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"); diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu_path-cls.c b/tools.suckless.org/dmenu/patches/legacy/dmenu_path-cls.c @@ -1,100 +0,0 @@ -#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; -} diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu_path.c b/tools.suckless.org/dmenu/patches/legacy/dmenu_path.c @@ -1,376 +0,0 @@ -/* - * dmenu_path - * This program dumps all executables in $PATH to stdout. - * It uses the file $HOME/.dmenu_cache as a cache. - * - * This program is released under the X11 license (sometimes known as the MIT - * license), which basically means that you can do whatever you want with it. - * - * Sorry for the hairy code. I didn't know how to make it simpler and still - * as generic. Valgrind claims it's correct and doesn't leak, but I'm sure you - * can find a couple of ways to make it crash. - * - * I'd appreciate, but I don't require, that you mail me any improvements or - * comments on the code. - * - * Elmo Todurov todurov+dmenu@gmail.com - * 2010-05-19 09:55 - */ - -#include <sys/stat.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <malloc.h> -#include <unistd.h> -#include <dirent.h> -#include <assert.h> - -static uid_t uid; -static gid_t gid; -static char* cache_path; - -static int uptodate(char** paths) -{ - struct stat dirstat; - time_t cache_time; - char** dirs; - - if (stat(cache_path, &dirstat)) - { - if (errno != ENOENT) - { - perror("stat"); - } - return 0; - } - cache_time = dirstat.st_mtime; - - dirs = paths; - while (*dirs != NULL) - { - if (stat(*dirs, &dirstat)) - { - if (errno != ENOENT) - perror("stat"); - return 0; - } - - if (cache_time < dirstat.st_mtime) - return 0; - - dirs++; - } - - return 1; -} - -static void die(const char* msg) -{ - perror(msg); - exit(EXIT_FAILURE); -} - -static char* get_cache_path() -{ - const char* home; - char* path; - home = getenv("HOME"); - if (home == NULL) - die("getenv"); - path = (char*)malloc(strlen(home) + strlen("/.dmenu_cache") + 1); - if (path == NULL) - die("malloc"); - strcpy(path, home); - strcat(path, "/.dmenu_cache"); - return path; -} - -static char* get_PATH() -{ - const char* path = getenv("PATH"); - char* copy_path; - if (path == NULL) - die("getenv"); - - copy_path = strdup(path); - return copy_path; -} - -static void split_PATH(char* PATH, char*** dirs_in) -{ - char** dirs; - const char* dir = strtok(PATH, ":"); - size_t i = 0; - size_t allocated = 10; - dirs = (char**)malloc(sizeof(char*) * allocated); - if (dirs == NULL) - die("malloc"); - - while (dir != NULL) - { - dirs[i] = (char*)malloc(strlen(dir) + 1); - if (dirs[i] == NULL) - die("malloc"); - strcpy(dirs[i], dir); - dir = strtok(NULL, ":"); - i++; - if (i == allocated) - { - allocated *= 2; - dirs = (char**)realloc(dirs, allocated * sizeof(char**)); - if (dirs == NULL) - die("realloc"); - } - } - dirs[i] = NULL; - - *dirs_in = dirs; -} - -static void free_charpp(char** in) -{ - char** ptr = in; - while (*ptr != NULL) - { - free(*ptr); - ptr++; - } - free(in); -} - -static void fprint_charpp(char** in, FILE* out) -{ - char** ptr = in; - while (*ptr != NULL) - { - fputs(*ptr, out); - fputc('\n', out); - ptr++; - } -} - -static size_t count_charpp(char** in) -{ - char** ptr = in; - size_t count = 0; - while (*ptr != NULL) - { - count++; - ptr++; - } - return count; -} - -static int isexecutable(const char* fname) -{ - struct stat st; - int ret; - int success; - gid_t* grouplist; - - ret = stat(fname, &st); - if (ret != 0) - return 0; - if (!S_ISREG(st.st_mode)) /* this catches regular files and symlinks as well */ - return 0; - if ((st.st_uid == uid && (st.st_mode & S_IXUSR) != 0) - || (st.st_uid != uid && st.st_gid != gid && (st.st_mode & S_IXOTH) != 0)) - { - return 1; - } - - /* check secondary groups */ - if (st.st_mode & S_IXGRP) - { - success = 0; - ret = getgroups(0, 0); - grouplist = (gid_t*)malloc(sizeof(gid_t) * ret); - if (grouplist == NULL) - die("malloc"); - ret = getgroups(ret, grouplist); - while (ret != 0) - { - ret--; - if (st.st_uid != uid /* for group to match, user must not match. */ - && st.st_gid == grouplist[ret]) - { - success = 1; - break; - } - } - free(grouplist); - return success; - } - - return 0; -} - -static void add(const char* prog, char*** progs) -{ - static unsigned progs_allocated = 0; - static unsigned progs_used = 0; - - if (progs_used == progs_allocated) - { - progs_allocated = progs_allocated == 0 ? 256 : progs_allocated * 2; - *progs = (char**)realloc(*progs, sizeof(char*) * progs_allocated); - if (*progs == NULL) - die("realloc"); - } - - if (prog != NULL) - { - (*progs)[progs_used] = (char*)malloc(strlen(prog) + 1); - if ((*progs)[progs_used] == NULL) - die("malloc"); - strcpy((*progs)[progs_used], prog); - progs_used++; - } - else - { - (*progs)[progs_used] = NULL; - } -} - -static void refresh_path(const char* path, char*** progs) -{ - DIR* dirp = opendir(path); - struct dirent* dp; - char fullpath[PATH_MAX]; - char* end; - strcpy(fullpath, path); - end = fullpath + strlen(fullpath); - - if (dirp == NULL) - { - if (errno != ENOENT) - perror("opendir"); - return; - } - - dp = readdir(dirp); - while (dp != NULL) - { - strcat(end, "/"); - strcpy(end + 1, dp->d_name); - if (isexecutable(fullpath)) - add(dp->d_name, progs); - dp = readdir(dirp); - } - closedir(dirp); -} - -static int compare(const void* a, const void* b) -{ - return strcmp(*(const char**)a, *(const char**)b); -} - -static void sort(char*** progs) -{ - qsort(*progs, count_charpp(*progs), sizeof(*progs), compare); -} - -static void uniq(char*** progs) -{ - char** progs_new; - char** ptr_1 = *progs; - char** ptr_2 = ptr_1 + 1; - unsigned long i = 0;; - - progs_new = (char**)malloc(sizeof(char*) * (count_charpp(*progs) + 1)); - if (progs_new == NULL) - die("malloc"); - - while (*ptr_1 != NULL) - { - while (*ptr_2 != NULL && strcmp(*ptr_1, *ptr_2) == 0) - { - free(*ptr_2); - ptr_2++; - } - progs_new[i] = *ptr_1; - i++; - ptr_1 = ptr_2; - ptr_2++; - } - progs_new[i] = NULL; - - free(*progs); - - *progs = progs_new; -} - -static void refresh(char** paths) -{ - char** progs = NULL; - FILE* out; - while (*paths != NULL) - { - refresh_path(*paths, &progs); - paths++; - } - add(NULL, &progs); - - out = fopen(cache_path, "w"); - if (out == NULL) - die("fopen"); - - sort(&progs); - uniq(&progs); - fprint_charpp(progs, out); - fprint_charpp(progs, stdout); - - free_charpp(progs); - fclose(out); -} - -static void cat() -{ - FILE* cache = fopen(cache_path, "r"); - char buf[4096]; - struct stat cachestat; - size_t still_unread; - size_t chunk; - if (cache == NULL) - die("fopen"); - - if (stat(cache_path, &cachestat)) - die("stat"); - still_unread = cachestat.st_size; - - while (still_unread > 0) - { - chunk = fread(buf, 1, sizeof(buf), cache); - still_unread -= chunk; - fwrite(buf, 1, chunk, stdout); - } - fclose(cache); -} - -int main(int argc, char *argv[]) -{ - char* PATH; - char** paths = NULL; - PATH = get_PATH(); - uid = getuid(); - gid = getgid(); - - cache_path = get_cache_path(); - split_PATH(PATH, &paths); - free(PATH); - sort(&paths); - uniq(&paths); - - if ((argc == 2 && strcmp(argv[1], "-f") == 0) - || !uptodate(paths)) - refresh(paths); - else - cat(); - - free_charpp(paths); - free(cache_path); - - return 0; -} diff --git a/tools.suckless.org/dmenu/patches/legacy/dmenu_path.md b/tools.suckless.org/dmenu/patches/legacy/dmenu_path.md @@ -1,11 +0,0 @@ -dmenu_path.c -============ - -The mainline dmenu_path is a shell script, which means it can be slow. Faster -implementations have been written in C. - -Download --------- - -* [376 LOC](dmenu_path.c) by Elmo Todurov - <todurov@gmail.com> -* [100 LOC](dmenu_path-cls.c) by Connor Lane Smith - <cls@lubutu.com> diff --git a/tools.suckless.org/dmenu/patches/legacy/index.md b/tools.suckless.org/dmenu/patches/legacy/index.md @@ -1,4 +0,0 @@ -Legacy patches -============== - -Patches that have since been merged into dmenu trunk in the latest release. diff --git a/tools.suckless.org/dmenu/patches/legacy/kp_decimal.md b/tools.suckless.org/dmenu/patches/legacy/kp_decimal.md @@ -1,14 +0,0 @@ -Keypad decimal key -================== - -This patch allows the decimal key on keypads to input a decimal in dmenu. - -Download --------- - -* [allow-kp_decimal-in-dmenu.patch](allow-kp_decimal-in-dmenu.patch) - -Author ------- - -* Thomas Adam (thomas_adam) <[thomas.adam22@gmail.com](mailto:thomas.adam22@gmail.com)> diff --git a/tools.suckless.org/dmenu/patches/legacy/paste.md b/tools.suckless.org/dmenu/patches/legacy/paste.md @@ -1,23 +0,0 @@ -Paste -===== - -Description ------------ - -This patch allows you to paste the contents of the X selection into dmenu. The -default keybinding for this is mod1+p. - -The patch depends on [sselp](/sselp). - -Download --------- - -* [dmenu-4.0-paste.diff](dmenu-4.0-paste.diff) (597) (20091029) - -Author ------- - -* Evan Gates (emg) <[evan.gates@gmail.com](mailto:evan.gates@gmail.com)> - - -***Note, this patch is present in dmenu-4.1.1.*** diff --git a/tools.suckless.org/dmenu/patches/legacy/vertical.md b/tools.suckless.org/dmenu/patches/legacy/vertical.md @@ -1,14 +0,0 @@ -Vertical menu -============= - -This patch allows you to present a vertical menu instead of a horizontal (this is especially useful for long menu entries such as URLs in conjunction with surf). - -It is expected this patch will go into mainstream dmenu in a slightly modified form in the next version (due to the recent decision of surf to use dmenu for interactive input). - -Download --------- - -* [dmenu-4.0-vertical_meillo.diff](dmenu-4.0-vertical_meillo.diff) - - -***Note, this patch is present in dmenu-4.1.1.*** diff --git a/tools.suckless.org/dmenu/patches/monarg.md b/tools.suckless.org/dmenu/patches/monarg.md @@ -1,17 +0,0 @@ -Monitor by Argument -=================== - -Description ------------ - -Accept an additional command line argument to specify the monitor where dmenu -is to be started. Works well with -[dwm-6.1-monarg.diff](http://dwm.suckless.org/patches/monarg). - -Download --------- -* [dmenu-4.5-monarg.diff](dmenu-4.5-monarg.diff) - -Author ------- -* mar77i <mysatyre at gmail dot com> diff --git a/tools.suckless.org/dmenu/patches/mouse-support.md b/tools.suckless.org/dmenu/patches/mouse-support.md @@ -20,11 +20,11 @@ Mouse actions supported: * In horizontal mode: same as left-clicking on right arrow. * In vertical mode: show items below. -The attached patch applies cleanly to latest dmenu 4.5 tip (dec9a28863f388072be105e0950deb72ac719d48). +The attached patch applies cleanly to latest dmenu 4.6. Download -------- -* [dmenu-4.5-mouse-support.diff](dmenu-4.5-mouse-support.diff) +* [dmenu-4.6-mouse-support.diff](dmenu-4.6-mouse-support.diff) Author ------ diff --git a/tools.suckless.org/dmenu/patches/multisel.md b/tools.suckless.org/dmenu/patches/multisel.md @@ -1,12 +0,0 @@ -Multiselect -=========== - -Allow for selecting multiple items. Ctrl+Enter prints an item, colors it differently, and allows input to continue. - -Download --------- -* [dmenu-4.4.1-multisel.diff](dmenu-4.4.1-multisel.diff) - -Author ------- -* Evan Gates (emg)<evan.gates@gmail.com> diff --git a/tools.suckless.org/dmenu/patches/multiselect_and_newline.md b/tools.suckless.org/dmenu/patches/multiselect_and_newline.md @@ -1,19 +0,0 @@ -Multiselect and newline -======================= - -multi-select: selecting an item and pressing return won't terminate dmenu -newline : seperates standard outputs by newlines - -These two features are enabled by -ms and -nl command line flag, they can be useful in scripts where one wishes to print several elements from a list -with new line in between. - -The code comes from a vertical patch for dmenu_3.9 wrote by Fresch, the original patch has a lot of options, I just cutted out the one I use on top of Meillo's dmenu vertical patch. (these two and xmms-like pattern matching for huge strings) - -Cutter ------- -- Julien Steinhauser <[julien.steinhauser@orange.fr](mailto:julien.steinhauser@orange.fr)> - -Download --------- - -* [dmenu-ms_nl.diff](dmenu-ms_nl.diff) diff --git a/tools.suckless.org/dmenu/patches/non_blocking_stdin.md b/tools.suckless.org/dmenu/patches/non_blocking_stdin.md @@ -12,7 +12,6 @@ patch, so that you can use stdout to feed stdin. Download -------- -* [dmenu-tip-non-blocking-stdin.diff](dmenu-tip-non-blocking-stdin.diff) * [dmenu-git-non-blocking-stdin.diff](dmenu-git-non-blocking-stdin.diff) Author diff --git a/tools.suckless.org/dmenu/patches/xft.md b/tools.suckless.org/dmenu/patches/xft.md @@ -1,29 +0,0 @@ -Xft support -=========== - -Description ------------ - -This patch provides Xft support to dmenu, thereby allowing use of -anti-aliased fonts and more. Fonts are specified using the standard -Xft syntax: - - <family>-<size>:<name>=<value> - -For example, 28pt Sans: - - dmenu -fn Sans-28 - -Download --------- - -* [dmenu git](dmenu-git-xft.diff) applies cleanly against 13a529ce63364544bdc851dfd5d3aa2ef8740914 -* [dmenu 4.5](dmenu-4.5-xft.diff) -* [dmenu 4.5 for debian](dmenu-4.5-xft-debian.diff) -* [dmenu 4.5 (improved)](dmenu-4.5-xft-improved.diff) -* [dmenu 4.4.1](dmenu-4.4.1-xft.diff) - -History ------- - -Created from Dan Brown's [4.2.1 patch](http://lists.suckless.org/dev/1011/6474.html). diff --git a/tools.suckless.org/dmenu/patches/xmms-like_pattern_matching.md b/tools.suckless.org/dmenu/patches/xmms-like_pattern_matching.md @@ -1,34 +0,0 @@ -xmms-like pattern matching -========================== - -This patch allows the user to match strings in several pieces. -For example to type: - - dme atc - -could match - - http://tools.suckless.org/dmenu/patches/ - -It can be useful to ease the matching on huge strings. - -The patch comes in two flavours: - -* **tok** (tokenise), for dmenu 4.2.1. Enabled with **-t** command line flag. - -* **xmms**, for legacy dmenu. The original patch submitted by Julien Steinhauser. Enabled with the **-xs** command line flag. - -Download tok ------------- - -* [dmenu-4.2.1-tok.diff](dmenu-4.2.1-tok.diff) - -* [dmenu-4.4-tok.diff](dmenu-4.4-tok.diff) - -Download xmms (legacy) -------------- - -* [dmenu-4.1.1-xmms.diff](dmenu-4.1.1-xmms.diff) - -* [dmenu_xmms.diff](dmenu_xmms.diff) (for **dmenu_3.9** - the original patch submitted by Julien Steinhauser <[julien.steinhauser@orange.fr](mailto:julien.steinhauser@orange.fr)>, taken from [fresch's patch](https://bbs.archlinux.org/viewtopic.php?pid=429090#p429090)) - diff --git a/tools.suckless.org/dmenu/patches/xrdb.diff b/tools.suckless.org/dmenu/patches/xrdb.diff @@ -1,85 +0,0 @@ -diff -r 2b9683c50723 -r ebcc0d8213e0 dmenu.c ---- a/dmenu.c Wed Dec 01 20:25:10 2010 +0000 -+++ b/dmenu.c Tue Dec 14 15:53:44 2010 +0300 -@@ -7,6 +7,7 @@ - #include <X11/Xlib.h> - #include <X11/Xatom.h> - #include <X11/Xutil.h> -+#include <X11/Xresource.h> - #ifdef XINERAMA - #include <X11/extensions/Xinerama.h> - #endif -@@ -37,6 +38,7 @@ - static void run(void); - static void setup(void); - static void usage(void); -+static void read_resourses(void); - - static char text[BUFSIZ]; - static int bh, mw, mh; -@@ -47,10 +49,10 @@ - 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 = NULL; -+static const char *normfgcolor = NULL; -+static const char *selbgcolor = NULL; -+static const char *selfgcolor = NULL; - static unsigned long normcol[ColLast]; - static unsigned long selcol[ColLast]; - static Atom utf8; -@@ -101,6 +103,7 @@ - usage(); - - dc = initdc(); -+ read_resourses(); - initfont(dc, font); - readstdin(); - setup(); -@@ -109,6 +112,42 @@ - return EXIT_FAILURE; /* should not reach */ - } - -+/* Set font and colors from X resources database if they are not set -+ * from command line */ -+void -+read_resourses(void) { -+ XrmDatabase xdb; -+ char* xrm; -+ char* datatype[20]; -+ XrmValue xvalue; -+ -+ XrmInitialize(); -+ xrm = XResourceManagerString(dc->dpy); -+ if( xrm != NULL ) { -+ xdb = XrmGetStringDatabase(xrm); -+ if( font == NULL && XrmGetResource(xdb, "dmenu.font", "*", datatype, &xvalue) == True ) -+ font = strdup(xvalue.addr); -+ if( normfgcolor == NULL && XrmGetResource(xdb, "dmenu.foreground", "*", datatype, &xvalue) == True ) -+ normfgcolor = strdup(xvalue.addr); -+ if( normbgcolor == NULL && XrmGetResource(xdb, "dmenu.background", "*", datatype, &xvalue) == True ) -+ normbgcolor = strdup(xvalue.addr); -+ if( selfgcolor == NULL && XrmGetResource(xdb, "dmenu.selforeground", "*", datatype, &xvalue) == True ) -+ selfgcolor = strdup(xvalue.addr); -+ if( selbgcolor == NULL && XrmGetResource(xdb, "dmenu.selbackground", "*", datatype, &xvalue) == True ) -+ selbgcolor = strdup(xvalue.addr); -+ XrmDestroyDatabase(xdb); -+ } -+ /* Set default colors if they are not set */ -+ if( normbgcolor == NULL ) -+ normbgcolor = "#cccccc"; -+ if( normfgcolor == NULL ) -+ normfgcolor = "#000000"; -+ if( selbgcolor == NULL ) -+ selbgcolor = "#0066ff"; -+ if( selfgcolor == NULL ) -+ selfgcolor = "#ffffff"; -+} -+ - void - appenditem(Item *item, Item **list, Item **last) { - if(!*last) diff --git a/tools.suckless.org/dmenu/patches/xrdb.md b/tools.suckless.org/dmenu/patches/xrdb.md @@ -1,16 +0,0 @@ -Incremental output -================== - -This patch allows to confgure font and colors using X resource database. -Following resources are supported: - - * dmenu.font - font - * dmenu.foreground - foreground color - * dmenu.background - background color - * dmenu.selforeground - foreground color for selected area - * dmenu.selbackground - background color for selected area - -Download --------- - -* [xrdb.diff](xrdb.diff)