updated dmenu and patched xresources

This commit is contained in:
mrsu 2024-06-15 23:10:51 +01:00
parent deb38655db
commit aaa18d5eb6
9 changed files with 297 additions and 34 deletions

View File

@ -6,13 +6,7 @@ include config.mk
SRC = drw.c dmenu.c stest.c util.c SRC = drw.c dmenu.c stest.c util.c
OBJ = $(SRC:.c=.o) OBJ = $(SRC:.c=.o)
all: options dmenu stest all: dmenu stest
options:
@echo dmenu build options:
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
.c.o: .c.o:
$(CC) -c $(CFLAGS) $< $(CC) -c $(CFLAGS) $<
@ -61,4 +55,4 @@ uninstall:
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
$(DESTDIR)$(MANPREFIX)/man1/stest.1 $(DESTDIR)$(MANPREFIX)/man1/stest.1
.PHONY: all options clean dist install uninstall .PHONY: all clean dist install uninstall

View File

@ -3,16 +3,24 @@
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ 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 */ 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 */ /* -fn option overrides fonts[0]; default X11 font or font set */
static char font[] = "monospace:size=10";
static const char *fonts[] = { static const char *fonts[] = {
"monospace:size=14", font,
"NotoColorEmoji:pixelsize=48:antialias=true:autohint=true" "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 *prompt = NULL; /* -p option; prompt to the left of input field */
static char normfgcolor[] = "#bbbbbb";
static char normbgcolor[] = "#222222";
static char selfgcolor[] = "#eeeeee";
static char selbgcolor[] = "#005577";
static char *colors[SchemeLast][2] = {
/* fg bg */ /* fg bg */
[SchemeNorm] = { "#ebdbb2", "#282828" }, [SchemeNorm] = { normfgcolor, normbgcolor },
[SchemeSel] = { "#ffffff", "#005577" }, [SchemeSel] = { selfgcolor, selbgcolor },
[SchemeOut] = { "#000000", "#00ffff" }, [SchemeOut] = { "#000000", "#00ffff" },
}; };
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
@ -23,3 +31,15 @@ static unsigned int lines = 0;
* for example: " /?\"&[]" * for example: " /?\"&[]"
*/ */
static const char worddelimiters[] = " "; static const char worddelimiters[] = " ";
/*
* Xresources preferences to load at startup
*/
ResourcePref resources[] = {
{ "font", STRING, &font },
{ "normfgcolor", STRING, &normfgcolor },
{ "normbgcolor", STRING, &normbgcolor },
{ "selfgcolor", STRING, &selfgcolor },
{ "selbgcolor", STRING, &selbgcolor },
{ "prompt", STRING, &prompt },
};

View File

@ -1,5 +1,5 @@
# dmenu version # dmenu version
VERSION = 5.2 VERSION = 5.3
# paths # paths
PREFIX = /usr/local PREFIX = /usr/local

75
dmenu.c
View File

@ -12,6 +12,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/Xresource.h>
#ifdef XINERAMA #ifdef XINERAMA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif #endif
@ -23,7 +24,6 @@
/* macros */ /* macros */
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ #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) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */ /* enums */
@ -55,6 +55,21 @@ static XIC xic;
static Drw *drw; static Drw *drw;
static Clr *scheme[SchemeLast]; static Clr *scheme[SchemeLast];
/* Xresources preferences */
enum resource_type {
STRING = 0,
INTEGER = 1,
FLOAT = 2
};
typedef struct {
char *name;
enum resource_type type;
void *dst;
} ResourcePref;
static void load_xresources(void);
static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
#include "config.h" #include "config.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@ -501,7 +516,7 @@ keypress(XKeyEvent *ev)
switch(ksym) { switch(ksym) {
default: default:
insert: insert:
if (!iscntrl((unsigned char)*buf)) if (!iscntrl((unsigned char)*buf))
insert(buf, len); insert(buf, len);
break; break;
@ -660,6 +675,54 @@ readstdin(void)
lines = MIN(lines, i); lines = MIN(lines, i);
} }
void
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
{
char *sdst = NULL;
int *idst = NULL;
float *fdst = NULL;
sdst = dst;
idst = dst;
fdst = dst;
char fullname[256];
char *type;
XrmValue ret;
snprintf(fullname, sizeof(fullname), "%s.%s", "dmenu", name);
fullname[sizeof(fullname) - 1] = '\0';
XrmGetResource(db, fullname, "*", &type, &ret);
if (!(ret.addr == NULL || strncmp("String", type, 64)))
{
switch (rtype) {
case STRING:
strcpy(sdst, ret.addr);
break;
case INTEGER:
*idst = strtoul(ret.addr, NULL, 10);
break;
case FLOAT:
*fdst = strtof(ret.addr, NULL);
break;
}
}
}
void
load_xresources(void)
{
Display *display;
char *resm;
XrmDatabase db;
ResourcePref *p;
display = XOpenDisplay(NULL);
resm = XResourceManagerString(display);
if (!resm)
return;
db = XrmGetStringDatabase(resm);
for (p = resources; p < resources + LENGTH(resources); p++)
resource_load(db, p->name, p->type, p->dst);
XCloseDisplay(display);
}
static void static void
run(void) run(void)
{ {
@ -803,9 +866,8 @@ setup(void)
static void static void
usage(void) usage(void)
{ {
die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor] [-it text]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]");
" [-it text]\n");
} }
int int
@ -814,6 +876,9 @@ main(int argc, char *argv[])
XWindowAttributes wa; XWindowAttributes wa;
int i, fast = 0; int i, fast = 0;
XrmInitialize();
load_xresources();
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
/* these options take no arguments */ /* these options take no arguments */
if (!strcmp(argv[i], "-v")) { /* prints version information */ if (!strcmp(argv[i], "-v")) { /* prints version information */

23
drw.c
View File

@ -195,7 +195,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
/* Wrapper to create color schemes. The caller has to call free(3) on the /* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */ * returned color scheme when done using it. */
Clr * Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
{ {
size_t i; size_t i;
Clr *ret; Clr *ret;
@ -238,8 +238,8 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
int int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{ {
int i, ty, ellipsis_x = 0; int ty, ellipsis_x = 0;
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
XftDraw *d = NULL; XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont; Fnt *usedfont, *curfont, *nextfont;
int utf8strlen, utf8charlen, render = x || y || w || h; int utf8strlen, utf8charlen, render = x || y || w || h;
@ -251,9 +251,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
XftResult result; XftResult result;
int charexists = 0, overflow = 0; int charexists = 0, overflow = 0;
/* keep track of a couple codepoints for which we have no match. */ /* keep track of a couple codepoints for which we have no match. */
enum { nomatches_len = 64 }; static unsigned int nomatches[128], ellipsis_width;
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
static unsigned int ellipsis_width = 0;
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
return 0; return 0;
@ -338,11 +336,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
* character must be drawn. */ * character must be drawn. */
charexists = 1; charexists = 1;
for (i = 0; i < nomatches_len; ++i) { hash = (unsigned int)utf8codepoint;
/* avoid calling XftFontMatch if we know we won't find a match */ hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
if (utf8codepoint == nomatches.codepoint[i]) hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
h1 = (hash >> 17) % LENGTH(nomatches);
/* avoid expensive XftFontMatch call when we know we won't find a match */
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
goto no_match; goto no_match;
}
fccharset = FcCharSetCreate(); fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint); FcCharSetAddChar(fccharset, utf8codepoint);
@ -371,7 +372,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
curfont->next = usedfont; curfont->next = usedfont;
} else { } else {
xfont_free(usedfont); xfont_free(usedfont);
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
no_match: no_match:
usedfont = drw->fonts; usedfont = drw->fonts;
} }

2
drw.h
View File

@ -40,7 +40,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
/* Colorscheme abstraction */ /* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
/* Cursor abstraction */ /* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape); Cur *drw_cur_create(Drw *drw, int shape);

View File

@ -0,0 +1,182 @@
diff -rupN orig/config.def.h patched/config.def.h
--- orig/config.def.h 2021-04-16 06:30:47.713924755 +0300
+++ patched/config.def.h 2021-04-16 06:34:14.956933252 +0300
@@ -2,16 +2,25 @@
/* 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 font[] = "monospace:size=10";
static const char *fonts[] = {
- "monospace:size=10"
+ font,
+ "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 *prompt = NULL; /* -p option; prompt to the left of input field */
+
+static char normfgcolor[] = "#bbbbbb";
+static char normbgcolor[] = "#222222";
+static char selfgcolor[] = "#eeeeee";
+static char selbgcolor[] = "#005577";
+static char *colors[SchemeLast][2] = {
/* fg bg */
- [SchemeNorm] = { "#bbbbbb", "#222222" },
- [SchemeSel] = { "#eeeeee", "#005577" },
- [SchemeOut] = { "#000000", "#00ffff" },
+ [SchemeNorm] = { normfgcolor, normbgcolor },
+ [SchemeSel] = { selfgcolor, selbgcolor },
+ [SchemeOut] = { "#000000", "#00ffff" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
@@ -21,3 +30,15 @@ static unsigned int lines = 0;
* for example: " /?\"&[]"
*/
static const char worddelimiters[] = " ";
+
+/*
+ * Xresources preferences to load at startup
+ */
+ResourcePref resources[] = {
+ { "font", STRING, &font },
+ { "normfgcolor", STRING, &normfgcolor },
+ { "normbgcolor", STRING, &normbgcolor },
+ { "selfgcolor", STRING, &selfgcolor },
+ { "selbgcolor", STRING, &selbgcolor },
+ { "prompt", STRING, &prompt },
+};
diff -rupN orig/dmenu.c patched/dmenu.c
--- orig/dmenu.c 2021-04-16 06:30:47.715924755 +0300
+++ patched/dmenu.c 2021-04-16 06:30:59.668925245 +0300
@@ -11,6 +11,7 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
+#include <X11/Xresource.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
@@ -53,6 +54,21 @@ static XIC xic;
static Drw *drw;
static Clr *scheme[SchemeLast];
+/* Xresources preferences */
+enum resource_type {
+ STRING = 0,
+ INTEGER = 1,
+ FLOAT = 2
+};
+typedef struct {
+ char *name;
+ enum resource_type type;
+ void *dst;
+} ResourcePref;
+
+static void load_xresources(void);
+static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
+
#include "config.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@@ -395,7 +411,7 @@ keypress(XKeyEvent *ev)
switch(ksym) {
default:
-insert:
+ insert:
if (!iscntrl(*buf))
insert(buf, len);
break;
@@ -547,6 +563,54 @@ readstdin(void)
lines = MIN(lines, i);
}
+void
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
+{
+ char *sdst = NULL;
+ int *idst = NULL;
+ float *fdst = NULL;
+ sdst = dst;
+ idst = dst;
+ fdst = dst;
+ char fullname[256];
+ char *type;
+ XrmValue ret;
+ snprintf(fullname, sizeof(fullname), "%s.%s", "dmenu", name);
+ fullname[sizeof(fullname) - 1] = '\0';
+ XrmGetResource(db, fullname, "*", &type, &ret);
+ if (!(ret.addr == NULL || strncmp("String", type, 64)))
+ {
+ switch (rtype) {
+ case STRING:
+ strcpy(sdst, ret.addr);
+ break;
+ case INTEGER:
+ *idst = strtoul(ret.addr, NULL, 10);
+ break;
+ case FLOAT:
+ *fdst = strtof(ret.addr, NULL);
+ break;
+ }
+ }
+}
+
+void
+load_xresources(void)
+{
+ Display *display;
+ char *resm;
+ XrmDatabase db;
+ ResourcePref *p;
+ display = XOpenDisplay(NULL);
+ resm = XResourceManagerString(display);
+ if (!resm)
+ return;
+ db = XrmGetStringDatabase(resm);
+ for (p = resources; p < resources + LENGTH(resources); p++)
+ resource_load(db, p->name, p->type, p->dst);
+ XCloseDisplay(display);
+}
+
static void
run(void)
{
@@ -700,6 +764,9 @@ main(int argc, char *argv[])
XWindowAttributes wa;
int i, fast = 0;
+ XrmInitialize();
+ load_xresources();
+
for (i = 1; i < argc; i++)
/* these options take no arguments */
if (!strcmp(argv[i], "-v")) { /* prints version information */
diff -rupN orig/drw.c patched/drw.c
--- orig/drw.c 2021-04-16 06:30:47.718924755 +0300
+++ patched/drw.c 2021-04-16 06:30:59.670925245 +0300
@@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, cons
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
diff -rupN orig/drw.h patched/drw.h
--- orig/drw.h 2021-04-16 06:30:47.718924755 +0300
+++ patched/drw.h 2021-04-16 06:30:59.671925245 +0300
@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const c
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);

BIN
stest Executable file

Binary file not shown.

1
util.h
View File

@ -3,6 +3,7 @@
#define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
void die(const char *fmt, ...); void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size); void *ecalloc(size_t nmemb, size_t size);