diff options
author | Lars Rustand | 2019-07-20 15:00:06 +0200 |
---|---|---|
committer | Lars Rustand | 2019-07-20 15:10:52 +0200 |
commit | d3154998249a2713b5d01240f3bdf34022ac8131 (patch) | |
tree | d5ba44e63060735d0b224111fc828030b005bda1 | |
parent | f1a8b6b7e7c4c2f675bd1f775cf647743b53c6ff (diff) | |
download | aur-d3154998249a2713b5d01240f3bdf34022ac8131.tar.gz |
Updated to 4.9
-rw-r--r-- | .SRCINFO | 26 | ||||
-rw-r--r-- | PKGBUILD | 24 | ||||
-rw-r--r-- | break-fix.diff | 23 | ||||
-rw-r--r-- | dmenu-4.5-fuzzy-fixed.diff | 94 | ||||
-rw-r--r-- | dmenu-4.5-height-fixed.diff | 84 | ||||
-rw-r--r-- | dmenu-4.5-history-fixed.diff | 216 | ||||
-rw-r--r-- | dmenu-4.5-mouse-support.diff | 143 | ||||
-rw-r--r-- | dmenu-4.5-xft.diff | 418 | ||||
-rw-r--r-- | dmenu-4.9.tar.gz | bin | 0 -> 15972 bytes | |||
-rw-r--r-- | dmenu-fuzzymatch-4.9.diff | 163 | ||||
-rw-r--r-- | dmenu-lineheight-4.9.diff | 94 | ||||
-rw-r--r-- | dmenu-mousesupport-4.7.diff | 156 | ||||
-rw-r--r-- | dmenu-xft-mouse-height-fuzzy-history-4.9-1-x86_64.pkg.tar.xz | bin | 0 -> 30580 bytes |
13 files changed, 432 insertions, 1009 deletions
@@ -1,7 +1,7 @@ pkgbase = dmenu-xft-mouse-height-fuzzy-history pkgdesc = Dynamic X menu - with xft, mouse, height, history, and fuzzy search support - pkgver = 4.5 - pkgrel = 5 + pkgver = 4.9 + pkgrel = 1 url = http://tools.suckless.org/dmenu/ arch = i686 arch = x86_64 @@ -12,20 +12,14 @@ pkgbase = dmenu-xft-mouse-height-fuzzy-history provides = dmenu conflicts = dmenu conflicts = dmenu2 - source = http://dl.suckless.org/tools/dmenu-4.5.tar.gz - source = dmenu-4.5-xft.diff - source = break-fix.diff - source = dmenu-4.5-history-fixed.diff - source = dmenu-4.5-fuzzy-fixed.diff - source = dmenu-4.5-mouse-support.diff - source = dmenu-4.5-height-fixed.diff - md5sums = 9c46169ed703732ec52ed946c27d84b4 - md5sums = 0c73d595eb78f159bea83f33bba15e80 - md5sums = 6921f9d8aabb53f22adcbf5630dff6b8 - md5sums = 8541735789d9810d7020fdba62b72296 - md5sums = 71fc82b76c45499fcd46b3754407f59d - md5sums = eeec3e11ff68f27ebbc3133ad6549f56 - md5sums = 53b286e8bd76d9225f365673fafd6083 + source = http://dl.suckless.org/tools/dmenu-4.9.tar.gz + source = dmenu-fuzzymatch-4.9.diff + source = dmenu-mousesupport-4.7.diff + source = dmenu-lineheight-4.9.diff + md5sums = 9a537ec9a3a2ce9f08963d66b56cc030 + md5sums = 10f1d55f242fd34aae6b72b51fd50915 + md5sums = 274972c3f6de489dd00543a6d653b960 + md5sums = 0832170eeeec1a70febf641828ddcd17 pkgname = dmenu-xft-mouse-height-fuzzy-history @@ -1,7 +1,7 @@ # Maintainer: Franklyn Tackitt pkgname=dmenu-xft-mouse-height-fuzzy-history -pkgver=4.5 -pkgrel=5 +pkgver=4.9 +pkgrel=1 pkgdesc="Dynamic X menu - with xft, mouse, height, history, and fuzzy search support" url="http://tools.suckless.org/dmenu/" arch=('i686' 'x86_64') @@ -9,20 +9,14 @@ license=('MIT') depends=('sh' 'libxinerama' 'libxft') conflicts=('dmenu' 'dmenu2') provides=('dmenu') -patches=(dmenu-4.5-xft.diff - break-fix.diff - dmenu-4.5-history-fixed.diff - dmenu-4.5-fuzzy-fixed.diff - dmenu-4.5-mouse-support.diff - dmenu-4.5-height-fixed.diff) +patches=(dmenu-fuzzymatch-4.9.diff + dmenu-mousesupport-4.7.diff + dmenu-lineheight-4.9.diff) source=(http://dl.suckless.org/tools/dmenu-$pkgver.tar.gz "${patches[@]}") -md5sums=('9c46169ed703732ec52ed946c27d84b4' - '0c73d595eb78f159bea83f33bba15e80' - '6921f9d8aabb53f22adcbf5630dff6b8' - '8541735789d9810d7020fdba62b72296' - '71fc82b76c45499fcd46b3754407f59d' - 'eeec3e11ff68f27ebbc3133ad6549f56' - '53b286e8bd76d9225f365673fafd6083') +md5sums=('9a537ec9a3a2ce9f08963d66b56cc030' + '10f1d55f242fd34aae6b72b51fd50915' + '274972c3f6de489dd00543a6d653b960' + '0832170eeeec1a70febf641828ddcd17') prepare() { cd $srcdir/dmenu-$pkgver for patch in "${patches[@]}"; do diff --git a/break-fix.diff b/break-fix.diff deleted file mode 100644 index 989ee6707961..000000000000 --- a/break-fix.diff +++ /dev/null @@ -1,23 +0,0 @@ -diff -upr dmenu-4.5-xft/dmenu.c dmenu-4.5-break/dmenu.c ---- dmenu-4.5-xft/dmenu.c 2014-05-04 17:32:10.896300286 -0600 -+++ dmenu-4.5-break/dmenu.c 2014-05-04 17:31:41.406300227 -0600 -@@ -337,8 +337,9 @@ keypress(XKeyEvent *ev) { - sel = matchend; - break; - case XK_Escape: -- ret = EXIT_FAILURE; -- running = False; -+ ret = EXIT_FAILURE; -+ running = False; -+ break; - case XK_Home: - if(sel == matches) { - cursor = 0; -@@ -378,6 +379,7 @@ keypress(XKeyEvent *ev) { - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - ret = EXIT_SUCCESS; - running = False; -+ break; - case XK_Right: - if(text[cursor] != '\0') { - cursor = nextrune(+1); diff --git a/dmenu-4.5-fuzzy-fixed.diff b/dmenu-4.5-fuzzy-fixed.diff deleted file mode 100644 index 2db2cf2b026d..000000000000 --- a/dmenu-4.5-fuzzy-fixed.diff +++ /dev/null @@ -1,94 +0,0 @@ -diff -rupN orig/dmenu.c new/dmenu.c ---- orig/dmenu.c 2015-02-03 11:21:10.802786099 -0700 -+++ new/dmenu.c 2015-02-03 11:22:45.321029644 -0700 -@@ -34,6 +34,9 @@ static void grabkeyboard(void); - static void insert(const char *str, ssize_t n); - static void keypress(XKeyEvent *ev); - static void match(void); -+static void match_fuzzy(void); -+static void match_tokens(void); -+static char *strchri(const char *s, int c); - static size_t nextrune(int inc); - static void paste(void); - static void readitems(void); -@@ -64,12 +67,14 @@ static Item *matches, *matchend; - static Item *prev, *curr, *next, *sel; - static Window win; - static XIC xic; -+static Bool fuzzy; - - static char *histfile = NULL; - static Item *histitems, *histend; - - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; -+static char *(*fstrchr)(const char *, const int) = strchr; - - int - main(int argc, char *argv[]) { -@@ -86,9 +91,12 @@ main(int argc, char *argv[]) { - topbar = False; - else if(!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = True; -+ else if(!strcmp(argv[i], "-z")) /* enable fuzzy matching */ -+ fuzzy = True; - else if(!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; -+ fstrchr = strchri; - } - else if(i+1 == argc) - usage(); -@@ -464,8 +472,52 @@ keypress(XKeyEvent *ev) { - drawmenu(); - } - -+char * -+strchri(const char *s, int c) { -+ char *u, *l; -+ if(!isalpha(c)) return strchr(s, c); -+ if(isupper(c)) { -+ u = strchr(s, c); -+ l = strchr(s, tolower(c)); -+ } -+ else { -+ l = strchr(s, c); -+ u = strchr(s, toupper(c)); -+ } -+ -+ if(u && l) return u < l ? u : l; -+ return u == NULL ? l : u; -+} -+ - void - match(void) { -+ if(fuzzy) match_fuzzy(); -+ else match_tokens(); -+} -+ -+void -+match_fuzzy(void) { -+ int i; -+ size_t len; -+ Item *item; -+ -+ char *pos; -+ -+ len = strlen(text); -+ -+ matches = matchend = NULL; -+ for(item = items; item && item->text; item++) { -+ i = 0; -+ for(pos = fstrchr(item->text, text[i]); pos && text[i]; i++, pos = fstrchr(pos+1, text[i])); -+ if(i == len) appenditem(item, &matches, &matchend); -+ } -+ -+ curr = sel = matches; -+ calcoffsets(); -+} -+ -+void -+match_tokens(void) { - static char **tokv = NULL; - static int tokn = 0; - diff --git a/dmenu-4.5-height-fixed.diff b/dmenu-4.5-height-fixed.diff deleted file mode 100644 index 8186a90f3668..000000000000 --- a/dmenu-4.5-height-fixed.diff +++ /dev/null @@ -1,84 +0,0 @@ -diff -rupN orig/dmenu.1 new/dmenu.1 ---- orig/dmenu.1 2015-02-03 11:24:25.218280503 -0700 -+++ new/dmenu.1 2015-02-03 11:24:34.434303318 -0700 -@@ -8,6 +8,8 @@ dmenu \- dynamic menu - .RB [ \-i ] - .RB [ \-l - .IR lines ] -+.RB [ \-h -+.IR height ] - .RB [ \-p - .IR prompt ] - .RB [ \-fn -@@ -51,6 +53,9 @@ dmenu matches menu items case insensitiv - .BI \-l " lines" - dmenu lists items vertically, with the given number of lines. - .TP -+.BI \-h " height" -+defines the height of the bar in pixels. -+.TP - .BI \-p " prompt" - defines the prompt to be displayed to the left of the input field. - .TP -diff -rupN orig/dmenu.c new/dmenu.c ---- orig/dmenu.c 2015-02-03 11:24:25.218280503 -0700 -+++ new/dmenu.c 2015-02-03 11:25:32.430445657 -0700 -@@ -55,7 +55,7 @@ static const char *normbgcolor = "#22222 - static const char *normfgcolor = "#bbbbbb"; - static const char *selbgcolor = "#005577"; - static const char *selfgcolor = "#eeeeee"; --static unsigned int lines = 0; -+static unsigned int lines, line_height = 0; - static ColorSet *normcol; - static ColorSet *selcol; - static Atom clip, utf8; -@@ -104,6 +104,8 @@ main(int argc, char *argv[]) { - /* these options take one argument */ - else if(!strcmp(argv[i], "-l")) /* number of lines in vertical list */ - lines = atoi(argv[++i]); -+ else if(!strcmp(argv[i], "-h")) /* minimum height of single line */ -+ line_height = atoi(argv[++i]); - else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; - else if(!strcmp(argv[i], "-fn")) /* font or font set */ -@@ -260,8 +262,8 @@ drawmenu(void) { - /* draw input field */ - dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; - drawtext(dc, text, normcol); -- if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) -- drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG); -+ if((curpos = textnw(dc, text, cursor) + dc->font.height/2) < dc->w) -+ drawrect(dc, curpos, (dc->h - dc->font.height)/2 + 1, 1, dc->font.height -1, True, normcol->FG); - - if(lines > 0) { - /* draw vertical list */ -@@ -800,7 +802,7 @@ setup(void) { - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); - - /* calculate menu geometry */ -- bh = dc->font.height + 2; -+ bh = (line_height > dc->font.height + 2) ? line_height : dc->font.height + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; - #ifdef XINERAMA -@@ -869,7 +871,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] [-h height] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-hist histfile] [-v]\n", stderr); - exit(EXIT_FAILURE); - } -diff -rupN orig/draw.c new/draw.c ---- orig/draw.c 2015-02-03 11:24:25.219280505 -0700 -+++ new/draw.c 2015-02-03 11:24:34.435303320 -0700 -@@ -39,7 +39,7 @@ drawtext(DC *dc, const char *text, Color - void - 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; -+ int y = dc->y + dc->font.ascent + (dc->h - dc->font.height)/2; - - XSetForeground(dc->dpy, dc->gc, col->FG); - if(dc->font.xft_font) { diff --git a/dmenu-4.5-history-fixed.diff b/dmenu-4.5-history-fixed.diff deleted file mode 100644 index 4cc660b1334d..000000000000 --- a/dmenu-4.5-history-fixed.diff +++ /dev/null @@ -1,216 +0,0 @@ -diff -rupN without/dmenu.1 with/dmenu.1 ---- without/dmenu.1 2015-02-03 11:15:59.416937469 -0700 -+++ with/dmenu.1 2015-02-03 11:16:13.160976522 -0700 -@@ -20,6 +20,8 @@ dmenu \- dynamic menu - .IR color ] - .RB [ \-sf - .IR color ] -+.RB [ \-hist -+.IR "<filename>" ] - .RB [ \-v ] - .P - .BR dmenu_run " ..." -@@ -70,6 +72,9 @@ defines the selected background color. - .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 stdout, then exits. - .SH USAGE -diff -rupN without/dmenu.c with/dmenu.c ---- without/dmenu.c 2015-02-03 11:15:59.416937469 -0700 -+++ with/dmenu.c 2015-02-03 11:19:01.935443821 -0700 -@@ -36,7 +36,7 @@ static void keypress(XKeyEvent *ev); - static void match(void); - static size_t nextrune(int inc); - static void paste(void); --static void readstdin(void); -+static void readitems(void); - static void run(void); - static void setup(void); - static void usage(void); -@@ -65,6 +65,9 @@ static Item *prev, *curr, *next, *sel; - static Window win; - static XIC xic; - -+static char *histfile = NULL; -+static Item *histitems, *histend; -+ - static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; - static char *(*fstrstr)(const char *, const char *) = strstr; - -@@ -104,6 +107,8 @@ main(int argc, char *argv[]) { - selbgcolor = argv[++i]; - else if(!strcmp(argv[i], "-sf")) /* selected foreground color */ - selfgcolor = argv[++i]; -+ else if(!strcmp(argv[i], "-hist")) -+ histfile = argv[++i]; - else - usage(); - -@@ -114,10 +119,10 @@ main(int argc, char *argv[]) { - - if(fast) { - grabkeyboard(); -- readstdin(); -+ readitems(); - } - else { -- readstdin(); -+ readitems(); - grabkeyboard(); - } - setup(); -@@ -127,6 +132,59 @@ main(int argc, char *argv[]) { - return ret; - } - -+static int -+writehistory(char *command) { -+ FILE *f; -+ Item *histitem; -+ char *histline; -+ char *histcmd; -+ int currcnt = 1; -+ int histcnt; -+ -+ if(!histfile || strlen(command) <= 0) -+ return 0; -+ -+ if((f = fopen(histfile, "w"))) { -+ /* get the current count of previous runs for this command */ -+ for(histitem = histitems; histitem && histitem->text; histitem=histitem->right) { -+ histline = strdup(histitem->text); -+ histcmd = strsep(&histline, "\t"); -+ if(strcmp(command, histcmd) == 0) { -+ currcnt = atoi(strsep(&histline, "\t")) + 1; -+ } -+ } -+ -+ /* loop through history printing those with more runs */ -+ for(histitem = histitems; histitem && histitem->text; histitem=histitem->right) { -+ histline = strdup(histitem->text); -+ histcmd = strsep(&histline, "\t"); -+ histcnt = atoi(strsep(&histline, "\t")); -+ if(histcnt > currcnt) { -+ fprintf(f, "%s", histitem->text); -+ } else { -+ break; -+ } -+ } -+ -+ /* print this command now so it's the first in line with this run count */ -+ /* reducing the count by 1 here to keep the next comparison loop simple */ -+ fprintf(f, "%s\t%d\n", command, currcnt--); -+ -+ /* print all the rest except this command's old line */ -+ for(; histitem && histitem->text; histitem=histitem->right) { -+ histline = strdup(histitem->text); -+ histcmd = strsep(&histline, "\t"); -+ histcnt = atoi(strsep(&histline, "\t")); -+ if(histcnt < currcnt || strcmp(command, histcmd) != 0) -+ fprintf(f, "%s", histitem->text); -+ } -+ fclose(f); -+ return 1; -+ } -+ -+ return 0; -+} -+ - void - appenditem(Item *item, Item **list, Item **last) { - if(*last) -@@ -378,6 +436,7 @@ keypress(XKeyEvent *ev) { - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - ret = EXIT_SUCCESS; -+ writehistory( (sel == NULL) ? text : sel->text); - running = False; - break; - case XK_Right: -@@ -484,26 +543,60 @@ paste(void) { - } - - void --readstdin(void) { -- char buf[sizeof text], *p, *maxstr = NULL; -- size_t i, max = 0, size = 0; -+readitems(void) { -+ char buf[sizeof text], *p, *maxstr = NULL, *histline, *histcmd; -+ size_t i = 0, j = 0, k = 0, max = 0, size = 0; -+ FILE *f; -+ Bool listed; -+ Item *histitem; -+ histitems = histend = NULL; -+ -+ if(histfile && (f = fopen(histfile, "r"))) { -+ for(; fgets(buf, sizeof buf, f); i++) { -+ histitem = malloc(sizeof *histitem); -+ histitem->text = strdup(buf); -+ appenditem(histitem, &histitems, &histend); -+ if(i+1 >= size / sizeof *items) -+ if(!(items = realloc(items, (size += BUFSIZ)))) -+ eprintf("cannot realloc %u bytes:", size); -+ if((p = strchr(buf, '\n'))) -+ *p = '\0'; -+ histline = strdup(buf); -+ histcmd = strsep(&histline, "\t"); -+ if(!(items[i].text = strdup(histcmd))) -+ eprintf("cannot strdup %u bytes:", strlen(histcmd)+1); -+ if(strlen(items[i].text) > max) -+ max = strlen(maxstr = items[i].text); -+ } -+ fclose(f); -+ } - - /* read each line from stdin and add it to the item list */ -- for(i = 0; fgets(buf, sizeof buf, stdin); i++) { -- if(i+1 >= size / sizeof *items) -- if(!(items = realloc(items, (size += BUFSIZ)))) -- eprintf("cannot realloc %u bytes:", size); -+ for(j = i; fgets(buf, sizeof buf, stdin); j++) { - if((p = strchr(buf, '\n'))) - *p = '\0'; -- if(!(items[i].text = strdup(buf))) -- eprintf("cannot strdup %u bytes:", strlen(buf)+1); -- if(strlen(items[i].text) > max) -- max = strlen(maxstr = items[i].text); -+ listed = False; -+ for(k = 0; k < i; k++) { -+ if(strcmp(buf, items[k].text) == 0) { -+ listed = True; -+ j--; -+ break; -+ } -+ } -+ if(!listed) { -+ if(j+1 >= size / sizeof *items) -+ if(!(items = realloc(items, (size += BUFSIZ)))) -+ eprintf("cannot realloc %u bytes:", size); -+ if(!(items[j].text = strdup(buf))) -+ eprintf("cannot strdup %u bytes:", strlen(buf)+1); -+ if(strlen(items[j].text) > max) -+ max = strlen(maxstr = items[j].text); -+ } - } - if(items) -- items[i].text = NULL; -+ items[j].text = NULL; - inputw = maxstr ? textw(dc, maxstr) : 0; -- lines = MIN(lines, i); -+ lines = MIN(lines, j); - } - - void -@@ -617,6 +710,6 @@ setup(void) { - void - usage(void) { - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" -- " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); -+ " [-nb color] [-nf color] [-sb color] [-sf color] [-hist histfile] [-v]\n", stderr); - exit(EXIT_FAILURE); - } diff --git a/dmenu-4.5-mouse-support.diff b/dmenu-4.5-mouse-support.diff deleted file mode 100644 index d5bb4de2fc8e..000000000000 --- a/dmenu-4.5-mouse-support.diff +++ /dev/null @@ -1,143 +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); -@@ -388,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; -@@ -496,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); -@@ -585,8 +693,9 @@ setup(void) { - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = normcol->BG; -- 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), - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); diff --git a/dmenu-4.5-xft.diff b/dmenu-4.5-xft.diff deleted file mode 100644 index ff93337ca276..000000000000 --- a/dmenu-4.5-xft.diff +++ /dev/null @@ -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/dmenu-4.9.tar.gz b/dmenu-4.9.tar.gz Binary files differnew file mode 100644 index 000000000000..da7255d3f201 --- /dev/null +++ b/dmenu-4.9.tar.gz diff --git a/dmenu-fuzzymatch-4.9.diff b/dmenu-fuzzymatch-4.9.diff new file mode 100644 index 000000000000..9fd206d8bc9d --- /dev/null +++ b/dmenu-fuzzymatch-4.9.diff @@ -0,0 +1,163 @@ +From 94353eb52055927d9079f3d9e33da1c954abf386 Mon Sep 17 00:00:00 2001 +From: aleks <aleks.stier@icloud.com> +Date: Wed, 26 Jun 2019 13:25:10 +0200 +Subject: [PATCH] Add support for fuzzy-matching + +--- + config.def.h | 1 + + config.mk | 2 +- + dmenu.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 91 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..51612b9 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 fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/config.mk b/config.mk +index 0929b4a..d14309a 100644 +--- a/config.mk ++++ b/config.mk +@@ -20,7 +20,7 @@ FREETYPEINC = /usr/include/freetype2 + + # includes and libs + INCS = -I$(X11INC) -I$(FREETYPEINC) +-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) ++LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm + + # flags + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) +diff --git a/dmenu.c b/dmenu.c +index 6b8f51b..96ddc98 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -1,6 +1,7 @@ + /* See LICENSE file for copyright and license details. */ + #include <ctype.h> + #include <locale.h> ++#include <math.h> + #include <stdio.h> + #include <stdlib.h> + #include <string.h> +@@ -32,6 +33,7 @@ struct item { + char *text; + struct item *left, *right; + int out; ++ double distance; + }; + + static char text[BUFSIZ] = ""; +@@ -210,9 +212,94 @@ grabkeyboard(void) + die("cannot grab keyboard"); + } + ++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 ? 0 : da->distance < db->distance ? -1 : 1; ++} ++ ++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; /* pointer */ ++ sidx = eidx = -1; /* start of match, end of match */ ++ /* walk through item text */ ++ for (i = 0; i < itext_len && (c = it->text[i]); i++) { ++ /* fuzzy match pattern */ ++ if (!fstrncmp(&text[pidx], &c, 1)) { ++ if(sidx == -1) ++ sidx = i; ++ pidx++; ++ if (pidx == text_len) { ++ eidx = i; ++ break; ++ } ++ } ++ } ++ /* build list of matches */ ++ if (eidx != -1) { ++ /* compute distance */ ++ /* add penalty if match starts late (log(sidx+2)) ++ * add penalty for long a match without many matching characters */ ++ it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len); ++ /* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */ ++ 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 + match(void) + { ++ if (fuzzy) { ++ fuzzymatch(); ++ return; ++ } + static char **tokv = NULL; + static int tokn = 0; + +@@ -702,6 +789,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], "-F")) /* grabs keyboard before reading stdin */ ++ fuzzy = 0; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; +-- +2.22.0 + diff --git a/dmenu-lineheight-4.9.diff b/dmenu-lineheight-4.9.diff new file mode 100644 index 000000000000..d12c77afa605 --- /dev/null +++ b/dmenu-lineheight-4.9.diff @@ -0,0 +1,94 @@ +From 87f92a561c31246f6f9effc0e89ef92677c87746 Mon Sep 17 00:00:00 2001 +From: astier <aleksandrs.stier@uni-bielefeld.de> +Date: Wed, 27 Feb 2019 21:44:55 +0100 +Subject: [PATCH] Add an option which defines the lineheight + +Despite both the panel and dmenu using the same font (a Terminus 12), +dmenu is shorter and the panel is visible from under the dmenu bar. +The appearance can be even more distracting when using similar colors +for background and selections. With the option added by this patch, +dmenu can be launched with a '-h 24', thus completely covering the panel. +--- + config.def.h | 1 + + dmenu.1 | 3 +++ + dmenu.c | 10 ++++++++-- + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..317fa2f 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -15,6 +15,7 @@ static const char *colors[SchemeLast][2] = { + }; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; ++static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */ + + /* + * Characters not considered part of a word while deleting words +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..7ef34d2 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -50,6 +50,9 @@ dmenu matches menu items case insensitively. + .BI \-l " lines" + dmenu lists items vertically, with the given number of lines. + .TP ++.BI \-h " height" ++dmenu uses a menu line of at least 'height' pixels tall, but no less than 8. ++.TP + .BI \-m " monitor" + dmenu is displayed on the monitor number supplied. Monitor numbers are starting + from 0. +diff --git a/dmenu.c b/dmenu.c +index 6b8f51b..45d1946 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -131,7 +131,7 @@ drawmenu(void) + { + unsigned int curpos; + struct item *item; +- int x = 0, y = 0, w; ++ int x = 0, y = 0, fh = drw->fonts->h, w; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); +@@ -148,7 +148,7 @@ drawmenu(void) + curpos = TEXTW(text) - TEXTW(&text[cursor]); + if ((curpos += lrpad / 2 - 1) < w) { + drw_setscheme(drw, scheme[SchemeNorm]); +- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); ++ drw_rect(drw, x + curpos, 2 + (bh-fh)/2, 2, fh - 4, 1, 0); + } + + if (lines > 0) { +@@ -604,6 +604,7 @@ setup(void) + + /* calculate menu geometry */ + bh = drw->fonts->h + 2; ++ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; + #ifdef XINERAMA +@@ -683,6 +684,7 @@ static void + usage(void) + { + fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ " [-h height]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); + exit(1); + } +@@ -716,6 +718,10 @@ main(int argc, char *argv[]) + prompt = argv[++i]; + else if (!strcmp(argv[i], "-fn")) /* font or font set */ + fonts[0] = argv[++i]; ++ else if(!strcmp(argv[i], "-h")) { /* minimum height of one menu line */ ++ lineheight = atoi(argv[++i]); ++ lineheight = MAX(lineheight,8); /* reasonable default in case of value too small/negative */ ++ } + else if (!strcmp(argv[i], "-nb")) /* normal background color */ + colors[SchemeNorm][ColBg] = argv[++i]; + else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ +-- +2.21.0 + diff --git a/dmenu-mousesupport-4.7.diff b/dmenu-mousesupport-4.7.diff new file mode 100644 index 000000000000..b72bd862b9be --- /dev/null +++ b/dmenu-mousesupport-4.7.diff @@ -0,0 +1,156 @@ +From 27f62488ceb466f73f682f5104825c60712bb5ff Mon Sep 17 00:00:00 2001 +From: Hiltjo Posthuma <hiltjo@codemadness.org> +Date: Fri, 9 Jun 2017 13:00:06 +0200 +Subject: [PATCH] dmenu mouse support + +--- + dmenu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 118 insertions(+), 1 deletion(-) + +diff --git a/dmenu.c b/dmenu.c +index d605ab4..0c8500b 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -459,6 +459,119 @@ keypress(XKeyEvent *ev) + } + + static void ++buttonpress(XEvent *e) ++{ ++ 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; ++ ++ /* 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(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 (ev->state & ~ControlMask) ++ return; ++ if (lines > 0) { ++ /* vertical list: (ctrl)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); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ } 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: (ctrl)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); ++ if (!(ev->state & ControlMask)) ++ exit(0); ++ sel = item; ++ if (sel) { ++ sel->out = 1; ++ drawmenu(); ++ } ++ return; ++ } ++ } ++ /* 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; +@@ -512,6 +625,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); +@@ -609,7 +725,8 @@ setup(void) + /* create menu window */ + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; +- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; ++ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | ++ ButtonPressMask; + win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); +-- +2.12.2 + diff --git a/dmenu-xft-mouse-height-fuzzy-history-4.9-1-x86_64.pkg.tar.xz b/dmenu-xft-mouse-height-fuzzy-history-4.9-1-x86_64.pkg.tar.xz Binary files differnew file mode 100644 index 000000000000..65d9278dae8c --- /dev/null +++ b/dmenu-xft-mouse-height-fuzzy-history-4.9-1-x86_64.pkg.tar.xz |