summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzachir <zachir@librem.one>2021-08-25 10:34:19 -0500
committerzachir <zachir@librem.one>2021-08-25 10:34:19 -0500
commitf84336a06d7c660ec8864bd04ac2138ff3a54dbc (patch)
treee2bb43361372b79348cbeb59696462f58bf34768
parentbedcf8c2fb2237e08da4136f3c0a9ee69c461c73 (diff)
dmenu: add ZIR patch for dmenu-5.0
-rw-r--r--dmenu-zir-5.0.diff347
1 files changed, 347 insertions, 0 deletions
diff --git a/dmenu-zir-5.0.diff b/dmenu-zir-5.0.diff
new file mode 100644
index 0000000..351140e
--- /dev/null
+++ b/dmenu-zir-5.0.diff
@@ -0,0 +1,347 @@
+diff --git a/config.def.h b/config.def.h
+index 1edb647..2140b85 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,18 +3,21 @@
+
+ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
+ /* -fn option overrides fonts[0]; default X11 font or font set */
+-static const char *fonts[] = {
++static char *fonts[] = {
+ "monospace:size=10"
+ };
+ static const char *prompt = NULL; /* -p option; prompt to the left of input field */
+-static const char *colors[SchemeLast][2] = {
++static char *colors[SchemeLast][2] = {
+ /* fg bg */
+ [SchemeNorm] = { "#bbbbbb", "#222222" },
+ [SchemeSel] = { "#eeeeee", "#005577" },
++ [SchemeSelHighlight] = { "#ffc978", "#005577" },
++ [SchemeNormHighlight] = { "#ffc978", "#222222" },
+ [SchemeOut] = { "#000000", "#00ffff" },
+ };
+ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
+ static unsigned int lines = 0;
++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/config.h b/config.h
+new file mode 100644
+index 0000000..8bd9346
+--- /dev/null
++++ b/config.h
+@@ -0,0 +1,27 @@
++/* See LICENSE file for copyright and license details. */
++/* Default settings; can be overriden by command line. */
++
++static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
++/* -fn option overrides fonts[0]; default X11 font or font set */
++static char *fonts[] = {
++ "mononoki Nerd Font Mono:size=10",
++ "JoyPixels:size=10"
++};
++static const char *prompt = NULL; /* -p option; prompt to the left of input field */
++static char *colors[SchemeLast][2] = {
++ /* fg bg */
++ [SchemeNorm] = { "#bbbbbb", "#222222" },
++ [SchemeSel] = { "#eeeeee", "#005577" },
++ [SchemeSelHighlight] = { "#ffc978", "#005577" },
++ [SchemeNormHighlight] = { "#ffc978", "#222222" },
++ [SchemeOut] = { "#000000", "#ff0000" },
++};
++/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
++static unsigned int lines = 0;
++static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */
++
++/*
++ * Characters not considered part of a word while deleting words
++ * for example: " /?\"&[]"
++ */
++static const char worddelimiters[] = " ";
+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 65f25ce..9a1f14b 100644
+--- a/dmenu.c
++++ b/dmenu.c
+@@ -15,18 +15,19 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif
+ #include <X11/Xft/Xft.h>
++#include <X11/Xresource.h>
+
+ #include "drw.h"
+ #include "util.h"
+
+ /* macros */
+ #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
+- * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
++ && MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
+ #define LENGTH(X) (sizeof X / sizeof X[0])
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+
+ /* enums */
+-enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
++enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */
+
+ struct item {
+ char *text;
+@@ -53,6 +54,10 @@ static XIC xic;
+ static Drw *drw;
+ static Clr *scheme[SchemeLast];
+
++/* Temporary arrays to allow overriding xresources values */
++static char *colortemp[4];
++static char *tempfonts;
++
+ #include "config.h"
+
+ static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
+@@ -113,6 +118,42 @@ cistrstr(const char *s, const char *sub)
+ return NULL;
+ }
+
++static void
++drawhighlights(struct item *item, int x, int y, int maxw)
++{
++ char restorechar, tokens[sizeof text], *highlight, *token;
++ int indentx, highlightlen;
++
++ drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]);
++ strcpy(tokens, text);
++ for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) {
++ highlight = fstrstr(item->text, token);
++ while (highlight) {
++ // Move item str end, calc width for highlight indent, & restore
++ highlightlen = highlight - item->text;
++ restorechar = *highlight;
++ item->text[highlightlen] = '\0';
++ indentx = TEXTW(item->text);
++ item->text[highlightlen] = restorechar;
++
++ // Move highlight str end, draw highlight, & restore
++ restorechar = highlight[strlen(token)];
++ highlight[strlen(token)] = '\0';
++ drw_text(
++ drw,
++ x + indentx - (lrpad / 2) - 1,
++ y,
++ MIN(maxw - indentx, TEXTW(highlight) - lrpad),
++ bh, 0, highlight, 0
++ );
++ highlight[strlen(token)] = restorechar;
++
++ if (strlen(highlight) - strlen(token) < strlen(token)) break;
++ highlight = fstrstr(highlight + strlen(token), token);
++ }
++ }
++}
++
+ static int
+ drawitem(struct item *item, int x, int y, int w)
+ {
+@@ -123,7 +164,9 @@ drawitem(struct item *item, int x, int y, int w)
+ else
+ drw_setscheme(drw, scheme[SchemeNorm]);
+
+- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
++ int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
++ drawhighlights(item, x, y, w);
++ return r;
+ }
+
+ static void
+@@ -131,7 +174,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 +191,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) {
+@@ -556,11 +599,11 @@ run(void)
+ if (XFilterEvent(&ev, win))
+ continue;
+ switch(ev.type) {
+- case DestroyNotify:
+- if (ev.xdestroywindow.window != win)
+- break;
+- cleanup();
+- exit(1);
++ case DestroyNotify:
++ if (ev.xdestroywindow.window != win)
++ break;
++ cleanup();
++ exit(1);
+ case Expose:
+ if (ev.xexpose.count == 0)
+ drw_map(drw, win, 0, 0, mw, mh);
+@@ -601,14 +644,20 @@ setup(void)
+ int a, di, n, area = 0;
+ #endif
+ /* init appearance */
+- for (j = 0; j < SchemeLast; j++)
+- scheme[j] = drw_scm_create(drw, colors[j], 2);
++ for (j = 0; j < SchemeLast; j++) {
++ scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2);
++ }
++ for (j = 0; j < SchemeOut; ++j) {
++ for (i = 0; i < 2; ++i)
++ free(colors[j][i]);
++ }
+
+ clip = XInternAtom(dpy, "CLIPBOARD", False);
+ utf8 = XInternAtom(dpy, "UTF8_STRING", False);
+
+ /* calculate menu geometry */
+ bh = drw->fonts->h + 2;
++ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */
+ lines = MAX(lines, 0);
+ mh = (lines + 1) * bh;
+ #ifdef XINERAMA
+@@ -664,10 +713,9 @@ setup(void)
+ CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
+ XSetClassHint(dpy, win, &ch);
+
+-
+ /* input methods */
+- if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
+- die("XOpenIM failed: could not open input device");
++ if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
++ die("XOpenIM failed: could not open input device");
+
+ xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow, win, XNFocusWindow, win, NULL);
+@@ -690,10 +738,46 @@ static void
+ usage(void)
+ {
+ fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
++ " [-h height]\n"
+ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
+ exit(1);
+ }
+
++void
++readxresources(void) {
++ XrmInitialize();
++
++ char* xrm;
++ if ((xrm = XResourceManagerString(drw->dpy))) {
++ char *type;
++ XrmDatabase xdb = XrmGetStringDatabase(xrm);
++ XrmValue xval;
++
++ if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval))
++ fonts[0] = strdup(xval.addr);
++ else
++ fonts[0] = strdup(fonts[0]);
++ if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval))
++ colors[SchemeNorm][ColBg] = strdup(xval.addr);
++ else
++ colors[SchemeNorm][ColBg] = strdup(colors[SchemeNorm][ColBg]);
++ if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval))
++ colors[SchemeNorm][ColFg] = strdup(xval.addr);
++ else
++ colors[SchemeNorm][ColFg] = strdup(colors[SchemeNorm][ColFg]);
++ if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval))
++ colors[SchemeSel][ColBg] = strdup(xval.addr);
++ else
++ colors[SchemeSel][ColBg] = strdup(colors[SchemeSel][ColBg]);
++ if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval))
++ colors[SchemeSel][ColFg] = strdup(xval.addr);
++ else
++ colors[SchemeSel][ColFg] = strdup(colors[SchemeSel][ColFg]);
++
++ XrmDestroyDatabase(xdb);
++ }
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -722,15 +806,19 @@ main(int argc, char *argv[])
+ 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 */
+- fonts[0] = argv[++i];
++ tempfonts = 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];
++ colortemp[0] = argv[++i];
+ else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
+- colors[SchemeNorm][ColFg] = argv[++i];
++ colortemp[1] = argv[++i];
+ else if (!strcmp(argv[i], "-sb")) /* selected background color */
+- colors[SchemeSel][ColBg] = argv[++i];
++ colortemp[2]= argv[++i];
+ else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
+- colors[SchemeSel][ColFg] = argv[++i];
++ colortemp[3]= argv[++i];
+ else if (!strcmp(argv[i], "-w")) /* embedding window id */
+ embed = argv[++i];
+ else
+@@ -748,8 +836,23 @@ main(int argc, char *argv[])
+ die("could not get embedding window attributes: 0x%lx",
+ parentwin);
+ drw = drw_create(dpy, screen, root, wa.width, wa.height);
+- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
++ readxresources();
++ /* Now we check whether to override xresources with commandline parameters */
++ if ( tempfonts )
++ fonts[0] = strdup(tempfonts);
++ if ( colortemp[0])
++ colors[SchemeNorm][ColBg] = strdup(colortemp[0]);
++ if ( colortemp[1])
++ colors[SchemeNorm][ColFg] = strdup(colortemp[1]);
++ if ( colortemp[2])
++ colors[SchemeSel][ColBg] = strdup(colortemp[2]);
++ if ( colortemp[3])
++ colors[SchemeSel][ColFg] = strdup(colortemp[3]);
++
++ if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts)))
+ die("no fonts could be loaded.");
++
++ free(fonts[0]);
+ lrpad = drw->fonts->h;
+
+ #ifdef __OpenBSD__
+diff --git a/drw.c b/drw.c
+index 4cdbcbe..6927c41 100644
+--- a/drw.c
++++ b/drw.c
+@@ -95,7 +95,7 @@ drw_free(Drw *drw)
+ {
+ XFreePixmap(drw->dpy, drw->drawable);
+ XFreeGC(drw->dpy, drw->gc);
+- drw_fontset_free(drw->fonts);
++ drw_fontset_free(drw->fonts);
+ free(drw);
+ }
+