sites

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 2c7c5d85c957b4955b858c6fb55800d91d555187
parent c037d3558f41bd9be7c97056cb89ffcc801eabcf
Author: nzl <uruabi@gmail.com>
Date:   Sat, 24 Feb 2018 01:14:43 +0800

[dmenu][PATCH] Add patch that implements text scrolling

Diffstat:
Atools.suckless.org/dmenu/patches/dmenu-scroll-20180224-8895128.diff | 262+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/dmenu/patches/scroll.md | 14++++++++++++++
2 files changed, 276 insertions(+), 0 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/dmenu-scroll-20180224-8895128.diff b/tools.suckless.org/dmenu/patches/dmenu-scroll-20180224-8895128.diff @@ -0,0 +1,262 @@ +From f424638a4a81ae24ec68eed2f1376b19354cac55 Mon Sep 17 00:00:00 2001 +From: nzl <uruabi@gmail.com> +Date: Sat, 24 Feb 2018 00:31:00 +0800 +Subject: [PATCH] Implement text scrolling + +a new function drw_text_align is added, it is different from drw_text in that +it doesn't append '...' for long text, and it allows drawing text right +justified. +--- + dmenu.c | 24 ++++++--- + drw.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + drw.h | 2 + + 3 files changed, 188 insertions(+), 7 deletions(-) + +diff --git a/dmenu.c b/dmenu.c +index a246111..bc5e732 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -128,9 +128,11 @@ drawitem(struct item *item, int x, int y, int w) + static void + drawmenu(void) + { +- unsigned int curpos; ++ static int curpos, oldcurlen; + struct item *item; + int x = 0, y = 0, w; ++ int curlen; ++ char ch; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); +@@ -142,13 +144,21 @@ drawmenu(void) + /* draw input field */ + w = (lines > 0 || !matches) ? mw - x : inputw; + drw_setscheme(drw, scheme[SchemeNorm]); +- drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); ++ w -= lrpad / 2; ++ x += lrpad / 2; + +- drw_font_getexts(drw->fonts, text, cursor, &curpos, NULL); +- if ((curpos += lrpad / 2 - 1) < w) { +- drw_setscheme(drw, scheme[SchemeNorm]); +- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); +- } ++ ch = text[cursor]; ++ text[cursor] = '\0'; ++ curlen = drw_fontset_getwidth(drw, text); ++ text[cursor] = ch; ++ curpos += curlen - oldcurlen; ++ curpos = curpos - 1 >= w ? w : (curpos < 0 ? 0 : curpos); ++ oldcurlen = curlen; ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ drw_text_align(drw, x, 0, curpos, bh, text, cursor, AlignR); ++ drw_text_align(drw, x + curpos, 0, w - curpos, bh, text + cursor, strlen(text) - cursor, AlignL); ++ drw_rect(drw, x + curpos - 1, 2, 2, bh - 4, 1, 0); + + if (lines > 0) { + /* draw vertical list */ +diff --git a/drw.c b/drw.c +index c638323..bfffbc1 100644 +--- a/drw.c ++++ b/drw.c +@@ -364,6 +364,175 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp + return x + (render ? w : 0); + } + ++int ++utf8nextchar(const char *str, int len, int i, int inc) ++{ ++ int n; ++ ++ for (n = i + inc; n + inc >= 0 && n + inc <= len ++ && (str[n] & 0xc0) == 0x80; n += inc) ++ ; ++ return n; ++} ++ ++int ++drw_text_align(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int textlen, int align) ++{ ++ int ty; ++ unsigned int ew; ++ XftDraw *d = NULL; ++ Fnt *usedfont, *curfont, *nextfont; ++ size_t len; ++ int utf8strlen, utf8charlen, render = x || y || w || h; ++ long utf8codepoint = 0; ++ const char *utf8str; ++ FcCharSet *fccharset; ++ FcPattern *fcpattern; ++ FcPattern *match; ++ XftResult result; ++ int charexists = 0; ++ int i, n; ++ ++ if (!drw || (render && !drw->scheme) || !text || !drw->fonts || textlen <= 0 ++ || (align != AlignL && align != AlignR)) ++ return 0; ++ ++ if (!render) { ++ w = ~w; ++ } else { ++ XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel); ++ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); ++ d = XftDrawCreate(drw->dpy, drw->drawable, ++ DefaultVisual(drw->dpy, drw->screen), ++ DefaultColormap(drw->dpy, drw->screen)); ++ } ++ ++ usedfont = drw->fonts; ++ i = align == AlignL ? 0 : textlen; ++ x = align == AlignL ? x : x + w; ++ while (1) { ++ utf8strlen = 0; ++ nextfont = NULL; ++ /* if (align == AlignL) */ ++ utf8str = text + i; ++ ++ while ((align == AlignL && i < textlen) || (align == AlignR && i > 0)) { ++ if (align == AlignL) { ++ utf8charlen = utf8decode(text + i, &utf8codepoint, MIN(textlen - i, UTF_SIZ)); ++ if (!utf8charlen) { ++ textlen = i; ++ break; ++ } ++ } else { ++ n = utf8nextchar(text, textlen, i, -1); ++ utf8charlen = utf8decode(text + n, &utf8codepoint, MIN(textlen - n, UTF_SIZ)); ++ if (!utf8charlen) { ++ textlen -= i; ++ text += i; ++ i = 0; ++ break; ++ } ++ } ++ for (curfont = drw->fonts; curfont; curfont = curfont->next) { ++ charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); ++ if (charexists) { ++ if (curfont == usedfont) { ++ utf8strlen += utf8charlen; ++ i += align == AlignL ? utf8charlen : -utf8charlen; ++ } else { ++ nextfont = curfont; ++ } ++ break; ++ } ++ } ++ ++ if (!charexists || nextfont) ++ break; ++ else ++ charexists = 0; ++ } ++ ++ if (align == AlignR) ++ utf8str = text + i; ++ ++ if (utf8strlen) { ++ drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); ++ /* shorten text if necessary */ ++ if (align == AlignL) { ++ for (len = utf8strlen; len && ew > w; ) { ++ len = utf8nextchar(utf8str, len, len, -1); ++ drw_font_getexts(usedfont, utf8str, len, &ew, NULL); ++ } ++ } else { ++ for (len = utf8strlen; len && ew > w; ) { ++ n = utf8nextchar(utf8str, len, 0, +1); ++ utf8str += n; ++ len -= n; ++ drw_font_getexts(usedfont, utf8str, len, &ew, NULL); ++ } ++ } ++ ++ if (len) { ++ if (render) { ++ ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; ++ XftDrawStringUtf8(d, &drw->scheme[ColFg], ++ usedfont->xfont, align == AlignL ? x : x - ew, ty, (XftChar8 *)utf8str, len); ++ } ++ x += align == AlignL ? ew : -ew; ++ w -= ew; ++ } ++ if (len < utf8strlen) ++ break; ++ } ++ ++ if ((align == AlignR && i <= 0) || (align == AlignL && i >= textlen)) { ++ break; ++ } else if (nextfont) { ++ charexists = 0; ++ usedfont = nextfont; ++ } else { ++ /* Regardless of whether or not a fallback font is found, the ++ * character must be drawn. */ ++ charexists = 1; ++ ++ fccharset = FcCharSetCreate(); ++ FcCharSetAddChar(fccharset, utf8codepoint); ++ ++ if (!drw->fonts->pattern) { ++ /* Refer to the comment in xfont_create for more information. */ ++ die("the first font in the cache must be loaded from a font string."); ++ } ++ ++ fcpattern = FcPatternDuplicate(drw->fonts->pattern); ++ FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); ++ FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); ++ ++ FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); ++ FcDefaultSubstitute(fcpattern); ++ match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); ++ ++ FcCharSetDestroy(fccharset); ++ FcPatternDestroy(fcpattern); ++ ++ if (match) { ++ usedfont = xfont_create(drw, NULL, match); ++ if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { ++ for (curfont = drw->fonts; curfont->next; curfont = curfont->next) ++ ; /* NOP */ ++ curfont->next = usedfont; ++ } else { ++ xfont_free(usedfont); ++ usedfont = drw->fonts; ++ } ++ } ++ } ++ } ++ if (d) ++ XftDrawDestroy(d); ++ ++ return x; ++} ++ + void + drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) + { +diff --git a/drw.h b/drw.h +index 4c67419..b66a83e 100644 +--- a/drw.h ++++ b/drw.h +@@ -13,6 +13,7 @@ typedef struct Fnt { + } Fnt; + + enum { ColFg, ColBg }; /* Clr scheme index */ ++enum { AlignL, AlignR }; + typedef XftColor Clr; + + typedef struct { +@@ -52,6 +53,7 @@ void drw_setscheme(Drw *drw, Clr *scm); + /* Drawing functions */ + void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); + int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); ++int drw_text_align(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int textlen, int align); + + /* Map functions */ + void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); +-- +2.15.1 + diff --git a/tools.suckless.org/dmenu/patches/scroll.md b/tools.suckless.org/dmenu/patches/scroll.md @@ -0,0 +1,14 @@ +Text Scrolling +============ + +This patch adds support for text scrolling, it doesn't append '...' for long +input anymore as it can handle long text now. It's especially useful when using +in surf, after having inserted a long url via tab-completion. + +Download +-------- +* [dmenu-scroll-20180224-8895128.diff](dmenu-scroll-20180224-8895128.diff) + +Author +------ +* nzl <uruabi@gmail.com>