On Tue, Jul 22, 2014 at 10:27:51AM -0400, Lee Fallat wrote:
> The Xft patch should be fairly straight forward to port, as it only
> touches the font functions. I'd do it but I have no time right now.
> 
> On Tue, Jul 22, 2014 at 9:15 AM, Eric Pruitt <eric.pru...@gmail.com> wrote:
> > I'm looking for a Pango or Xft and, ideally, a compatible systray patch
> > that will work with dwm 6.1 / the current Git repository head. The
> > systray patch on the wiki works fine, but the Pango and Xft patches I've
> > come across so far only work with dwm 6.0 because they predate the
> > creation of the suckless graphics library (drw.h / drw.c), and in my
> > experience, the systray patches often need to be modified to work with
> > whatever graphics library is in use.
> >

Hi,

the following patch went over this very list a while ago. It works for
me...

WKR
Hinnerk


--- Forwarded message from q...@c9x.me -----

Date: Sat, 23 Nov 2013 00:32:39 +0100
From: q...@c9x.me
To: dev@suckless.org
Subject: [dev] [dwm] Xft patch
Reply-To: dev mail list <dev@suckless.org>

For my personal use of dwm I have written a small
patch to support Xft---it actually decreases the
line count of dwm.  I thought it would be useful
to share it with you.

You will also notice that the patch changes the
window creation semantics.  This is because I
wanted new windows to appear close the currently
focused one.  Not systematically in the master
area.

Do whatever you want with this.

-- Quentin

diff --git a/config.mk b/config.mk
index bc3d80e..f5e949f 100644
--- a/config.mk
+++ b/config.mk
@@ -15,8 +15,8 @@ XINERAMALIBS  = -lXinerama
 XINERAMAFLAGS = -DXINERAMA
 
 # includes and libs
-INCS = -I${X11INC}
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS}
+INCS = -I${X11INC} -I/usr/include/freetype2
+LIBS = -L${X11LIB} -lX11 -lXft ${XINERAMALIBS}
 
 # flags
 CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" 
${XINERAMAFLAGS}
diff --git a/drw.c b/drw.c
index b130405..7057a34 100644
--- a/drw.c
+++ b/drw.c
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <X11/Xlib.h>
+#include <X11/Xft/Xft.h>
 
 #include "drw.h"
 #include "util.h"
@@ -42,39 +43,19 @@ drw_free(Drw *drw) {
 }
 
 Fnt *
-drw_font_create(Display *dpy, const char *fontname) {
+drw_font_create(Display *dpy, int screen, const char *fontname) {
        Fnt *font;
-       char *def, **missing;
-       int n;
 
        font = (Fnt *)calloc(1, sizeof(Fnt));
        if(!font)
                return NULL;
-       font->set = XCreateFontSet(dpy, fontname, &missing, &n, &def);
-       if(missing) {
-               while(n--)
-                       fprintf(stderr, "drw: missing fontset: %s\n", 
missing[n]);
-               XFreeStringList(missing);
-       }
-       if(font->set) {
-               XFontStruct **xfonts;
-               char **font_names;
-               XExtentsOfFontSet(font->set);
-               n = XFontsOfFontSet(font->set, &xfonts, &font_names);
-               while(n--) {
-                       font->ascent = MAX(font->ascent, (*xfonts)->ascent);
-                       font->descent = MAX(font->descent,(*xfonts)->descent);
-                       xfonts++;
-               }
-       }
-       else {
-               if(!(font->xfont = XLoadQueryFont(dpy, fontname))
-               && !(font->xfont = XLoadQueryFont(dpy, "fixed")))
-                       die("error, cannot load font: '%s'\n", fontname);
-               font->ascent = font->xfont->ascent;
-               font->descent = font->xfont->descent;
-       }
+       if(!(font->xfont = XftFontOpenName(dpy,screen,fontname))
+       && !(font->xfont = XftFontOpenName(dpy,screen,"fixed")))
+               die("error, cannot load font: '%s'\n", fontname);
+       font->ascent = font->xfont->ascent;
+       font->descent = font->xfont->descent;
        font->h = font->ascent + font->descent;
+       font->dpy = dpy;
        return font;
 }
 
@@ -82,10 +63,7 @@ void
 drw_font_free(Display *dpy, Fnt *font) {
        if(!font)
                return;
-       if(font->set)
-               XFreeFontSet(dpy, font->set);
-       else
-               XFreeFont(dpy, font->xfont);
+       XftFontClose(dpy, font->xfont);
        free(font);
 }
 
@@ -93,7 +71,7 @@ Clr *
 drw_clr_create(Drw *drw, const char *clrname) {
        Clr *clr;
        Colormap cmap;
-       XColor color;
+       Visual *vis;
 
        if(!drw)
                return NULL;
@@ -101,9 +79,10 @@ drw_clr_create(Drw *drw, const char *clrname) {
        if(!clr)
                return NULL;
        cmap = DefaultColormap(drw->dpy, drw->screen);
-       if(!XAllocNamedColor(drw->dpy, cmap, clrname, &color, &color))
+       vis = DefaultVisual(drw->dpy, drw->screen);
+       if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb))
                die("error, cannot allocate color '%s'\n", clrname);
-       clr->rgb = color.pixel;
+       clr->pix = clr->rgb.pixel;
        return clr;
 }
 
@@ -121,7 +100,7 @@ drw_setfont(Drw *drw, Fnt *font) {
 
 void
 drw_setscheme(Drw *drw, ClrScheme *scheme) {
-       if(drw && scheme) 
+       if(drw && scheme)
                drw->scheme = scheme;
 }
 
@@ -131,7 +110,7 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned 
int h, int filled, int
 
        if(!drw || !drw->font || !drw->scheme)
                return;
-       XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb : 
drw->scheme->fg->rgb);
+       XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : 
drw->scheme->fg->pix);
        dx = (drw->font->ascent + drw->font->descent + 2) / 4;
        if(filled)
                XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, 
dx+1, dx+1);
@@ -144,13 +123,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned 
int h, const char *tex
        char buf[256];
        int i, tx, ty, th, len, olen;
        Extnts tex;
+       Colormap cmap;
+       Visual *vis;
+       XftDraw *d;
 
        if(!drw || !drw->scheme)
                return;
-       XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->rgb : 
drw->scheme->bg->rgb);
+       XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->pix : 
drw->scheme->bg->pix);
        XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
        if(!text || !drw->font)
                return;
+
        olen = strlen(text);
        drw_font_getexts(drw->font, text, olen, &tex);
        th = drw->font->ascent + drw->font->descent;
@@ -164,11 +147,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned 
int h, const char *tex
        memcpy(buf, text, len);
        if(len < olen)
                for(i = len; i && i > len - 3; buf[--i] = '.');
-       XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->rgb : 
drw->scheme->fg->rgb);
-       if(drw->font->set)
-               XmbDrawString(drw->dpy, drw->drawable, drw->font->set, drw->gc, 
tx, ty, buf, len);
-       else
-               XDrawString(drw->dpy, drw->drawable, drw->gc, tx, ty, buf, len);
+
+       cmap = DefaultColormap(drw->dpy, drw->screen);
+       vis = DefaultVisual(drw->dpy, drw->screen);
+       d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap);
+       XftDrawStringUtf8(d, invert ? &drw->scheme->bg->rgb : 
&drw->scheme->fg->rgb, drw->font->xfont, tx, ty, (XftChar8 *)buf, len);
+       XftDrawDestroy(d);
 }
 
 void
@@ -182,19 +166,13 @@ drw_map(Drw *drw, Window win, int x, int y, unsigned int 
w, unsigned int h) {
 
 void
 drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) {
-       XRectangle r;
+       XGlyphInfo ext;
 
        if(!font || !text)
                return;
-       if(font->set) {
-               XmbTextExtents(font->set, text, len, NULL, &r);
-               tex->w = r.width;
-               tex->h = r.height;
-       }
-       else {
-               tex->h = font->ascent + font->descent;
-               tex->w = XTextWidth(font->xfont, text, len);
-       }
+       XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
+       tex->h = font->h;
+       tex->w = ext.xOff;
 }
 
 unsigned int
diff --git a/drw.h b/drw.h
index a5f34e0..503e764 100644
--- a/drw.h
+++ b/drw.h
@@ -1,7 +1,8 @@
 /* See LICENSE file for copyright and license details. */
 
 typedef struct {
-       unsigned long rgb;
+       unsigned long pix;
+       XftColor rgb;
 } Clr;
 
 typedef struct {
@@ -9,11 +10,11 @@ typedef struct {
 } Cur;
 
 typedef struct {
+       Display *dpy;
        int ascent;
        int descent;
        unsigned int h;
-       XFontSet set;
-       XFontStruct *xfont;
+       XftFont *xfont;
 } Fnt;
 
 typedef struct {
@@ -44,7 +45,7 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int h);
 void drw_free(Drw *drw);
 
 /* Fnt abstraction */
-Fnt *drw_font_create(Display *dpy, const char *fontname);
+Fnt *drw_font_create(Display *dpy, int screen, const char *fontname);
 void drw_font_free(Display *dpy, Fnt *font);
 void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts 
*extnts);
 unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int 
len);
diff --git a/dwm.c b/dwm.c
index 1bbb4b3..f9ae316 100644
--- a/dwm.c
+++ b/dwm.c
@@ -39,6 +39,7 @@
 #ifdef XINERAMA
 #include <X11/extensions/Xinerama.h>
 #endif /* XINERAMA */
+#include <X11/Xft/Xft.h>
 
 #include "drw.h"
 #include "util.h"
@@ -145,7 +146,7 @@ static void applyrules(Client *c);
 static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool 
interact);
 static void arrange(Monitor *m);
 static void arrangemon(Monitor *m);
-static void attach(Client *c);
+static void attach(Client *c, Bool top);
 static void attachstack(Client *c);
 static void buttonpress(XEvent *e);
 static void checkotherwm(void);
@@ -395,9 +396,13 @@ arrangemon(Monitor *m) {
 }
 
 void
-attach(Client *c) {
-       c->next = c->mon->clients;
-       c->mon->clients = c;
+attach(Client *c, Bool top) {
+       Client **tc = &c->mon->clients;
+
+       if(!top)
+               for(; *tc && *tc != c->mon->sel; tc = &(*tc)->next);
+       c->next = *tc;
+       *tc = c;
 }
 
 void
@@ -792,7 +797,7 @@ focus(Client *c) {
                detachstack(c);
                attachstack(c);
                grabbuttons(c, True);
-               XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border->rgb);
+               XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border->pix);
                setfocus(c);
        }
        else {
@@ -1040,7 +1045,7 @@ manage(Window w, XWindowAttributes *wa) {
 
        wc.border_width = c->bw;
        XConfigureWindow(dpy, w, CWBorderWidth, &wc);
-       XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->rgb);
+       XSetWindowBorder(dpy, w, scheme[SchemeNorm].border->pix);
        configure(c); /* propagates border_width, if size doesn't change */
        updatewindowtype(c);
        updatesizehints(c);
@@ -1051,13 +1056,13 @@ manage(Window w, XWindowAttributes *wa) {
                c->isfloating = c->oldstate = trans != None || c->isfixed;
        if(c->isfloating)
                XRaiseWindow(dpy, c->win);
-       attach(c);
+       attach(c, False);
        attachstack(c);
        XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, 
PropModeAppend,
                        (unsigned char *) &(c->win), 1);
        XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* 
some windows require this */
        setclientstate(c, NormalState);
-       if (c->mon == selmon)
+       if(c->mon == selmon)
                unfocus(selmon->sel, False);
        c->mon->sel = c;
        arrange(c->mon);
@@ -1183,7 +1188,7 @@ nexttiled(Client *c) {
 void
 pop(Client *c) {
        detach(c);
-       attach(c);
+       attach(c, True);
        focus(c);
        arrange(c->mon);
 }
@@ -1383,7 +1388,7 @@ sendmon(Client *c, Monitor *m) {
        detachstack(c);
        c->mon = m;
        c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
-       attach(c);
+       attach(c, False);
        attachstack(c);
        focus(NULL);
        arrange(NULL);
@@ -1426,8 +1431,8 @@ setfocus(Client *c) {
        if(!c->neverfocus) {
                XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
                XChangeProperty(dpy, root, netatom[NetActiveWindow],
-                               XA_WINDOW, 32, PropModeReplace,
-                               (unsigned char *) &(c->win), 1);
+                               XA_WINDOW, 32, PropModeReplace,
+                               (unsigned char *) &(c->win), 1);
        }
        sendevent(c, wmatom[WMTakeFocus]);
 }
@@ -1497,7 +1502,7 @@ setup(void) {
        /* init screen */
        screen = DefaultScreen(dpy);
        root = RootWindow(dpy, screen);
-       fnt = drw_font_create(dpy, font);
+       fnt = drw_font_create(dpy, screen, font);
        sw = DisplayWidth(dpy, screen);
        sh = DisplayHeight(dpy, screen);
        bh = fnt->h + 2;
@@ -1676,7 +1681,7 @@ unfocus(Client *c, Bool setfocus) {
        if(!c)
                return;
        grabbuttons(c, False);
-       XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->rgb);
+       XSetWindowBorder(dpy, c->win, scheme[SchemeNorm].border->pix);
        if(setfocus) {
                XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
                XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
@@ -1730,7 +1735,7 @@ updatebars(void) {
                .event_mask = ButtonPressMask|ExposureMask
        };
        for(m = mons; m; m = m->next) {
-               if (m->barwin)
+               if(m->barwin)
                        continue;
                m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 
0, DefaultDepth(dpy, screen),
                                          CopyFromParent, DefaultVisual(dpy, 
screen),
@@ -1818,7 +1823,7 @@ updategeom(void) {
                                        m->clients = c->next;
                                        detachstack(c);
                                        c->mon = mons;
-                                       attach(c);
+                                       attach(c, False);
                                        attachstack(c);
                                }
                                if(m == selmon)


--- End forwarded message -----

Attachment: signature.asc
Description: Digital signature

Reply via email to