sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 2c84f85f6d1d2bc440d527eadda8c355f1dab6d5
parent bd6c86c9e4a51bc456d152e4e99fe5553ac863b4
Author: memeplex <carlosjosepita@gmail.com>
Date:   Thu,  9 Jan 2014 15:30:22 -0300

Pango patch update: markup & cleanup.

Diffstat:
Mdwm.suckless.org/patches/dwm-6.0-pango.diff | 183++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mdwm.suckless.org/patches/pango.md | 42++++++++++++++++++++++++++----------------
2 files changed, 137 insertions(+), 88 deletions(-)

diff --git a/dwm.suckless.org/patches/dwm-6.0-pango.diff b/dwm.suckless.org/patches/dwm-6.0-pango.diff @@ -1,47 +1,54 @@ diff --git a/config.def.h b/config.def.h -index 77ff358..4c266bb 100644 +index 77ff358..3bee2e7 100644 --- a/config.def.h +++ b/config.def.h @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ - + /* appearance */ -static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; +static const char font[] = "Sans 8"; static const char normbordercolor[] = "#444444"; static const char normbgcolor[] = "#222222"; static const char normfgcolor[] = "#bbbbbb"; +@@ -12,6 +12,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ + static const Bool showbar = True; /* False means no bar */ + static const Bool topbar = True; /* False means bottom bar */ ++static const Bool statusmarkup = True; /* True means use pango markup in status message */ + + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; diff --git a/config.mk b/config.mk index 484554a..cdfb642 100644 --- a/config.mk +++ b/config.mk @@ -15,8 +15,8 @@ XINERAMALIBS = -L${X11LIB} -lXinerama XINERAMAFLAGS = -DXINERAMA - + # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} +INCS = -I. -I/usr/include -I${X11INC} `pkg-config --cflags xft pango pangoxft` +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} `pkg-config --libs xft pango pangoxft` - + # flags CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} diff --git a/dwm.c b/dwm.c -index 1d78655..d441ba2 100644 +index 1d78655..4e73727 100644 --- a/dwm.c +++ b/dwm.c -@@ -36,6 +36,10 @@ +@@ -36,6 +36,9 @@ #include <X11/Xlib.h> #include <X11/Xproto.h> #include <X11/Xutil.h> +#include <X11/Xft/Xft.h> +#include <pango/pango.h> +#include <pango/pangoxft.h> -+#include <pango/pango-font.h> #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif /* XINERAMA */ -@@ -47,8 +51,12 @@ +@@ -47,8 +50,12 @@ * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) @@ -54,35 +61,50 @@ index 1d78655..d441ba2 100644 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define WIDTH(X) ((X)->w + 2 * (X)->bw) #define HEIGHT(X) ((X)->h + 2 * (X)->bw) -@@ -103,12 +111,16 @@ typedef struct { - unsigned long sel[ColLast]; +@@ -104,11 +111,15 @@ typedef struct { Drawable drawable; GC gc; -+ XftColor xftnorm[ColLast]; -+ XftColor xftsel[ColLast]; -+ XftDraw *xftdrawable; struct { ++ XftColor norm[ColLast]; ++ XftColor sel[ColLast]; ++ XftDraw *drawable; ++ } xft; ++ struct { int ascent; int descent; int height; - XFontSet set; - XFontStruct *xfont; -+ PangoContext *pgc; -+ PangoLayout *plo; -+ PangoFontDescription *pfd; ++ PangoLayout *layout; } font; } DC; /* draw context */ - -@@ -186,7 +198,7 @@ static void focus(Client *c); + +@@ -186,7 +197,7 @@ static void focus(Client *c); static void focusin(XEvent *e); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); -static unsigned long getcolor(const char *colstr); -+//static unsigned long getcolor(const char *colstr); ++static unsigned long getcolor(const char *colstr, XftColor *color); static Bool getrootptr(int *x, int *y); static long getstate(Window w); static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); -@@ -485,10 +497,6 @@ cleanup(void) { +@@ -254,7 +265,7 @@ static void zoom(const Arg *arg); + + /* variables */ + static const char broken[] = "broken"; +-static char stext[256]; ++static char stext[512]; + static int screen; + static int sw, sh; /* X display screen geometry width, height */ + static int bh, blw = 0; /* bar geometry */ +@@ -479,18 +490,21 @@ cleanup(void) { + Arg a = {.ui = ~0}; + Layout foo = { "", NULL }; + Monitor *m; ++ int i; + + view(&a); + selmon->lt[selmon->sellt] = &foo; for(m = mons; m; m = m->next) while(m->stack) unmanage(m->stack, False); @@ -92,66 +114,80 @@ index 1d78655..d441ba2 100644 - XFreeFont(dpy, dc.font.xfont); XUngrabKey(dpy, AnyKey, AnyModifier, root); XFreePixmap(dpy, dc.drawable); ++ for(i = ColBorder; i < ColLast; i++) { ++ XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), dc.xft.norm + i); ++ XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), dc.xft.sel + i); ++ } ++ XftDrawDestroy(dc.xft.drawable); ++ g_object_unref(dc.font.layout); XFreeGC(dpy, dc.gc); -@@ -581,6 +589,7 @@ configurenotify(XEvent *e) { + XFreeCursor(dpy, cursor[CurNormal]); + XFreeCursor(dpy, cursor[CurResize]); +@@ -581,6 +595,7 @@ configurenotify(XEvent *e) { if(dc.drawable != 0) XFreePixmap(dpy, dc.drawable); dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); -+ XftDrawChange(dc.xftdrawable, dc.drawable); ++ XftDrawChange(dc.xft.drawable, dc.drawable); updatebars(); for(m = mons; m; m = m->next) XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); -@@ -796,7 +805,7 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { +@@ -796,20 +811,25 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { return; olen = strlen(text); h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; -+ y = dc.y + (dc.h / 2) - (h / 2); ++ y = dc.y + (dc.h / 2) - (h / 2); x = dc.x + (h / 2); - /* shorten text if necessary */ +- /* shorten text if necessary */ ++ /* shorten text if necessary (this could wreak havoc with pango markup but fortunately ++ dc.w is adjusted to the width of the status text and not the other way around) */ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); -@@ -805,11 +814,10 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) { + if(!len) + return; memcpy(buf, text, len); if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); - XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]); - if(dc.font.set) - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); -- else ++ if(text == stext && statusmarkup) ++ pango_layout_set_markup(dc.font.layout, buf, len); + else - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); -+ pango_layout_set_text(dc.font.plo, text, len); -+ pango_xft_render_layout(dc.xftdrawable, -+ (col == dc.norm? dc.xftnorm : dc.xftsel) + (invert? ColBG : ColFG), -+ dc.font.plo, x * PANGO_SCALE, y * PANGO_SCALE); ++ pango_layout_set_text(dc.font.layout, buf, len); ++ pango_xft_render_layout(dc.xft.drawable, ++ (col == dc.norm ? dc.xft.norm : dc.xft.sel) + (invert ? ColBG : ColFG), ++ dc.font.layout, x * PANGO_SCALE, y * PANGO_SCALE); ++ if(text == stext && statusmarkup) /* clear markup attributes */ ++ pango_layout_set_attributes(dc.font.layout, NULL); } - + void -@@ -927,13 +935,13 @@ getatomprop(Client *c, Atom prop) { +@@ -927,13 +947,13 @@ getatomprop(Client *c, Atom prop) { } - + unsigned long -getcolor(const char *colstr) { +getcolor(const char *colstr, XftColor *color) { Colormap cmap = DefaultColormap(dpy, screen); - XColor color; + Visual *vis = DefaultVisual(dpy, screen); - + - if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) + if(!XftColorAllocName(dpy, vis, cmap, colstr, color)) die("error, cannot allocate color '%s'\n", colstr); - return color.pixel; + return color->pixel; } - + Bool -@@ -1034,35 +1042,19 @@ incnmaster(const Arg *arg) { - +@@ -1034,36 +1054,24 @@ incnmaster(const Arg *arg) { + void initfont(const char *fontstr) { - char *def, **missing; - int n; -+ PangoFontMetrics *metrics; - +- - dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); - if(missing) { - while(n--) @@ -178,25 +214,30 @@ index 1d78655..d441ba2 100644 - dc.font.ascent = dc.font.xfont->ascent; - dc.font.descent = dc.font.xfont->descent; - } -+ dc.font.pgc = pango_xft_get_context(dpy, screen); -+ dc.font.pfd = pango_font_description_from_string(fontstr); ++ PangoFontMap *fontmap; ++ PangoContext *context; ++ PangoFontDescription *desc; ++ PangoFontMetrics *metrics; ++ ++ fontmap = pango_xft_get_font_map(dpy, screen); ++ context = pango_font_map_create_context(fontmap); ++ desc = pango_font_description_from_string(fontstr); ++ dc.font.layout = pango_layout_new(context); ++ pango_layout_set_font_description(dc.font.layout, desc); + -+ metrics = pango_context_get_metrics(dc.font.pgc, dc.font.pfd, -+ pango_language_from_string(setlocale(LC_CTYPE, ""))); ++ metrics = pango_context_get_metrics(context, desc, NULL); + dc.font.ascent = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE; + dc.font.descent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; -+ pango_font_metrics_unref(metrics); -+ -+ dc.font.plo = pango_layout_new(dc.font.pgc); -+ pango_layout_set_font_description(dc.font.plo, dc.font.pfd); dc.font.height = dc.font.ascent + dc.font.descent; ++ ++ pango_font_metrics_unref(metrics); ++ g_object_unref(context); } - -@@ -1611,19 +1603,24 @@ setup(void) { - cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); + + #ifdef XINERAMA +@@ -1612,17 +1620,16 @@ setup(void) { cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); -+ /* init appearance */ - dc.norm[ColBorder] = getcolor(normbordercolor); - dc.norm[ColBG] = getcolor(normbgcolor); @@ -204,30 +245,23 @@ index 1d78655..d441ba2 100644 - dc.sel[ColBorder] = getcolor(selbordercolor); - dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); -+ dc.norm[ColBorder] = getcolor(normbordercolor, dc.xftnorm + ColBorder); -+ dc.norm[ColBG] = getcolor(normbgcolor, dc.xftnorm + ColBG); -+ dc.norm[ColFG] = getcolor(normfgcolor, dc.xftnorm + ColFG); -+ dc.sel[ColBorder] = getcolor(selbordercolor, dc.xftsel + ColBorder); -+ dc.sel[ColBG] = getcolor(selbgcolor, dc.xftsel + ColBG); -+ dc.sel[ColFG] = getcolor(selfgcolor, dc.xftsel + ColFG); -+ ++ dc.norm[ColBorder] = getcolor(normbordercolor, dc.xft.norm + ColBorder); ++ dc.norm[ColBG] = getcolor(normbgcolor, dc.xft.norm + ColBG); ++ dc.norm[ColFG] = getcolor(normfgcolor, dc.xft.norm + ColFG); ++ dc.sel[ColBorder] = getcolor(selbordercolor, dc.xft.sel + ColBorder); ++ dc.sel[ColBG] = getcolor(selbgcolor, dc.xft.sel + ColBG); ++ dc.sel[ColFG] = getcolor(selfgcolor, dc.xft.sel + ColFG); dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen)); ++ dc.xft.drawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); - if(!dc.font.set) - XSetFont(dpy, dc.gc, dc.font.xfont->fid); -- /* init bars */ -+ -+ dc.xftdrawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen)); -+ if(!dc.xftdrawable) -+ printf("error, cannot create drawable\n"); -+ -+ /* init bar */ + /* init bars */ updatebars(); updatestatus(); - /* EWMH support per view */ -@@ -1692,13 +1689,10 @@ tagmon(const Arg *arg) { - +@@ -1692,13 +1699,15 @@ tagmon(const Arg *arg) { + int textnw(const char *text, unsigned int len) { - XRectangle r; @@ -238,9 +272,14 @@ index 1d78655..d441ba2 100644 - } - return XTextWidth(dc.font.xfont, text, len); + PangoRectangle r; -+ pango_layout_set_text(dc.font.plo, text, len); -+ pango_layout_get_extents(dc.font.plo, &r, 0); ++ if(text == stext && statusmarkup) ++ pango_layout_set_markup(dc.font.layout, text, len); ++ else ++ pango_layout_set_text(dc.font.layout, text, len); ++ pango_layout_get_extents(dc.font.layout, 0, &r); ++ if(text == stext && statusmarkup) /* clear markup attributes */ ++ pango_layout_set_attributes(dc.font.layout, NULL); + return r.width / PANGO_SCALE; } - + void diff --git a/dwm.suckless.org/patches/pango.md b/dwm.suckless.org/patches/pango.md @@ -4,27 +4,37 @@ Pango Description ----------- -This patch adds pango support for the status bar. - -I find pango a better alternative than xft because it supports chains of fallback fonts -out of the box, so you can use -for example- iconic fonts as your second family: "DejaVu -Sans, Icons 8". The Icons family is a non-overlapping merge of Awesome and Ionicons fonts -I've made for my statusbar. In case you're interested: -https://aur.archlinux.org/packages/ttf-font-icons/ (there is a cheatsheet with the icons -and their unicode points linked there). - -This is not achievable using xft without further effort. Don't be mislead by the fact that -fontconfig understands descriptors like "DejaVu Sans, Icons-8" or even font sequences -defined as alias in your fonts.conf. xft will pick one font once and for all, not on a -char-by-char basis. +This relatively simple patch adds pango support for the status bar. This not only adds +TrueType font support but also opens a couple of interesting possibilities that are +not possible under barebone xft: + +* **Simple markup** for status messages (optional, enable/disable it in your config.h) + using [pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html). + So you can format your status messages specifying fg/bg colors, sizes, sub/superscripts, + underline, emphasis, bold, etc. You can do dynamic font switching, also! To play safe + with the rest of the status bar, markup support is restricted to the status message area + over which you have direct control. + +* **Fallback fonts**, so you can use -for example- some set of iconic fonts as your second + family: "DejaVu Sans, Icons 8" [1]. There are tons of monochromatic nice looking TTF + icons around the web these days as webfonts are becoming more and more popular. Notice + that you can also use the more powerful font switching enabled by pango markup to + achieve the same goal. Also don't be mislead by the fact that fontconfig understands + descriptors like "DejaVu Sans, Icons-8" or even font sequences defined as alias in your + fonts.conf. xft will pick one font once and for all, not on a char-by-char basis. + +[1] The [Icons family](https://aur.archlinux.org/packages/ttf-font-icons/) is a + non-overlapping merge of Awesome and Ionicons fonts I've made for my statusbar. In case + you want to take a look at it, there is a + [cheatsheet](https://www.dropbox.com/s/ske86jxsslpyx3a/icons.pdf) listing the icons and + their unicode points. Download -------- -* [dwm-6.0-pango.diff](dwm-6.0-pango.diff) (8.3k) (30 Dec 2013) +* [dwm-6.0-pango.diff](dwm-6.0-pango.diff) Author ------ -* Carlos Pita (memeplex)<carlosjosepita@gmail.com> (I just polished and fixed a patch that - I found around the web). +* Carlos Pita (memeplex) <carlosjosepita@gmail.com>