Skip to content

Commit 8d2c9ca

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents ce18c01 + e81f17d commit 8d2c9ca

7 files changed

Lines changed: 174 additions & 124 deletions

File tree

LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ MIT/X Consortium License
1717
© 2015-2016 Quentin Rameau <quinq@fifth.space>
1818
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
1919
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
20+
© 2020-2022 Chris Down <chris@chrisdown.name>
2021

2122
Permission is hereby granted, free of charge, to any person obtaining a
2223
copy of this software and associated documentation files (the "Software"),

config.def.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static const char *termcmd[] = { "tabbed", "-r", "2", "st", "-w", "''", "-e", N
126126
static const char scratchpadname[] = "scratchpad";
127127
static const char *scratchpadcmd[] = { "st", "-t", scratchpadname, "-g", "120x34", NULL };
128128

129-
static Key keys[] = {
129+
static const Key keys[] = {
130130
/* modifier key function argument */
131131
{ MODKEY|ShiftMask, XK_Return, togglescratch, {.v = scratchpadcmd } },
132132
{ MODKEY, XK_b, togglebar, {0} },
@@ -205,7 +205,7 @@ static const int scrollargs[][2] = {
205205

206206
/* button definitions */
207207
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
208-
static Button buttons[] = {
208+
static const Button buttons[] = {
209209
/* click event mask button function argument */
210210
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
211211
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },

config.mk

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# dwm version
2-
VERSION = 6.3
2+
VERSION = 6.4
33

44
# Customize below to fit your system
55

@@ -19,13 +19,14 @@ FREETYPELIBS = -lfontconfig -lXft
1919
FREETYPEINC = /usr/include/freetype2
2020
# OpenBSD (uncomment)
2121
#FREETYPEINC = ${X11INC}/freetype2
22+
#MANPREFIX = ${PREFIX}/man
2223

2324
# includes and libs
2425
INCS = -I${X11INC} -I${FREETYPEINC}
2526
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
2627

2728
# flags
28-
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
29+
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
2930
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
3031
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
3132
LDFLAGS = ${LIBS}

drw.c

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -240,26 +240,28 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
240240
int
241241
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
242242
{
243-
char buf[1024];
244-
int ty;
245-
unsigned int ew;
243+
int i, ty, ellipsis_x = 0;
244+
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
246245
XftDraw *d = NULL;
247246
Fnt *usedfont, *curfont, *nextfont;
248-
size_t i, len;
249247
int utf8strlen, utf8charlen, render = x || y || w || h;
250248
long utf8codepoint = 0;
251249
const char *utf8str;
252250
FcCharSet *fccharset;
253251
FcPattern *fcpattern;
254252
FcPattern *match;
255253
XftResult result;
256-
int charexists = 0;
254+
int charexists = 0, overflow = 0;
255+
/* keep track of a couple codepoints for which we have no match. */
256+
enum { nomatches_len = 64 };
257+
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
258+
static unsigned int ellipsis_width = 0;
257259

258-
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
260+
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
259261
return 0;
260262

261263
if (!render) {
262-
w = ~w;
264+
w = invert ? invert : ~invert;
263265
} else {
264266
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
265267
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
@@ -271,55 +273,64 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
271273
}
272274

273275
usedfont = drw->fonts;
276+
if (!ellipsis_width && render)
277+
ellipsis_width = drw_fontset_getwidth(drw, "...");
274278
while (1) {
275-
utf8strlen = 0;
279+
ew = ellipsis_len = utf8strlen = 0;
276280
utf8str = text;
277281
nextfont = NULL;
278282
while (*text) {
279283
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
280284
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
281285
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
282286
if (charexists) {
283-
if (curfont == usedfont) {
287+
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
288+
if (ew + ellipsis_width <= w) {
289+
/* keep track where the ellipsis still fits */
290+
ellipsis_x = x + ew;
291+
ellipsis_w = w - ew;
292+
ellipsis_len = utf8strlen;
293+
}
294+
295+
if (ew + tmpw > w) {
296+
overflow = 1;
297+
/* called from drw_fontset_getwidth_clamp():
298+
* it wants the width AFTER the overflow
299+
*/
300+
if (!render)
301+
x += tmpw;
302+
else
303+
utf8strlen = ellipsis_len;
304+
} else if (curfont == usedfont) {
284305
utf8strlen += utf8charlen;
285306
text += utf8charlen;
307+
ew += tmpw;
286308
} else {
287309
nextfont = curfont;
288310
}
289311
break;
290312
}
291313
}
292314

293-
if (!charexists || nextfont)
315+
if (overflow || !charexists || nextfont)
294316
break;
295317
else
296318
charexists = 0;
297319
}
298320

299321
if (utf8strlen) {
300-
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
301-
/* shorten text if necessary */
302-
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
303-
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
304-
305-
if (len) {
306-
memcpy(buf, utf8str, len);
307-
buf[len] = '\0';
308-
if (len < utf8strlen)
309-
for (i = len; i && i > len - 3; buf[--i] = '.')
310-
; /* NOP */
311-
312-
if (render) {
313-
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
314-
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
315-
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
316-
}
317-
x += ew;
318-
w -= ew;
322+
if (render) {
323+
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
324+
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
325+
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
319326
}
327+
x += ew;
328+
w -= ew;
320329
}
330+
if (render && overflow)
331+
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
321332

322-
if (!*text) {
333+
if (!*text || overflow) {
323334
break;
324335
} else if (nextfont) {
325336
charexists = 0;
@@ -329,6 +340,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
329340
* character must be drawn. */
330341
charexists = 1;
331342

343+
for (i = 0; i < nomatches_len; ++i) {
344+
/* avoid calling XftFontMatch if we know we won't find a match */
345+
if (utf8codepoint == nomatches.codepoint[i])
346+
goto no_match;
347+
}
348+
332349
fccharset = FcCharSetCreate();
333350
FcCharSetAddChar(fccharset, utf8codepoint);
334351

@@ -340,7 +357,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
340357
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
341358
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
342359
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
343-
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
344360

345361
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
346362
FcDefaultSubstitute(fcpattern);
@@ -357,6 +373,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
357373
curfont->next = usedfont;
358374
} else {
359375
xfont_free(usedfont);
376+
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
377+
no_match:
360378
usedfont = drw->fonts;
361379
}
362380
}
@@ -386,6 +404,15 @@ drw_fontset_getwidth(Drw *drw, const char *text)
386404
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
387405
}
388406

407+
unsigned int
408+
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
409+
{
410+
unsigned int tmp = 0;
411+
if (drw && drw->fonts && text && n)
412+
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
413+
return MIN(n, tmp);
414+
}
415+
389416
void
390417
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
391418
{

drw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void drw_free(Drw *drw);
3535
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
3636
void drw_fontset_free(Fnt* set);
3737
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
38+
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
3839
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
3940

4041
/* Colorscheme abstraction */

0 commit comments

Comments
 (0)