commit 2c84f85f6d1d2bc440d527eadda8c355f1dab6d5
parent bd6c86c9e4a51bc456d152e4e99fe5553ac863b4
Author: memeplex <carlosjosepita@gmail.com>
Date: Thu, 9 Jan 2014 15:30:22 -0300
Pango patch update: markup & cleanup.
Diffstat:
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>