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;
}