From 9406e7ea7cd9f17dda087543cab7992c40787e5e Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 27 Jun 2024 15:54:08 +0000 Subject: [PATCH] statusbar: print ellipsis when text is truncated (#501) currently, there's no feedback on when the statusbar text is getting truncated due to insufficient space. this prints an ellipsis if the text wouldn't be able to fit inside the given width to indicate truncation. Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/501 Reviewed-by: eylles --- window.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/window.c b/window.c index 3c8b3f0..42c3f2b 100644 --- a/window.c +++ b/window.c @@ -67,6 +67,11 @@ static struct { #if HAVE_LIBFONTS static XftFont *font; static double fontsize; +/* utf8 ellipsis "…". the buffer must be at least 4 bytes for utf8_decode() */ +enum { ELLIPSIS_LEN = 3 }; +static const unsigned char ellipsis[4] = { 0xe2, 0x80, 0xa6, 0x0 }; +static int ellipsis_w; +static int win_draw_text(win_t *, XftDraw *, const XftColor *, int, int, char *, int, int); #endif #if HAVE_LIBFONTS @@ -156,6 +161,7 @@ void win_init(win_t *win) f = win_res(db, BAR_FONT[0], BAR_FONT[1] ? BAR_FONT[1] : "monospace-8"); win_init_font(e, f); + ellipsis_w = TEXTWIDTH(win, (char *)ellipsis, ELLIPSIS_LEN); win->bar.l.buf = lbuf; win->bar.r.buf = rbuf; @@ -410,7 +416,7 @@ void win_clear(win_t *win) static int win_draw_text(win_t *win, XftDraw *d, const XftColor *color, int x, int y, char *text, int len, int w) { - int err, tw = 0, warned = 0; + int err, tw = 0, warned = 0, danger_zone = w - ellipsis_w; char *t, *next; uint32_t rune; XftFont *f; @@ -437,6 +443,21 @@ static int win_draw_text(win_t *win, XftDraw *d, const XftColor *color, FcCharSetDestroy(fccharset); } XftTextExtentsUtf8(win->env.dpy, f, (XftChar8 *)t, next - t, &ext); + if (d != NULL && tw + ext.xOff >= danger_zone) { + int remaining_width = TEXTWIDTH(win, t, (text + len) - t); + if (tw + remaining_width > w) { /* overflow, print ellipsis */ + if (tw + ellipsis_w <= w) { + win_draw_text(win, d, color, x, y, (char *)ellipsis, + ELLIPSIS_LEN, ellipsis_w); + tw += ellipsis_w; + } + if (f != font) + XftFontClose(win->env.dpy, f); + return tw; + } + /* text will fit, no need to check again on next iterations */ + danger_zone = INT_MAX; + } tw += ext.xOff; if (tw <= w) { XftDrawStringUtf8(d, color, f, x, y, (XftChar8 *)t, next - t);