From 8d1c9ab37821fe51e17ccf34a8e0ec126f97fb47 Mon Sep 17 00:00:00 2001 From: justsaumit Date: Wed, 2 Mar 2022 07:46:02 +0530 Subject: new patches --- patches/7.dmenu-textscroll-20180607-a314412.diff | 245 +++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 patches/7.dmenu-textscroll-20180607-a314412.diff (limited to 'patches/7.dmenu-textscroll-20180607-a314412.diff') diff --git a/patches/7.dmenu-textscroll-20180607-a314412.diff b/patches/7.dmenu-textscroll-20180607-a314412.diff new file mode 100644 index 0000000..7a7386a --- /dev/null +++ b/patches/7.dmenu-textscroll-20180607-a314412.diff @@ -0,0 +1,245 @@ +diff --git a/dmenu.c b/dmenu.c +index 5c835dd..71efe52 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -131,9 +131,10 @@ 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, rcurlen; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); +@@ -144,14 +145,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; + +- curpos = TEXTW(text) - TEXTW(&text[cursor]); +- if ((curpos += lrpad / 2 - 1) < w) { +- drw_setscheme(drw, scheme[SchemeNorm]); +- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); +- } ++ rcurlen = drw_fontset_getwidth(drw, text + cursor); ++ curlen = drw_fontset_getwidth(drw, text) - rcurlen; ++ curpos += curlen - oldcurlen; ++ curpos = MIN(w, MAX(0, curpos)); ++ curpos = MAX(curpos, w - rcurlen); ++ curpos = MIN(curpos, curlen); ++ 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); -- cgit v1.2.3