Compare commits

..

No commits in common. "8dfee8f81b57d5802e4ab1067b09ce036c415728" and "f84f1080d8eaec5a34bb21a342484d0ed941c54f" have entirely different histories.

6 changed files with 95 additions and 117 deletions

View File

@ -1,11 +1,9 @@
# Maintainer: Jef Roosens
pkgname=jjr-dmenu
pkgver=5.3
pkgname="jjr-dmenu"
pkgver="5.2"
pkgrel=1
pkgdesc="Chewing_Bever's custom build of Suckless's dmenu."
url="https://git.rustybever.be/Chewing_Bever/dmenu"
arch=(
"x86_64"
"x86_64_tigerlake"
@ -13,10 +11,11 @@ arch=(
"aarch64"
)
url="https://git.rustybever.be/Chewing_Bever/dmenu"
license=("MIT")
depends=("glibc" "libxinerama" "libxft" "fontconfig" "freetype2")
makedepends=("gcc")
depends=("libxinerama" "libxft" "fontconfig" "freetype2")
makedepends=("glibc" "gcc")
provides=("dmenu")
conflicts=("dmenu-git")
@ -25,19 +24,19 @@ source=("arg.h" "config.h" "config.mk" "dmenu.1" "dmenu.c" "dmenu_path.sh"
"stest.c" "util.c" "util.h")
sha256sums=('9ed2b2e3396fdebc8ecab2cdbb09db115cca015f63ec0443b8ccc56340b6b03c'
'9ae33f74aed02823abb8381e553d38455541ce3b6a0d642282b693992e71caef'
'5a6066f1cf97aaee4792708893faa1f16fad39d4dce22c79ccfb7590349fe0cc'
'f6de4c72dab3b9bef214bd52e6a7dff22e87a3118abaffd26ec1ae589cf68b3f'
'9f749419697381a1db77e9b23cb41629808fd7e451d475c9b5ee0e88bee803f6'
'dc93fd213531f01c968ec073382d4c91c14a3fb2464e1a62e23e94653a74fb81'
'5b2a53db7ba608d392efaa96be5530665b46107dc4e0ee1a864745a6e8a8587d'
'a3f19e648e20eb80532dfe87e9bd9feeaa92df838e6ecc061f274c9da579d617'
'564035fd8a8ade6504521d98fa10e8732e135403d546d04ca77316fe4a67b21c'
'8c9f81b98f447440cf59dd3eefda99eec4e7733266ad0c072612163ccff4e1df'
'7ed1cf72bfcb0f5444f338293aef74c455ce4ed5463f171a48358f64d7835d49'
'a7c7358ce13c8571044b79d5d91d01314d9174793474a27faa37d23c75ab603f'
'c35796210ea8410ae096025cc0d7996dccb3d9936306dff7531a0bb253e079f5'
'9f8e922fcfc18ffcc4975dd0b1bee38302bd4e0c538251dfef6d77cd7ed59c89'
'c32b5173eddf376296af085725cb878e4ca2603d4fda8bba3faac6a2bb1b4390'
'ec98e8759049af796598f0790752a21a69eaea1d438b09c39922d4a9f4a7cfe2'
'00d3389ef8858a565cf3fb3445620b90eb67d1a9b31434f4d54b05ed6c5abefb'
'ba76404e61abbd734e315999ffe4e883419c4c69ff17a5d4d88a5cd11dd4b055'
'1c093b9969daaf3e1a001b924c6c2da3770993916b444dfe65fe39aa0090aa1a'
'dec870d0b5834c9008ff62f495710daf524cffdf12d0cf8ba4fadf5643623987'
'1196a7b6efbf4cb3f5c435fffd72e7647f977483845d5c78c1c48d9ab8b96819')
build() {
@ -57,5 +56,3 @@ package() {
# install $installopts "$docdir" README.terminfo.rst
# install $installopts "$shrdir/$pkgname" "$_sourcedir/st.info"
}
# vim: ft=bash

View File

@ -1,5 +1,5 @@
# dmenu version
VERSION = 5.3
VERSION = 5.2
# paths
PREFIX = /usr/local
@ -17,7 +17,6 @@ FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = $(X11INC)/freetype2
#MANPREFIX = ${PREFIX}/man
# includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC)

56
dmenu.c
View File

@ -61,13 +61,6 @@ static char * cistrstr(const char *s, const char *sub);
static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
static char *(*fstrstr)(const char *, const char *) = cistrstr;
static unsigned int
textw_clamp(const char *str, unsigned int n)
{
unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad;
return MIN(w, n);
}
static void
appenditem(struct item *item, struct item **list, struct item **last)
{
@ -92,10 +85,10 @@ calcoffsets(void)
n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
/* calculate which items will begin the next page and previous page */
for (i = 0, next = curr; next; next = next->right)
if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n)
if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
break;
for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n)
if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
break;
}
@ -107,9 +100,6 @@ cleanup(void)
XUngrabKey(dpy, AnyKey, AnyModifier, root);
for (i = 0; i < SchemeLast; i++)
free(scheme[i]);
for (i = 0; items && items[i].text; ++i)
free(items[i].text);
free(items);
drw_free(drw);
XSync(dpy, False);
XCloseDisplay(dpy);
@ -185,7 +175,7 @@ drawmenu(void)
}
x += w;
for (item = curr; item != next; item = item->right)
x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">")));
x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">")));
if (next) {
w = TEXTW(">");
drw_setscheme(drw, scheme[SchemeNorm]);
@ -330,7 +320,7 @@ match(void)
/* separate input text into tokens to be matched individually */
for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
die("cannot realloc %zu bytes:", tokn * sizeof *tokv);
die("cannot realloc %u bytes:", tokn * sizeof *tokv);
len = tokc ? strlen(tokv[0]) : 0;
matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
@ -503,7 +493,7 @@ keypress(XKeyEvent *ev)
switch(ksym) {
default:
insert:
if (!iscntrl((unsigned char)*buf))
if (!iscntrl(*buf))
insert(buf, len);
break;
case XK_Delete:
@ -605,9 +595,9 @@ insert:
case XK_Tab:
if (!sel)
return;
cursor = strnlen(sel->text, sizeof text - 1);
memcpy(text, sel->text, cursor);
text[cursor] = '\0';
strncpy(text, sel->text, sizeof text - 1);
text[sizeof text - 1] = '\0';
cursor = strlen(text);
match();
break;
}
@ -637,22 +627,29 @@ paste(void)
static void
readstdin(void)
{
char *line = NULL;
size_t i, junk, size = 0;
ssize_t len;
char buf[sizeof text], *p;
size_t i, imax = 0, size = 0;
unsigned int tmpmax = 0;
/* read each line from stdin and add it to the item list */
for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++, line = NULL) {
for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
if (i + 1 >= size / sizeof *items)
if (!(items = realloc(items, (size += BUFSIZ))))
die("cannot realloc %zu bytes:", size);
if (line[len - 1] == '\n')
line[len - 1] = '\0';
items[i].text = line;
die("cannot realloc %u bytes:", size);
if ((p = strchr(buf, '\n')))
*p = '\0';
if (!(items[i].text = strdup(buf)))
die("cannot strdup %u bytes:", strlen(buf) + 1);
items[i].out = 0;
drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
if (tmpmax > inputw) {
inputw = tmpmax;
imax = i;
}
}
if (items)
items[i].text = NULL;
inputw = items ? TEXTW(items[imax].text) : 0;
lines = MIN(lines, i);
}
@ -761,7 +758,7 @@ setup(void)
mw = wa.width;
}
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
inputw = mw / 3; /* input width: ~33% of monitor width */
inputw = MIN(inputw, mw/3);
match();
/* create menu window */
@ -798,8 +795,9 @@ setup(void)
static void
usage(void)
{
die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]");
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
exit(1);
}
int

106
drw.c
View File

@ -133,6 +133,19 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
die("no font specified.");
}
/* Do not allow using color fonts. This is a workaround for a BadLength
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
* https://lists.suckless.org/dev/1701/30932.html
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
* and lots more all over the internet.
*/
FcBool iscol;
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
XftFontClose(drw->dpy, xfont);
return NULL;
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
@ -238,10 +251,12 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
int
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;
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
char buf[1024];
int ty;
unsigned int ew;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
size_t i, len;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
@ -249,17 +264,13 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0, overflow = 0;
/* keep track of a couple codepoints for which we have no match. */
enum { nomatches_len = 64 };
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
static unsigned int ellipsis_width = 0;
int charexists = 0;
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
return 0;
if (!render) {
w = invert ? invert : ~invert;
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
@ -271,10 +282,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
}
usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, "...");
while (1) {
ew = ellipsis_len = utf8strlen = 0;
utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
@ -282,27 +291,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
if (ew + ellipsis_width <= w) {
/* keep track where the ellipsis still fits */
ellipsis_x = x + ew;
ellipsis_w = w - ew;
ellipsis_len = utf8strlen;
}
if (ew + tmpw > w) {
overflow = 1;
/* called from drw_fontset_getwidth_clamp():
* it wants the width AFTER the overflow
*/
if (!render)
x += tmpw;
else
utf8strlen = ellipsis_len;
} else if (curfont == usedfont) {
if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
ew += tmpw;
} else {
nextfont = curfont;
}
@ -310,25 +301,36 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
}
}
if (overflow || !charexists || nextfont)
if (!charexists || nextfont)
break;
else
charexists = 0;
}
if (utf8strlen) {
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
}
x += ew;
w -= ew;
}
if (render && overflow)
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
/* shorten text if necessary */
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
if (!*text || overflow) {
if (len) {
memcpy(buf, utf8str, len);
buf[len] = '\0';
if (len < utf8strlen)
for (i = len; i && i > len - 3; buf[--i] = '.')
; /* NOP */
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
}
x += ew;
w -= ew;
}
}
if (!*text) {
break;
} else if (nextfont) {
charexists = 0;
@ -338,12 +340,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
* character must be drawn. */
charexists = 1;
for (i = 0; i < nomatches_len; ++i) {
/* avoid calling XftFontMatch if we know we won't find a match */
if (utf8codepoint == nomatches.codepoint[i])
goto no_match;
}
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
@ -355,6 +351,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
@ -371,8 +368,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
curfont->next = usedfont;
} else {
xfont_free(usedfont);
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
no_match:
usedfont = drw->fonts;
}
}
@ -402,15 +397,6 @@ drw_fontset_getwidth(Drw *drw, const char *text)
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
unsigned int
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
{
unsigned int tmp = 0;
if (drw && drw->fonts && text && n)
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
return MIN(n, tmp);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{

1
drw.h
View File

@ -35,7 +35,6 @@ void drw_free(Drw *drw);
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */

23
util.c
View File

@ -6,9 +6,18 @@
#include "util.h"
void
die(const char *fmt, ...)
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}
void
die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
@ -24,13 +33,3 @@ die(const char *fmt, ...)
exit(1);
}
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}