autolinux-dmenu


Logs | Files | LICENSE | LICENSE | GitLab


1
commit 5fe6aa0a3765e2bd993d768116d15113628116ba
2
Author: Connor Etherington <[email protected]>
3
Date:   Thu Apr 18 02:18:32 2024 +0200
4
5
    Auto-Commit Update 18.04.2024 - 02:18:32
6
---
7
 LICENSE                               |   30 +
8
 Makefile                              |   64 ++
9
 PKGBUILD                              |   44 ++
10
 arg.h                                 |   46 ++
11
 config.h                              |   45 ++
12
 config.mk                             |   31 +
13
 dmenu-border-4.9.diff                 |   25 +
14
 dmenu-center-20200111-8cd37e1.diff    |  120 ++++
15
 dmenu-fuzzyhighlight-4.9.diff         |  152 +++++
16
 dmenu-fuzzymatch-4.9.diff             |  163 +++++
17
 dmenu-grid-4.9.diff                   |  107 ++++
18
 dmenu-lineheight-4.9.diff             |   94 +++
19
 dmenu-morecolor-20190922-4bf895b.diff |   47 ++
20
 dmenu-mousesupport-5.0.diff           |  144 +++++
21
 dmenu-numbers-4.9.diff                |   81 +++
22
 dmenu.1                               |  225 +++++++
23
 dmenu.c                               | 1097 +++++++++++++++++++++++++++++++++
24
 dmenu_path                            |   13 +
25
 dmenu_run                             |    2 +
26
 drw.c                                 |  436 +++++++++++++
27
 drw.h                                 |   57 ++
28
 stest.1                               |   90 +++
29
 stest.c                               |  109 ++++
30
 util.c                                |   35 ++
31
 util.h                                |    8 +
32
 25 files changed, 3265 insertions(+)
33
34
diff --git a/LICENSE b/LICENSE
35
new file mode 100644
36
index 0000000..3afd28e
37
--- /dev/null
38
+++ b/LICENSE
39
@@ -0,0 +1,30 @@
40
+MIT/X Consortium License
41
+
42
+© 2006-2019 Anselm R Garbe <[email protected]>
43
+© 2006-2008 Sander van Dijk <[email protected]>
44
+© 2006-2007 Michał Janeczek <[email protected]>
45
+© 2007 Kris Maglione <[email protected]>
46
+© 2009 Gottox <[email protected]>
47
+© 2009 Markus Schnalke <[email protected]>
48
+© 2009 Evan Gates <[email protected]>
49
+© 2010-2012 Connor Lane Smith <[email protected]>
50
+© 2014-2020 Hiltjo Posthuma <[email protected]>
51
+© 2015-2019 Quentin Rameau <[email protected]>
52
+
53
+Permission is hereby granted, free of charge, to any person obtaining a
54
+copy of this software and associated documentation files (the "Software"),
55
+to deal in the Software without restriction, including without limitation
56
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
57
+and/or sell copies of the Software, and to permit persons to whom the
58
+Software is furnished to do so, subject to the following conditions:
59
+
60
+The above copyright notice and this permission notice shall be included in
61
+all copies or substantial portions of the Software.
62
+
63
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
66
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
68
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
69
+DEALINGS IN THE SOFTWARE.
70
diff --git a/Makefile b/Makefile
71
new file mode 100644
72
index 0000000..a03a95c
73
--- /dev/null
74
+++ b/Makefile
75
@@ -0,0 +1,64 @@
76
+# dmenu - dynamic menu
77
+# See LICENSE file for copyright and license details.
78
+
79
+include config.mk
80
+
81
+SRC = drw.c dmenu.c stest.c util.c
82
+OBJ = $(SRC:.c=.o)
83
+
84
+all: options dmenu stest
85
+
86
+options:
87
+	@echo dmenu build options:
88
+	@echo "CFLAGS   = $(CFLAGS)"
89
+	@echo "LDFLAGS  = $(LDFLAGS)"
90
+	@echo "CC       = $(CC)"
91
+
92
+.c.o:
93
+	$(CC) -c $(CFLAGS) $<
94
+
95
+config.h:
96
+	cp config.def.h $@
97
+
98
+$(OBJ): arg.h config.h config.mk drw.h
99
+
100
+dmenu: dmenu.o drw.o util.o
101
+	$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
102
+
103
+stest: stest.o
104
+	$(CC) -o $@ stest.o $(LDFLAGS)
105
+
106
+clean:
107
+	rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
108
+
109
+dist: clean
110
+	mkdir -p dmenu-$(VERSION)
111
+	cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
112
+		drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
113
+		dmenu-$(VERSION)
114
+	tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
115
+	gzip dmenu-$(VERSION).tar
116
+	rm -rf dmenu-$(VERSION)
117
+
118
+install: all
119
+	mkdir -p $(DESTDIR)$(PREFIX)/bin
120
+	cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
121
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
122
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
123
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
124
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
125
+	mkdir -p $(DESTDIR)$(MANPREFIX)/man1
126
+	sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
127
+	sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
128
+	chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
129
+	chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
130
+
131
+uninstall:
132
+	rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
133
+		$(DESTDIR)$(PREFIX)/bin/dmenu_path\
134
+		$(DESTDIR)$(PREFIX)/bin/dmenu_run\
135
+		$(DESTDIR)$(PREFIX)/bin/stest\
136
+		$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
137
+		$(DESTDIR)$(MANPREFIX)/man1/stest.1
138
+
139
+.PHONY: all options clean dist install uninstall
140
diff --git a/PKGBUILD b/PKGBUILD
141
new file mode 100644
142
index 0000000..addbd04
143
--- /dev/null
144
+++ b/PKGBUILD
145
@@ -0,0 +1,44 @@
146
+# Maintainer: Derek Taylor <[email protected]>
147
+pkgname=dmenu-distrotube-git
148
+pkgver=5.0.r28.988f34b
149
+pkgrel=1
150
+epoch=
151
+pkgdesc="A build of dmenu patched for centering, borders, grids, numbers, line height, mouse support, fuzzy matching and highlighting."
152
+arch=(x86_64)
153
+url="https://www.gitlab.com/dwt1/dmenu-distrotube.git"
154
+license=('MIT')
155
+groups=()
156
+depends=(ttf-hack ttf-joypixels)
157
+makedepends=(git)
158
+checkdepends=()
159
+optdepends=()
160
+provides=(dmenu)
161
+conflicts=(dmenu)
162
+replaces=()
163
+backup=()
164
+options=()
165
+install=
166
+changelog=
167
+source=("git+$url")
168
+noextract=()
169
+md5sums=('SKIP')
170
+validpgpkeys=()
171
+
172
+pkgver() {
173
+	cd "${_pkgname}"
174
+    printf "5.0.r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
175
+}
176
+
177
+build() {
178
+	cd dmenu-distrotube
179
+    make X11INC=/usr/include/X11 X11LIB=/usr/lib/X11
180
+}
181
+
182
+package() {
183
+    cd dmenu-distrotube  
184
+    mkdir -p ${pkgdir}/opt/${pkgname}
185
+    cp -rf * ${pkgdir}/opt/${pkgname}
186
+    make PREFIX=/usr DESTDIR="${pkgdir}" install
187
+    install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
188
+    install -Dm644 README.org "${pkgdir}/usr/share/doc/${pkgname}/README.org"
189
+}
190
diff --git a/arg.h b/arg.h
191
new file mode 100644
192
index 0000000..dd4bb03
193
--- /dev/null
194
+++ b/arg.h
195
@@ -0,0 +1,46 @@
196
+
197
+
198
+#ifndef ARG_H__
199
+#define ARG_H__
200
+
201
+extern char *argv0;
202
+
203
+/* use main(int argc, char *argv[]) */
204
+#define ARGBEGIN	for (argv0 = *argv, argv++, argc--;\
205
+					argv[0] && argv[0][0] == '-'\
206
+					&& argv[0][1];\
207
+					argc--, argv++) {\
208
+				char argc_;\
209
+				char **argv_;\
210
+				int brk_;\
211
+				if (argv[0][1] == '-' && argv[0][2] == '\0') {\
212
+					argv++;\
213
+					argc--;\
214
+					break;\
215
+				}\
216
+				for (brk_ = 0, argv[0]++, argv_ = argv;\
217
+						argv[0][0] && !brk_;\
218
+						argv[0]++) {\
219
+					if (argv_ != argv)\
220
+						break;\
221
+					argc_ = argv[0][0];\
222
+					switch (argc_)
223
+
224
+#define ARGEND			}\
225
+			}
226
+
227
+#define ARGC()		argc_
228
+
229
+#define EARGF(x)	((argv[0][1] == '\0' && argv[1] == NULL)?\
230
+				((x), abort(), (char *)0) :\
231
+				(brk_ = 1, (argv[0][1] != '\0')?\
232
+					(&argv[0][1]) :\
233
+					(argc--, argv++, argv[0])))
234
+
235
+#define ARGF()		((argv[0][1] == '\0' && argv[1] == NULL)?\
236
+				(char *)0 :\
237
+				(brk_ = 1, (argv[0][1] != '\0')?\
238
+					(&argv[0][1]) :\
239
+					(argc--, argv++, argv[0])))
240
+
241
+#endif
242
diff --git a/config.h b/config.h
243
new file mode 100644
244
index 0000000..cfa568f
245
--- /dev/null
246
+++ b/config.h
247
@@ -0,0 +1,45 @@
248
+
249
+/*                                           #------------------------------#                                  */
250
+/*                                                    # ## DMENU ## #                                          */
251
+/*                                           #------------------------------#                                  */
252
+
253
+
254
+static int topbar = 1;       /* -b  option; if 0, dmenu appears at bottom                                      */
255
+static int centered = 0;     /* -c option; centers dmenu on screen                                             */
256
+static int min_width = 500;  /* minimum width when centered                                                    */
257
+static int fuzzy = 1;        /* -F  option; if 0, dmenu doesn't use fuzzy matching                             */
258
+
259
+
260
+/* -fn option overrides fonts[0]; default X11 font or font set                                                 */
261
+
262
+static const char *fonts[] = {
263
+	"Hack:pixelsize=11:antialias=true:autohint=true",
264
+	"JoyPixels:pixelsize=8:antialias=true:autohint=true"
265
+};
266
+static const char *prompt      = NULL;      /* -p  option; prompt to the left of input field                   */
267
+static const char *colors[SchemeLast][2] = {
268
+
269
+	[SchemeNorm]          = { "#eee8d5", "#002b36" },
270
+	[SchemeSel]           = { "#ffffff", "#d33682" },
271
+	[SchemeSelHighlight]  = { "#2aa198", "#000000" },
272
+	[SchemeNormHighlight] = { "#2aa198", "#000000" },
273
+	[SchemeOut]           = { "#ffffff", "#268bd2" },
274
+	[SchemeMid]           = { "#eee8d5", "#002b36" },
275
+};
276
+
277
+
278
+/* -l and -g options; controls number of lines and columns in grid if > 0                                       */
279
+
280
+static unsigned int lines      = 0;
281
+static unsigned int lineheight = 22;  /* -h option; minimum height of a menu line                               */
282
+static unsigned int columns    = 0;
283
+
284
+/*  Characters not considered part of a word while deleting words
285
+ *  for example: " /?\"&[]"
286
+                                                                                                                */
287
+static const char worddelimiters[] = " ";
288
+
289
+
290
+/* Size of the window border                                                                                    */
291
+
292
+static unsigned int border_width = 0; /* -bw option; to add border width                                        */
293
diff --git a/config.mk b/config.mk
294
new file mode 100644
295
index 0000000..db908f0
296
--- /dev/null
297
+++ b/config.mk
298
@@ -0,0 +1,31 @@
299
+# dmenu version
300
+VERSION = 5.0
301
+
302
+# paths
303
+PREFIX = /usr
304
+MANPREFIX = $(PREFIX)/share/man
305
+
306
+X11INC = /usr/X11R6/include
307
+X11LIB = /usr/X11R6/lib
308
+
309
+# Xinerama, comment if you don't want it
310
+XINERAMALIBS  = -lXinerama
311
+XINERAMAFLAGS = -DXINERAMA
312
+
313
+# freetype
314
+FREETYPELIBS = -lfontconfig -lXft
315
+FREETYPEINC = /usr/include/freetype2
316
+# OpenBSD (uncomment)
317
+#FREETYPEINC = $(X11INC)/freetype2
318
+
319
+# includes and libs
320
+INCS = -I$(X11INC) -I$(FREETYPEINC)
321
+LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm
322
+
323
+# flags
324
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
325
+CFLAGS   = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
326
+LDFLAGS  = $(LIBS)
327
+
328
+# compiler and linker
329
+CC = cc
330
diff --git a/dmenu-border-4.9.diff b/dmenu-border-4.9.diff
331
new file mode 100644
332
index 0000000..89b4437
333
--- /dev/null
334
+++ b/dmenu-border-4.9.diff
335
@@ -0,0 +1,25 @@
336
+diff -up dmenu-4.9-b/config.def.h dmenu-4.9-a/config.def.h
337
+--- dmenu-4.9-b/config.def.h	2019-02-02 13:55:02.000000000 +0100
338
++++ dmenu-4.9-a/config.def.h	2019-05-19 02:10:12.740040403 +0200
339
+@@ -21,3 +21,6 @@ static unsigned int lines      = 0;
340
+  * for example: " /?\"&[]"
341
+  */
342
+ static const char worddelimiters[] = " ";
343
++
344
++/* Size of the window border */
345
++static const unsigned int border_width = 5;
346
+diff -up dmenu-4.9-b/dmenu.c dmenu-4.9-a/dmenu.c
347
+--- dmenu-4.9-b/dmenu.c	2019-02-02 13:55:02.000000000 +0100
348
++++ dmenu-4.9-a/dmenu.c	2019-05-19 02:11:20.966710117 +0200
349
+@@ -654,9 +654,10 @@ setup(void)
350
+ 	swa.override_redirect = True;
351
+ 	swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
352
+ 	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
353
+-	win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
354
++	win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
355
+ 	                    CopyFromParent, CopyFromParent, CopyFromParent,
356
+ 	                    CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
357
++	XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
358
+ 	XSetClassHint(dpy, win, &ch);
359
+ 
360
+ 	/* open input methods */
361
diff --git a/dmenu-center-20200111-8cd37e1.diff b/dmenu-center-20200111-8cd37e1.diff
362
new file mode 100644
363
index 0000000..af249a6
364
--- /dev/null
365
+++ b/dmenu-center-20200111-8cd37e1.diff
366
@@ -0,0 +1,120 @@
367
+From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001
368
+From: Nihal Jere <[email protected]>
369
+Date: Sat, 11 Jan 2020 21:16:08 -0600
370
+Subject: [PATCH] center patch now has adjustable minimum width
371
+
372
+---
373
+ config.def.h |  2 ++
374
+ dmenu.1      |  3 +++
375
+ dmenu.c      | 39 ++++++++++++++++++++++++++++++++-------
376
+ 3 files changed, 37 insertions(+), 7 deletions(-)
377
+
378
+diff --git a/config.def.h b/config.def.h
379
+index 1edb647..88ef264 100644
380
+--- a/config.def.h
381
++++ b/config.def.h
382
+@@ -2,6 +2,8 @@
383
+ /* Default settings; can be overriden by command line. */
384
+ 
385
+ static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
386
++static int centered = 0;                    /* -c option; centers dmenu on screen */
387
++static int min_width = 500;                    /* minimum width when centered */
388
+ /* -fn option overrides fonts[0]; default X11 font or font set */
389
+ static const char *fonts[] = {
390
+ 	"monospace:size=10"
391
+diff --git a/dmenu.1 b/dmenu.1
392
+index 323f93c..c036baa 100644
393
+--- a/dmenu.1
394
++++ b/dmenu.1
395
+@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
396
+ .B \-b
397
+ dmenu appears at the bottom of the screen.
398
+ .TP
399
++.B \-c
400
++dmenu appears centered on the screen.
401
++.TP
402
+ .B \-f
403
+ dmenu grabs the keyboard before reading stdin if not reading from a tty. This
404
+ is faster, but will lock up X until stdin reaches end\-of\-file.
405
+diff --git a/dmenu.c b/dmenu.c
406
+index 65f25ce..041c7f8 100644
407
+--- a/dmenu.c
408
++++ b/dmenu.c
409
+@@ -89,6 +89,15 @@ calcoffsets(void)
410
+ 			break;
411
+ }
412
+ 
413
++static int
414
++max_textw(void)
415
++{
416
++	int len = 0;
417
++	for (struct item *item = items; item && item->text; item++)
418
++		len = MAX(TEXTW(item->text), len);
419
++	return len;
420
++}
421
++
422
+ static void
423
+ cleanup(void)
424
+ {
425
+@@ -611,6 +620,7 @@ setup(void)
426
+ 	bh = drw->fonts->h + 2;
427
+ 	lines = MAX(lines, 0);
428
+ 	mh = (lines + 1) * bh;
429
++	promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
430
+ #ifdef XINERAMA
431
+ 	i = 0;
432
+ 	if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
433
+@@ -637,9 +647,16 @@ setup(void)
434
+ 				if (INTERSECT(x, y, 1, 1, info[i]))
435
+ 					break;
436
+ 
437
+-		x = info[i].x_org;
438
+-		y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
439
+-		mw = info[i].width;
440
++		if (centered) {
441
++			mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
442
++			x = info[i].x_org + ((info[i].width  - mw) / 2);
443
++			y = info[i].y_org + ((info[i].height - mh) / 2);
444
++		} else {
445
++			x = info[i].x_org;
446
++			y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
447
++			mw = info[i].width;
448
++		}
449
++
450
+ 		XFree(info);
451
+ 	} else
452
+ #endif
453
+@@ -647,11 +664,17 @@ setup(void)
454
+ 		if (!XGetWindowAttributes(dpy, parentwin, &wa))
455
+ 			die("could not get embedding window attributes: 0x%lx",
456
+ 			    parentwin);
457
+-		x = 0;
458
+-		y = topbar ? 0 : wa.height - mh;
459
+-		mw = wa.width;
460
++
461
++		if (centered) {
462
++			mw = MIN(MAX(max_textw() + promptw, min_width), wa.width);
463
++			x = (wa.width  - mw) / 2;
464
++			y = (wa.height - mh) / 2;
465
++		} else {
466
++			x = 0;
467
++			y = topbar ? 0 : wa.height - mh;
468
++			mw = wa.width;
469
++		}
470
+ 	}
471
+-	promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
472
+ 	inputw = MIN(inputw, mw/3);
473
+ 	match();
474
+ 
475
+@@ -709,6 +732,8 @@ main(int argc, char *argv[])
476
+ 			topbar = 0;
477
+ 		else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
478
+ 			fast = 1;
479
++		else if (!strcmp(argv[i], "-c"))   /* centers dmenu on screen */
480
++			centered = 1;
481
+ 		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
482
+ 			fstrncmp = strncasecmp;
483
+ 			fstrstr = cistrstr;
484
+-- 
485
+2.24.1
486
+
487
diff --git a/dmenu-fuzzyhighlight-4.9.diff b/dmenu-fuzzyhighlight-4.9.diff
488
new file mode 100644
489
index 0000000..58d5c6f
490
--- /dev/null
491
+++ b/dmenu-fuzzyhighlight-4.9.diff
492
@@ -0,0 +1,152 @@
493
+Author: Chris Noxz <[email protected]>
494
+note: This patch is meant to be used together with fuzzymatch
495
+
496
+diff -upN dmenu-4.9/config.def.h dmenu-4.9-fuzzyhighlight/config.def.h
497
+--- dmenu-4.9/config.def.h	2019-02-02 13:55:02.000000000 +0100
498
++++ dmenu-4.9-fuzzyhighlight/config.def.h	2020-04-04 10:26:36.990890854 +0200
499
+@@ -11,6 +11,8 @@ static const char *colors[SchemeLast][2]
500
+ 	/*     fg         bg       */
501
+ 	[SchemeNorm] = { "#bbbbbb", "#222222" },
502
+ 	[SchemeSel] = { "#eeeeee", "#005577" },
503
++	[SchemeSelHighlight] = { "#ffc978", "#005577" },
504
++	[SchemeNormHighlight] = { "#ffc978", "#222222" },
505
+ 	[SchemeOut] = { "#000000", "#00ffff" },
506
+ };
507
+ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
508
+diff -upN dmenu-4.9/dmenu.1 dmenu-4.9-fuzzyhighlight/dmenu.1
509
+--- dmenu-4.9/dmenu.1	2019-02-02 13:55:02.000000000 +0100
510
++++ dmenu-4.9-fuzzyhighlight/dmenu.1	2020-04-04 10:30:16.430054933 +0200
511
+@@ -20,6 +20,14 @@ dmenu \- dynamic menu
512
+ .IR color ]
513
+ .RB [ \-sf
514
+ .IR color ]
515
++.RB [ \-nhb
516
++.IR color ]
517
++.RB [ \-nhf
518
++.IR color ]
519
++.RB [ \-shb
520
++.IR color ]
521
++.RB [ \-shf
522
++.IR color ]
523
+ .RB [ \-w
524
+ .IR windowid ]
525
+ .P
526
+@@ -75,6 +83,18 @@ defines the selected background color.
527
+ .BI \-sf " color"
528
+ defines the selected foreground color.
529
+ .TP
530
++.BI \-nhb " color"
531
++defines the normal highlight background color.
532
++.TP
533
++.BI \-nhf " color"
534
++defines the normal highlight foreground color.
535
++.TP
536
++.BI \-shb " color"
537
++defines the selected highlight background color.
538
++.TP
539
++.BI \-shf " color"
540
++defines the selected highlight foreground color.
541
++.TP
542
+ .B \-v
543
+ prints version information to stdout, then exits.
544
+ .TP
545
+diff -upN dmenu-4.9/dmenu.c dmenu-4.9-fuzzyhighlight/dmenu.c
546
+--- dmenu-4.9/dmenu.c	2019-02-02 13:55:02.000000000 +0100
547
++++ dmenu-4.9-fuzzyhighlight/dmenu.c	2020-04-04 10:27:43.888026309 +0200
548
+@@ -26,7 +26,9 @@
549
+ #define TEXTW(X)              (drw_fontset_getwidth(drw, (X)) + lrpad)
550
+ 
551
+ /* enums */
552
+-enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
553
++enum { SchemeNorm, SchemeSel, SchemeNormHighlight, SchemeSelHighlight,
554
++       SchemeOut, SchemeLast }; /* color schemes */
555
++
556
+ 
557
+ struct item {
558
+ 	char *text;
559
+@@ -113,9 +115,49 @@ cistrstr(const char *s, const char *sub)
560
+ 	return NULL;
561
+ }
562
+ 
563
++static void
564
++drawhighlights(struct item *item, int x, int y, int maxw)
565
++{
566
++	int i, indent;
567
++	char *highlight;
568
++	char c;
569
++
570
++	if (!(strlen(item->text) && strlen(text)))
571
++		return;
572
++
573
++	drw_setscheme(drw, scheme[item == sel
574
++	                   ? SchemeSelHighlight
575
++	                   : SchemeNormHighlight]);
576
++	for (i = 0, highlight = item->text; *highlight && text[i];) {
577
++		if (*highlight == text[i]) {
578
++			/* get indentation */
579
++			c = *highlight;
580
++			*highlight = '\0';
581
++			indent = TEXTW(item->text);
582
++			*highlight = c;
583
++
584
++			/* highlight character */
585
++			c = highlight[1];
586
++			highlight[1] = '\0';
587
++			drw_text(
588
++				drw,
589
++				x + indent - (lrpad / 2),
590
++				y,
591
++				MIN(maxw - indent, TEXTW(highlight) - lrpad),
592
++				bh, 0, highlight, 0
593
++			);
594
++			highlight[1] = c;
595
++			i++;
596
++		}
597
++		highlight++;
598
++	}
599
++}
600
++
601
++
602
+ static int
603
+ drawitem(struct item *item, int x, int y, int w)
604
+ {
605
++	int r;
606
+ 	if (item == sel)
607
+ 		drw_setscheme(drw, scheme[SchemeSel]);
608
+ 	else if (item->out)
609
+@@ -123,7 +165,9 @@ drawitem(struct item *item, int x, int y
610
+ 	else
611
+ 		drw_setscheme(drw, scheme[SchemeNorm]);
612
+ 
613
+-	return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
614
++	r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
615
++	drawhighlights(item, x, y, w);
616
++	return r;
617
+ }
618
+ 
619
+ static void
620
+@@ -683,7 +727,8 @@ static void
621
+ usage(void)
622
+ {
623
+ 	fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
624
+-	      "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
625
++	      "             [-nb color] [-nf color] [-sb color] [-sf color]\n"
626
++	      "             [-nhb color] [-nhf color] [-shb color] [-shf color] [-w windowid]\n", stderr);
627
+ 	exit(1);
628
+ }
629
+ 
630
+@@ -724,6 +769,14 @@ main(int argc, char *argv[])
631
+ 			colors[SchemeSel][ColBg] = argv[++i];
632
+ 		else if (!strcmp(argv[i], "-sf"))  /* selected foreground color */
633
+ 			colors[SchemeSel][ColFg] = argv[++i];
634
++		else if (!strcmp(argv[i], "-nhb")) /* normal hi background color */
635
++			colors[SchemeNormHighlight][ColBg] = argv[++i];
636
++		else if (!strcmp(argv[i], "-nhf")) /* normal hi foreground color */
637
++			colors[SchemeNormHighlight][ColFg] = argv[++i];
638
++		else if (!strcmp(argv[i], "-shb")) /* selected hi background color */
639
++			colors[SchemeSelHighlight][ColBg] = argv[++i];
640
++		else if (!strcmp(argv[i], "-shf")) /* selected hi foreground color */
641
++			colors[SchemeSelHighlight][ColFg] = argv[++i];
642
+ 		else if (!strcmp(argv[i], "-w"))   /* embedding window id */
643
+ 			embed = argv[++i];
644
+ 		else
645
diff --git a/dmenu-fuzzymatch-4.9.diff b/dmenu-fuzzymatch-4.9.diff
646
new file mode 100644
647
index 0000000..9fd206d
648
--- /dev/null
649
+++ b/dmenu-fuzzymatch-4.9.diff
650
@@ -0,0 +1,163 @@
651
+From 94353eb52055927d9079f3d9e33da1c954abf386 Mon Sep 17 00:00:00 2001
652
+From: aleks <[email protected]>
653
+Date: Wed, 26 Jun 2019 13:25:10 +0200
654
+Subject: [PATCH] Add support for fuzzy-matching
655
+
656
+---
657
+ config.def.h |  1 +
658
+ config.mk    |  2 +-
659
+ dmenu.c      | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++
660
+ 3 files changed, 91 insertions(+), 1 deletion(-)
661
+
662
+diff --git a/config.def.h b/config.def.h
663
+index 1edb647..51612b9 100644
664
+--- a/config.def.h
665
++++ b/config.def.h
666
+@@ -2,6 +2,7 @@
667
+ /* Default settings; can be overriden by command line. */
668
+ 
669
+ static int topbar = 1;                      /* -b  option; if 0, dmenu appears at bottom     */
670
++static int fuzzy = 1;                      /* -F  option; if 0, dmenu doesn't use fuzzy matching     */
671
+ /* -fn option overrides fonts[0]; default X11 font or font set */
672
+ static const char *fonts[] = {
673
+ 	"monospace:size=10"
674
+diff --git a/config.mk b/config.mk
675
+index 0929b4a..d14309a 100644
676
+--- a/config.mk
677
++++ b/config.mk
678
+@@ -20,7 +20,7 @@ FREETYPEINC = /usr/include/freetype2
679
+ 
680
+ # includes and libs
681
+ INCS = -I$(X11INC) -I$(FREETYPEINC)
682
+-LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
683
++LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm
684
+ 
685
+ # flags
686
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
687
+diff --git a/dmenu.c b/dmenu.c
688
+index 6b8f51b..96ddc98 100644
689
+--- a/dmenu.c
690
++++ b/dmenu.c
691
+@@ -1,6 +1,7 @@
692
+ /* See LICENSE file for copyright and license details. */
693
+ #include <ctype.h>
694
+ #include <locale.h>
695
++#include <math.h>
696
+ #include <stdio.h>
697
+ #include <stdlib.h>
698
+ #include <string.h>
699
+@@ -32,6 +33,7 @@ struct item {
700
+ 	char *text;
701
+ 	struct item *left, *right;
702
+ 	int out;
703
++	double distance;
704
+ };
705
+ 
706
+ static char text[BUFSIZ] = "";
707
+@@ -210,9 +212,94 @@ grabkeyboard(void)
708
+ 	die("cannot grab keyboard");
709
+ }
710
+ 
711
++int
712
++compare_distance(const void *a, const void *b)
713
++{
714
++	struct item *da = *(struct item **) a;
715
++	struct item *db = *(struct item **) b;
716
++
717
++	if (!db)
718
++		return 1;
719
++	if (!da)
720
++		return -1;
721
++
722
++	return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1;
723
++}
724
++
725
++void
726
++fuzzymatch(void)
727
++{
728
++	/* bang - we have so much memory */
729
++	struct item *it;
730
++	struct item **fuzzymatches = NULL;
731
++	char c;
732
++	int number_of_matches = 0, i, pidx, sidx, eidx;
733
++	int text_len = strlen(text), itext_len;
734
++
735
++	matches = matchend = NULL;
736
++
737
++	/* walk through all items */
738
++	for (it = items; it && it->text; it++) {
739
++		if (text_len) {
740
++			itext_len = strlen(it->text);
741
++			pidx = 0; /* pointer */
742
++			sidx = eidx = -1; /* start of match, end of match */
743
++			/* walk through item text */
744
++			for (i = 0; i < itext_len && (c = it->text[i]); i++) {
745
++				/* fuzzy match pattern */
746
++				if (!fstrncmp(&text[pidx], &c, 1)) {
747
++					if(sidx == -1)
748
++						sidx = i;
749
++					pidx++;
750
++					if (pidx == text_len) {
751
++						eidx = i;
752
++						break;
753
++					}
754
++				}
755
++			}
756
++			/* build list of matches */
757
++			if (eidx != -1) {
758
++				/* compute distance */
759
++				/* add penalty if match starts late (log(sidx+2))
760
++				 * add penalty for long a match without many matching characters */
761
++				it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len);
762
++				/* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */
763
++				appenditem(it, &matches, &matchend);
764
++				number_of_matches++;
765
++			}
766
++		} else {
767
++			appenditem(it, &matches, &matchend);
768
++		}
769
++	}
770
++
771
++	if (number_of_matches) {
772
++		/* initialize array with matches */
773
++		if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*))))
774
++			die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*));
775
++		for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) {
776
++			fuzzymatches[i] = it;
777
++		}
778
++		/* sort matches according to distance */
779
++		qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
780
++		/* rebuild list of matches */
781
++		matches = matchend = NULL;
782
++		for (i = 0, it = fuzzymatches[i];  i < number_of_matches && it && \
783
++				it->text; i++, it = fuzzymatches[i]) {
784
++			appenditem(it, &matches, &matchend);
785
++		}
786
++		free(fuzzymatches);
787
++	}
788
++	curr = sel = matches;
789
++	calcoffsets();
790
++}
791
++
792
+ static void
793
+ match(void)
794
+ {
795
++	if (fuzzy) {
796
++		fuzzymatch();
797
++		return;
798
++	}
799
+ 	static char **tokv = NULL;
800
+ 	static int tokn = 0;
801
+ 
802
+@@ -702,6 +789,8 @@ main(int argc, char *argv[])
803
+ 			topbar = 0;
804
+ 		else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
805
+ 			fast = 1;
806
++		else if (!strcmp(argv[i], "-F"))   /* grabs keyboard before reading stdin */
807
++			fuzzy = 0;
808
+ 		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
809
+ 			fstrncmp = strncasecmp;
810
+ 			fstrstr = cistrstr;
811
+-- 
812
+2.22.0
813
+
814
diff --git a/dmenu-grid-4.9.diff b/dmenu-grid-4.9.diff
815
new file mode 100644
816
index 0000000..c27689b
817
--- /dev/null
818
+++ b/dmenu-grid-4.9.diff
819
@@ -0,0 +1,107 @@
820
+From 39ab9676914bd0d8105d0f96bbd7611a53077438 Mon Sep 17 00:00:00 2001
821
+From: Miles Alan <[email protected]>
822
+Date: Sat, 4 Jul 2020 11:19:04 -0500
823
+Subject: [PATCH] Add -g option to display entries in the given number of grid
824
+ columns
825
+
826
+This option can be used in conjunction with -l to format dmenu's options in
827
+arbitrary size grids. For example, to create a 4 column by 6 line grid, you
828
+could use: dmenu -g 4 -l 6
829
+---
830
+ config.def.h |  3 ++-
831
+ dmenu.1      |  7 ++++++-
832
+ dmenu.c      | 22 ++++++++++++++++------
833
+ 3 files changed, 24 insertions(+), 8 deletions(-)
834
+
835
+diff --git a/config.def.h b/config.def.h
836
+index 1edb647..96cf3c9 100644
837
+--- a/config.def.h
838
++++ b/config.def.h
839
+@@ -13,8 +13,9 @@ static const char *colors[SchemeLast][2] = {
840
+ 	[SchemeSel] = { "#eeeeee", "#005577" },
841
+ 	[SchemeOut] = { "#000000", "#00ffff" },
842
+ };
843
+-/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
844
++/* -l and -g options; controls number of lines and columns in grid if > 0 */
845
+ static unsigned int lines      = 0;
846
++static unsigned int columns    = 0;
847
+ 
848
+ /*
849
+  * Characters not considered part of a word while deleting words
850
+diff --git a/dmenu.1 b/dmenu.1
851
+index 323f93c..d0a734a 100644
852
+--- a/dmenu.1
853
++++ b/dmenu.1
854
+@@ -4,6 +4,8 @@ dmenu \- dynamic menu
855
+ .SH SYNOPSIS
856
+ .B dmenu
857
+ .RB [ \-bfiv ]
858
++.RB [ \-g
859
++.IR columns ]
860
+ .RB [ \-l
861
+ .IR lines ]
862
+ .RB [ \-m
863
+@@ -47,8 +49,11 @@ is faster, but will lock up X until stdin reaches end\-of\-file.
864
+ .B \-i
865
+ dmenu matches menu items case insensitively.
866
+ .TP
867
++.BI \-g " columns"
868
++dmenu lists items in a grid with the given number of columns.
869
++.TP
870
+ .BI \-l " lines"
871
+-dmenu lists items vertically, with the given number of lines.
872
++dmenu lists items in a grid with the given number of lines.
873
+ .TP
874
+ .BI \-m " monitor"
875
+ dmenu is displayed on the monitor number supplied. Monitor numbers are starting
876
+diff --git a/dmenu.c b/dmenu.c
877
+index 6b8f51b..d79b6bb 100644
878
+--- a/dmenu.c
879
++++ b/dmenu.c
880
+@@ -77,7 +77,7 @@ calcoffsets(void)
881
+ 	int i, n;
882
+ 
883
+ 	if (lines > 0)
884
+-		n = lines * bh;
885
++		n = lines * columns * bh;
886
+ 	else
887
+ 		n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
888
+ 	/* calculate which items will begin the next page and previous page */
889
+@@ -152,9 +152,15 @@ drawmenu(void)
890
+ 	}
891
+ 
892
+ 	if (lines > 0) {
893
+-		/* draw vertical list */
894
+-		for (item = curr; item != next; item = item->right)
895
+-			drawitem(item, x, y += bh, mw - x);
896
++		/* draw grid */
897
++		int i = 0;
898
++		for (item = curr; item != next; item = item->right, i++)
899
++			drawitem(
900
++				item,
901
++				x + ((i / lines) *  ((mw - x) / columns)),
902
++				y + (((i % lines) + 1) * bh),
903
++				(mw - x) / columns
904
++			);
905
+ 	} else if (matches) {
906
+ 		/* draw horizontal list */
907
+ 		x += inputw;
908
+@@ -708,9 +714,13 @@ main(int argc, char *argv[])
909
+ 		} else if (i + 1 == argc)
910
+ 			usage();
911
+ 		/* these options take one argument */
912
+-		else if (!strcmp(argv[i], "-l"))   /* number of lines in vertical list */
913
++		else if (!strcmp(argv[i], "-g")) {   /* number of columns in grid */
914
++			columns = atoi(argv[++i]);
915
++			if (lines == 0) lines = 1;
916
++		} else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */
917
+ 			lines = atoi(argv[++i]);
918
+-		else if (!strcmp(argv[i], "-m"))
919
++			if (columns == 0) columns = 1;
920
++		} else if (!strcmp(argv[i], "-m"))
921
+ 			mon = atoi(argv[++i]);
922
+ 		else if (!strcmp(argv[i], "-p"))   /* adds prompt to left of input field */
923
+ 			prompt = argv[++i];
924
+-- 
925
+2.23.1
926
+
927
diff --git a/dmenu-lineheight-4.9.diff b/dmenu-lineheight-4.9.diff
928
new file mode 100644
929
index 0000000..d12c77a
930
--- /dev/null
931
+++ b/dmenu-lineheight-4.9.diff
932
@@ -0,0 +1,94 @@
933
+From 87f92a561c31246f6f9effc0e89ef92677c87746 Mon Sep 17 00:00:00 2001
934
+From: astier <[email protected]>
935
+Date: Wed, 27 Feb 2019 21:44:55 +0100
936
+Subject: [PATCH] Add an option which defines the lineheight
937
+
938
+Despite both the panel and dmenu using the same font (a Terminus 12),
939
+dmenu is shorter and the panel is visible from under the dmenu bar.
940
+The appearance can be even more distracting when using similar colors
941
+for background and selections. With the option added by this patch,
942
+dmenu can be launched with a '-h 24', thus completely covering the panel.
943
+---
944
+ config.def.h |  1 +
945
+ dmenu.1      |  3 +++
946
+ dmenu.c      | 10 ++++++++--
947
+ 3 files changed, 12 insertions(+), 2 deletions(-)
948
+
949
+diff --git a/config.def.h b/config.def.h
950
+index 1edb647..317fa2f 100644
951
+--- a/config.def.h
952
++++ b/config.def.h
953
+@@ -15,6 +15,7 @@ static const char *colors[SchemeLast][2] = {
954
+ };
955
+ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
956
+ static unsigned int lines      = 0;
957
++static unsigned int lineheight = 0;         /* -h option; minimum height of a menu line     */
958
+ 
959
+ /*
960
+  * Characters not considered part of a word while deleting words
961
+diff --git a/dmenu.1 b/dmenu.1
962
+index 323f93c..7ef34d2 100644
963
+--- a/dmenu.1
964
++++ b/dmenu.1
965
+@@ -50,6 +50,9 @@ dmenu matches menu items case insensitively.
966
+ .BI \-l " lines"
967
+ dmenu lists items vertically, with the given number of lines.
968
+ .TP
969
++.BI \-h " height"
970
++dmenu uses a menu line of at least 'height' pixels tall, but no less than 8.
971
++.TP
972
+ .BI \-m " monitor"
973
+ dmenu is displayed on the monitor number supplied. Monitor numbers are starting
974
+ from 0.
975
+diff --git a/dmenu.c b/dmenu.c
976
+index 6b8f51b..45d1946 100644
977
+--- a/dmenu.c
978
++++ b/dmenu.c
979
+@@ -131,7 +131,7 @@ drawmenu(void)
980
+ {
981
+ 	unsigned int curpos;
982
+ 	struct item *item;
983
+-	int x = 0, y = 0, w;
984
++	int x = 0, y = 0, fh = drw->fonts->h, w;
985
+ 
986
+ 	drw_setscheme(drw, scheme[SchemeNorm]);
987
+ 	drw_rect(drw, 0, 0, mw, mh, 1, 1);
988
+@@ -148,7 +148,7 @@ drawmenu(void)
989
+ 	curpos = TEXTW(text) - TEXTW(&text[cursor]);
990
+ 	if ((curpos += lrpad / 2 - 1) < w) {
991
+ 		drw_setscheme(drw, scheme[SchemeNorm]);
992
+-		drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
993
++		drw_rect(drw, x + curpos, 2 + (bh-fh)/2, 2, fh - 4, 1, 0);
994
+ 	}
995
+ 
996
+ 	if (lines > 0) {
997
+@@ -604,6 +604,7 @@ setup(void)
998
+ 
999
+ 	/* calculate menu geometry */