Hi,

On a journey to find a statusbar for cwm, I found that x11/lemonbar
didn't support XFT. I used sources from https://github.com/krypt-n/bar
to compile on OpenBSD 6.4/amd64 and it seems to work. So far, it
compiles, lemonbar starts and renders text using xft:Sans:size=11.

Find the relevant patches attached.

Regards,
  Jo

--- Makefile.orig       Fri Nov 23 00:26:08 2018
+++ Makefile    Fri Nov 23 00:35:00 2018
@@ -1,4 +1,4 @@
 # This snippet has been shmelessly stol^Hborrowed from thestinger's repose 
Makefile
-VERSION = 1.2
+VERSION = 1.3
 GIT_DESC=$(shell test -d .git && git describe --always 2>/dev/null)
 
@@ -8,6 +8,8 @@
 
 CC     ?= gcc
-CFLAGS += -Wall -std=c99 -DVERSION="\"$(VERSION)\""
-LDFLAGS += -lxcb -lxcb-xinerama -lxcb-randr
+CFLAGS += -Wall -std=c99 -DVERSION="\"$(VERSION)\"" \
+                                       -I/usr/X11R6/include/freetype2
+LDFLAGS += -lxcb -lxcb-xinerama -lxcb-randr \
+                                        -lX11 -lX11-xcb -lXft -lfreetype -lz 
-lfontconfig
 CFDEBUG = -g3 -pedantic -Wall -Wunused-parameter -Wlong-long \
           -Wsign-conversion -Wconversion -Wimplicit-function-declaration
--- lemonbar.c.orig     Mon Nov 20 11:47:43 2017
+++ lemonbar.c  Fri Nov 23 00:30:26 2018
@@ -2,4 +2,5 @@
 #define _POSIX_C_SOURCE 200809L
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -8,4 +9,5 @@
 #include <signal.h>
 #include <poll.h>
+#include <fcntl.h>
 #include <getopt.h>
 #include <unistd.h>
@@ -18,6 +20,9 @@
 #include <xcb/randr.h>
 
-// Here be dragons
+#include <X11/Xft/Xft.h>
+#include <X11/Xlib-xcb.h>
 
+// Here bet  dragons
+
 #define max(a,b) ((a) > (b) ? (a) : (b))
 #define min(a,b) ((a) < (b) ? (a) : (b))
@@ -26,8 +31,13 @@
 typedef struct font_t {
     xcb_font_t ptr;
+    xcb_charinfo_t *width_lut;
+
+    XftFont *xft_ft;
+
+    int ascent;
+
     int descent, height, width;
     uint16_t char_max;
     uint16_t char_min;
-    xcb_charinfo_t *width_lut;
 } font_t;
 
@@ -69,9 +79,8 @@
 };
 
-enum {
-    ALIGN_L = 0,
-    ALIGN_C,
-    ALIGN_R
-};
+enum { ALIGN_L = 0,
+       ALIGN_C,
+       ALIGN_R
+     };
 
 enum {
@@ -84,13 +93,24 @@
 #define MAX_FONT_COUNT 5
 
+static Display *dpy;
 static xcb_connection_t *c;
+
 static xcb_screen_t *scr;
+static int scr_nbr = 0;
+
 static xcb_gcontext_t gc[GC_MAX];
 static xcb_visualid_t visual;
+static Visual *visual_ptr;
 static xcb_colormap_t colormap;
+
+
 static monitor_t *monhead, *montail;
 static font_t *font_list[MAX_FONT_COUNT];
 static int font_count = 0;
 static int font_index = -1;
+static int offsets_y[MAX_FONT_COUNT];
+static int offset_y_count = 0;
+static int offset_y_index = 0;
+
 static uint32_t attrs = 0;
 static bool dock = false;
@@ -102,4 +122,12 @@
 static area_stack_t area_stack;
 
+static XftColor sel_fg;
+static XftDraw *xft_draw;
+
+//char width lookuptable
+#define MAX_WIDTHS (1 << 16)
+static wchar_t xft_char[MAX_WIDTHS];
+static char    xft_width[MAX_WIDTHS];
+
 void
 update_gc (void)
@@ -108,4 +136,11 @@
     xcb_change_gc(c, gc[GC_CLEAR], XCB_GC_FOREGROUND, (const uint32_t []){ 
bgc.v });
     xcb_change_gc(c, gc[GC_ATTR], XCB_GC_FOREGROUND, (const uint32_t []){ 
ugc.v });
+    XftColorFree(dpy, visual_ptr, colormap , &sel_fg);
+    char color[] = "#ffffff";
+    uint32_t nfgc = fgc.v & 0x00ffffff;
+    snprintf(color, sizeof(color), "#%06X", nfgc);
+    if (!XftColorAllocName (dpy, visual_ptr, colormap, color, &sel_fg)) {
+        fprintf(stderr, "Couldn't allocate xft font color '%s'\n", color);
+    }
 }
 
@@ -189,5 +224,35 @@
 }
 
+
 int
+xft_char_width_slot (uint16_t ch)
+{
+    int slot = ch % MAX_WIDTHS;
+    while (xft_char[slot] != 0 && xft_char[slot] != ch)
+    {
+        slot = (slot + 1) % MAX_WIDTHS;
+    }
+    return slot;
+}
+
+int xft_char_width (uint16_t ch, font_t *cur_font)
+{
+    int slot = xft_char_width_slot(ch);
+    if (!xft_char[slot]) {
+        XGlyphInfo gi;
+        FT_UInt glyph = XftCharIndex (dpy, cur_font->xft_ft, (FcChar32) ch);
+        XftFontLoadGlyphs (dpy, cur_font->xft_ft, FcFalse, &glyph, 1);
+        XftGlyphExtents (dpy, cur_font->xft_ft, &glyph, 1, &gi);
+        XftFontUnloadGlyphs (dpy, cur_font->xft_ft, &glyph, 1);
+        xft_char[slot] = ch;
+        xft_width[slot] = gi.xOff;
+        return gi.xOff;
+    } else if (xft_char[slot] == ch)
+        return xft_width[slot];
+    else
+        return 0;
+}
+
+int
 shift (monitor_t *mon, int x, int align, int ch_width)
 {
@@ -208,6 +273,6 @@
             break;
     }
-
-    // Draw the background first
+    
+        /* Draw the background first */
     fill_rect(mon->pixmap, gc[GC_CLEAR], x, 0, ch_width, bh);
     return x;
@@ -234,17 +299,28 @@
 draw_char (monitor_t *mon, font_t *cur_font, int x, int align, uint16_t ch)
 {
-    int ch_width = (cur_font->width_lut) ?
-        cur_font->width_lut[ch - cur_font->char_min].character_width:
-        cur_font->width;
+    int ch_width;
 
+    if (cur_font->xft_ft) {
+        ch_width = xft_char_width(ch, cur_font);
+    } else {
+        ch_width = (cur_font->width_lut) ?
+            cur_font->width_lut[ch - cur_font->char_min].character_width:
+            cur_font->width;
+    }
+
     x = shift(mon, x, align, ch_width);
 
-    // xcb accepts string in UCS-2 BE, so swap
-    ch = (ch >> 8) | (ch << 8);
-
-    // The coordinates here are those of the baseline
-    xcb_poly_text_16_simple(c, mon->pixmap, gc[GC_DRAW],
-                            x, bh / 2 + cur_font->height / 2 - 
cur_font->descent,
+    int y = bh / 2 + cur_font->height / 2- cur_font->descent + 
offsets_y[offset_y_index];
+    if (cur_font->xft_ft) {
+        XftDrawString16 (xft_draw, &sel_fg, cur_font->xft_ft, x,y, &ch, 1);
+    } else {
+        /* xcb accepts string in UCS-2 BE, so swap */
+        ch = (ch >> 8) | (ch << 8);
+        
+        // The coordinates here are those of the baseline
+        xcb_poly_text_16_simple(c, mon->pixmap, gc[GC_DRAW],
+                            x, y,
                             1, &ch);
+    }
 
     draw_lines(mon, x, ch_width);
@@ -337,7 +413,13 @@
 
     switch (modifier) {
-        case '+': attrs |= (1<<pos); break;
-        case '-': attrs &=~(1<<pos); break;
-        case '!': attrs ^= (1<<pos); break;
+    case '+':
+        attrs |= (1u<<pos);
+        break;
+    case '-':
+        attrs &=~(1u<<pos);
+        break;
+    case '!':
+        attrs ^= (1u<<pos);
+        break;
     }
 }
@@ -460,4 +542,13 @@
 font_has_glyph (font_t *font, const uint16_t c)
 {
+    if (font->xft_ft) {
+        if (XftCharExists(dpy, font->xft_ft, (FcChar32) c)) {
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
     if (c < font->char_min || c > font->char_max)
         return false;
@@ -469,21 +560,25 @@
 }
 
-// returns NULL if character cannot be printed
 font_t *
 select_drawable_font (const uint16_t c)
 {
     // If the user has specified a font to use, try that first.
-    if (font_index != -1 && font_has_glyph(font_list[font_index - 1], c))
+    if (font_index != -1 && font_has_glyph(font_list[font_index - 1], c)) {
+        offset_y_index = font_index - 1;
         return font_list[font_index - 1];
+    }
 
     // If the end is reached without finding an appropriate font, return NULL.
     // If the font can draw the character, return it.
     for (int i = 0; i < font_count; i++) {
-        if (font_has_glyph(font_list[i], c))
+        if (font_has_glyph(font_list[i], c)) {
+            offset_y_index = i;
             return font_list[i];
+        }
     }
     return NULL;
 }
 
+
 void
 parse (char *text)
@@ -505,7 +600,12 @@
         fill_rect(m->pixmap, gc[GC_CLEAR], 0, 0, m->width, bh);
 
+    /* Create xft drawable */
+    if (!(xft_draw = XftDrawCreate (dpy, cur_mon->pixmap, visual_ptr , 
colormap))) {
+        fprintf(stderr, "Couldn't create xft drawable\n");
+    }
+
     for (;;) {
         if (*p == '\0' || *p == '\n')
-            return;
+                       break;
 
         if (p[0] == '%' && p[1] == '{' && (block_end = strchr(p++, '}'))) {
@@ -561,4 +661,8 @@
                               else
                               { p++; continue; }
+                                                 XftDrawDestroy (xft_draw);
+                                                 if (!(xft_draw = 
XftDrawCreate (dpy, cur_mon->pixmap, visual_ptr , colormap ))) {
+                                                       fprintf(stderr, 
"Couldn't create xft drawable\n");
+                                                 }
 
                               p++;
@@ -603,8 +707,4 @@
             p++;
         } else { // utf-8 -> ucs-2
-            // Escaped % symbol, eat the first one
-            if (p[0] == '%' && p[1] == '%')
-                p++;
-
             uint8_t *utf = (uint8_t *)p;
             uint16_t ucs;
@@ -650,6 +750,8 @@
                 continue;
 
-            xcb_change_gc(c, gc[GC_DRAW] , XCB_GC_FONT, (const uint32_t []){ 
cur_font->ptr });
-
+            if(cur_font->ptr)
+                xcb_change_gc(c, gc[GC_DRAW] , XCB_GC_FONT, (const uint32_t 
[]) {
+                cur_font->ptr
+            });
             int w = draw_char(cur_mon, cur_font, pos_x, align, ucs);
 
@@ -658,4 +760,5 @@
         }
     }
+    XftDrawDestroy (xft_draw);
 }
 
@@ -675,10 +778,4 @@
     font = xcb_generate_id(c);
 
-    cookie = xcb_open_font_checked(c, font, strlen(pattern), pattern);
-    if (xcb_request_check (c, cookie)) {
-        fprintf(stderr, "Could not load font \"%s\"\n", pattern);
-        return;
-    }
-
     font_t *ret = calloc(1, sizeof(font_t));
 
@@ -686,26 +783,53 @@
         return;
 
-    queryreq = xcb_query_font(c, font);
-    font_info = xcb_query_font_reply(c, queryreq, NULL);
+    cookie = xcb_open_font_checked(c, font, strlen(pattern), pattern);
+    if (!xcb_request_check (c, cookie)) {
+        queryreq = xcb_query_font(c, font);
+        font_info = xcb_query_font_reply(c, queryreq, NULL);
 
-    ret->ptr = font;
-    ret->descent = font_info->font_descent;
-    ret->height = font_info->font_ascent + font_info->font_descent;
-    ret->width = font_info->max_bounds.character_width;
-    ret->char_max = font_info->max_byte1 << 8 | font_info->max_char_or_byte2;
-    ret->char_min = font_info->min_byte1 << 8 | font_info->min_char_or_byte2;
-
-    // Copy over the width lut as it's part of font_info
-    int lut_size = sizeof(xcb_charinfo_t) * 
xcb_query_font_char_infos_length(font_info);
-    if (lut_size) {
-        ret->width_lut = malloc(lut_size);
-        memcpy(ret->width_lut, xcb_query_font_char_infos(font_info), lut_size);
+        ret->xft_ft = NULL;
+        ret->ptr = font;
+        ret->descent = font_info->font_descent;
+        ret->height = font_info->font_ascent + font_info->font_descent;
+        ret->width = font_info->max_bounds.character_width;
+        ret->char_max = font_info->max_byte1 << 8 | 
font_info->max_char_or_byte2;
+        ret->char_min = font_info->min_byte1 << 8 | 
font_info->min_char_or_byte2;
+        // Copy over the width lut as it's part of font_info
+        int lut_size = sizeof(xcb_charinfo_t) * 
xcb_query_font_char_infos_length(font_info);
+        if (lut_size) {
+            ret->width_lut = malloc(lut_size);
+            memcpy(ret->width_lut, xcb_query_font_char_infos(font_info), 
lut_size);
+        }
+        free(font_info);
+    } else if ((ret->xft_ft = XftFontOpenName (dpy, scr_nbr, pattern))) {
+        ret->ptr = 0;
+        ret->ascent = ret->xft_ft->ascent;
+        ret->descent = ret->xft_ft->descent;
+        ret->height = ret->ascent + ret->descent;
+    } else {
+        fprintf(stderr, "Could not load font %s\n", pattern);
+        free(ret);
+        return;
     }
 
-    free(font_info);
-
     font_list[font_count++] = ret;
 }
 
+void add_y_offset(int offset) {
+    if (offset_y_count >= MAX_FONT_COUNT) {
+        fprintf(stderr, "Max offset count reached. Could not set offset 
\"%d\"\n", offset);
+        return;
+    }
+
+    offsets_y[offset_y_count] = strtol(optarg, NULL, 10);
+    if (offset_y_count == 0) {
+        for (int i = 1; i < MAX_FONT_COUNT; ++i) {
+            offsets_y[i] = offsets_y[0];
+        }
+    }
+    ++offset_y_count;
+}
+
+
 enum {
     NET_WM_WINDOW_TYPE,
@@ -757,17 +881,20 @@
             strut[2] = bh;
             strut[8] = mon->x;
-            strut[9] = mon->x + mon->width - 1;
+            strut[9] = mon->x + mon->width;
         } else {
             strut[3]  = bh;
             strut[10] = mon->x;
-            strut[11] = mon->x + mon->width - 1;
+            strut[11] = mon->x + mon->width;
         }
 
         xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
atom_list[NET_WM_WINDOW_TYPE], XCB_ATOM_ATOM, 32, 1, 
&atom_list[NET_WM_WINDOW_TYPE_DOCK]);
         xcb_change_property(c, XCB_PROP_MODE_APPEND,  mon->window, 
atom_list[NET_WM_STATE], XCB_ATOM_ATOM, 32, 2, &atom_list[NET_WM_STATE_STICKY]);
-        xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ -1 } 
);
+        xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []) {
+            0u - 1u
+        } );
         xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
atom_list[NET_WM_STRUT_PARTIAL], XCB_ATOM_CARDINAL, 32, 12, strut);
         xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
atom_list[NET_WM_STRUT], XCB_ATOM_CARDINAL, 32, 4, strut);
         xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 3, "bar");
+        xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, 12, "lemonbar\0Bar");
     }
 }
@@ -789,11 +916,12 @@
     ret->next = ret->prev = NULL;
     ret->window = xcb_generate_id(c);
-
     int depth = (visual == scr->root_visual) ? XCB_COPY_FROM_PARENT : 32;
     xcb_create_window(c, depth, ret->window, scr->root,
-            ret->x, ret->y, width, bh, 0,
-            XCB_WINDOW_CLASS_INPUT_OUTPUT, visual,
-            XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT 
| XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
-            (const uint32_t []){ bgc.v, bgc.v, dock, XCB_EVENT_MASK_EXPOSURE | 
XCB_EVENT_MASK_BUTTON_PRESS, colormap });
+                      ret->x, ret->y, width, bh, 0,
+                      XCB_WINDOW_CLASS_INPUT_OUTPUT, visual,
+                      XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | 
XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
+    (const uint32_t []) {
+        bgc.v, bgc.v, dock, XCB_EVENT_MASK_EXPOSURE | 
XCB_EVENT_MASK_BUTTON_PRESS, colormap
+    });
 
     ret->pixmap = xcb_generate_id(c);
@@ -854,5 +982,5 @@
         // Get height of screen from y_offset + height of lowest monitor
         if (h >= height)
-        height = h;
+            height = h;
     }
 
@@ -877,8 +1005,8 @@
         if (rects[i].width > left) {
             monitor_t *mon = monitor_new(
-                    rects[i].x + left,
-                    rects[i].y,
-                    min(width, rects[i].width - left),
-                    rects[i].height);
+                                 rects[i].x + left,
+                                 rects[i].y,
+                                 min(width, rects[i].width - left),
+                                 rects[i].height);
 
             if (!mon)
@@ -888,5 +1016,4 @@
 
             width -= rects[i].width - left;
-
             // No need to check for other monitors
             if (width <= 0)
@@ -909,5 +1036,5 @@
 
     rres_reply = xcb_randr_get_screen_resources_current_reply(c,
-            xcb_randr_get_screen_resources_current(c, scr->root), NULL);
+                 xcb_randr_get_screen_resources_current(c, scr->root), NULL);
 
     if (!rres_reply) {
@@ -943,5 +1070,5 @@
 
         ci_reply = xcb_randr_get_crtc_info_reply(c,
-                xcb_randr_get_crtc_info(c, oi_reply->crtc, XCB_CURRENT_TIME), 
NULL);
+                   xcb_randr_get_crtc_info(c, oi_reply->crtc, 
XCB_CURRENT_TIME), NULL);
 
         free(oi_reply);
@@ -973,5 +1100,5 @@
             if (i != j && rects[j].width) {
                 if (rects[j].x >= rects[i].x && rects[j].x + rects[j].width <= 
rects[i].x + rects[i].width &&
-                    rects[j].y >= rects[i].y && rects[j].y + rects[j].height 
<= rects[i].y + rects[i].height) {
+                        rects[j].y >= rects[i].y && rects[j].y + 
rects[j].height <= rects[i].y + rects[i].height) {
                     rects[j].width = 0;
                     valid--;
@@ -1004,5 +1131,5 @@
 
     xqs_reply = xcb_xinerama_query_screens_reply(c,
-            xcb_xinerama_query_screens_unchecked(c), NULL);
+                xcb_xinerama_query_screens_unchecked(c), NULL);
 
     iter = xcb_xinerama_query_screens_screen_info_iterator(xqs_reply);
@@ -1029,20 +1156,19 @@
 get_visual (void)
 {
-    xcb_depth_iterator_t iter;
 
-    iter = xcb_screen_allowed_depths_iterator(scr);
+    XVisualInfo xv; 
+    xv.depth = 32;
+    int result = 0;
+    XVisualInfo* result_ptr = NULL; 
+    result_ptr = XGetVisualInfo(dpy, VisualDepthMask, &xv, &result);
 
-    // Try to find a RGBA visual
-    while (iter.rem) {
-        xcb_visualtype_t *vis = xcb_depth_visuals(iter.data);
-
-        if (iter.data->depth == 32)
-            return vis->visual_id;
-
-        xcb_depth_next(&iter);
+    if (result > 0) {
+        visual_ptr = result_ptr->visual;
+        return result_ptr->visualid;
     }
-
-    // Fallback to the default one
-    return scr->root_visual;
+    
+    //Fallback
+    visual_ptr = DefaultVisual(dpy, scr_nbr);  
+       return scr->root_visual;
 }
 
@@ -1101,6 +1227,15 @@
 xconn (void)
 {
-    // Connect to X
-    c = xcb_connect (NULL, NULL);
+    if ((dpy = XOpenDisplay(0)) == NULL) {
+        fprintf (stderr, "Couldnt open display\n");
+    }
+
+    if ((c = XGetXCBConnection(dpy)) == NULL) {
+        fprintf (stderr, "Couldnt connect to X\n");
+        exit (EXIT_FAILURE);
+    }
+
+       XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
+
     if (xcb_connection_has_error(c)) {
         fprintf(stderr, "Couldn't connect to X\n");
@@ -1108,10 +1243,9 @@
     }
 
-    // Grab infos from the first screen
+    /* Grab infos from the first screen */
     scr = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
 
-    // Try to get a RGBA visual and build the colormap for that
-    visual = get_visual();
-
+    /* Try to get a RGBA visual and build the colormap for that */
+       visual = get_visual();
     colormap = xcb_generate_id(c);
     xcb_create_colormap(c, XCB_COLORMAP_ALLOC_NONE, colormap, scr->root, 
visual);
@@ -1119,5 +1253,5 @@
 
 void
-init (char *wm_name)
+init (char *wm_name, char *wm_instance)
 {
     // Try to load a default font
@@ -1214,6 +1348,31 @@
         if (wm_name)
             xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8 ,strlen(wm_name), wm_name);
+
+        // set the WM_CLASS atom instance to the executable name
+        if (wm_instance) {
+            char *wm_class;
+            int wm_class_offset, wm_class_len;
+
+            // WM_CLASS is nullbyte seperated: wm_instance + "\0Bar\0"
+            wm_class_offset = strlen(wm_instance) + 1;
+            wm_class_len = wm_class_offset + 4;
+
+            wm_class = calloc(1, wm_class_len + 1);
+            strcpy(wm_class, wm_instance);
+            strcpy(wm_class+wm_class_offset, "Bar");
+
+            xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, 
XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, wm_class_len, wm_class);
+
+            free(wm_class);
+        }
     }
 
+    char color[] = "#ffffff";
+    uint32_t nfgc = fgc.v & 0x00ffffff;
+    snprintf(color, sizeof(color), "#%06X", nfgc);
+
+    if (!XftColorAllocName (dpy, visual_ptr, colormap, color, &sel_fg)) {
+        fprintf(stderr, "Couldn't allocate xft font color '%s'\n", color);
+    }
     xcb_flush(c);
 }
@@ -1223,8 +1382,12 @@
 {
     free(area_stack.area);
-
-    for (int i = 0; i < font_count; i++) {
-        xcb_close_font(c, font_list[i]->ptr);
-        free(font_list[i]->width_lut);
+    for (int i = 0; font_list[i]; i++) {
+        if (font_list[i]->xft_ft) {
+            XftFontClose (dpy, font_list[i]->xft_ft);
+        }
+        else {
+            xcb_close_font(c, font_list[i]->ptr);
+            free(font_list[i]->width_lut);
+        }
         free(font_list[i]);
     }
@@ -1238,5 +1401,5 @@
     }
 
-    xcb_free_colormap(c, colormap);
+    XftColorFree(dpy, visual_ptr, colormap, &sel_fg);
 
     if (gc[GC_DRAW])
@@ -1250,4 +1413,19 @@
 }
 
+char*
+strip_path(char *path)
+{
+    char *slash;
+
+    if (path == NULL || *path == '\0')
+        return strdup("lemonbar");
+
+    slash = strrchr(path, '/');
+    if (slash != NULL)
+        return strndup(slash + 1, 31);
+
+    return strndup(path, 31);
+}
+
 void
 sighandle (int signal)
@@ -1257,4 +1435,5 @@
 }
 
+
 int
 main (int argc, char **argv)
@@ -1272,4 +1451,5 @@
     int ch, areas;
     char *wm_name;
+    char *instance_name;
 
     // Install the parachute!
@@ -1281,4 +1461,5 @@
     dbgc = bgc = (rgba_t)0x00000000U;
     dfgc = fgc = (rgba_t)0xffffffffU;
+
     dugc = ugc = fgc;
 
@@ -1287,11 +1468,13 @@
     wm_name = NULL;
 
+    instance_name = strip_path(argv[0]);
+
     // Connect to the Xserver and initialize scr
     xconn();
 
-    while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:U:n:")) != -1) {
+    while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:U:n:o:")) != -1) {
         switch (ch) {
             case 'h':
-                printf ("lemonbar version %s\n", VERSION);
+                printf ("lemonbar version %s patched with XFT support\n", 
VERSION);
                 printf ("usage: %s [-h | -g | -b | -d | -f | -a | -p | -n | -u 
| -B | -F]\n"
                         "\t-h Show this help\n"
@@ -1305,5 +1488,6 @@
                         "\t-u Set the underline/overline height in pixels\n"
                         "\t-B Set background color in #AARRGGBB\n"
-                        "\t-F Set foreground color in #AARRGGBB\n", argv[0]);
+                        "\t-F Set foreground color in #AARRGGBB\n"
+                        "\t-o Add a vertical offset to the text, it can be 
negative\n", argv[0]);
                 exit (EXIT_SUCCESS);
             case 'g': (void)parse_geometry_string(optarg, geom_v); break;
@@ -1314,4 +1498,5 @@
             case 'f': font_load(optarg); break;
             case 'u': bu = strtoul(optarg, NULL, 10); break;
+            case 'o': add_y_offset(strtol(optarg, NULL, 10)); break;
             case 'B': dbgc = bgc = parse_color(optarg, NULL, 
(rgba_t)0x00000000U); break;
             case 'F': dfgc = fgc = parse_color(optarg, NULL, 
(rgba_t)0xffffffffU); break;
@@ -1343,10 +1528,15 @@
 
     // Do the heavy lifting
-    init(wm_name);
+    init(wm_name, instance_name);
     // The string is strdup'd when the command line arguments are parsed
     free(wm_name);
+    // The string is strdup'd when stripping argv[0]
+    free(instance_name);
     // Get the fd to Xserver
     pollin[1].fd = xcb_get_file_descriptor(c);
 
+    // Prevent fgets to block
+    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
+       
     for (;;) {
         bool redraw = false;
@@ -1362,7 +1552,7 @@
             }
             if (pollin[0].revents & POLLIN) { // New input, process it
-                if (fgets(input, sizeof(input), stdin) == NULL)
-                    break; // EOF received
-
+                input[0] = '\0';
+                while (fgets(input, sizeof(input), stdin) != NULL)
+                    ; // Drain the buffer, the last line is actually used
                 parse(input);
                 redraw = true;
@@ -1387,5 +1577,5 @@
                                 }
                             }
-                            break;
+                        break;
                     }
 

Reply via email to