From a521989933894ec45911de038629ccae1714387a Mon Sep 17 00:00:00 2001 From: Ryan Flannery Date: Thu, 10 Feb 2011 19:05:14 -0500 Subject: [PATCH 01/15] Use default width of screen-width rather than hardcoded 1280. From Alexander Polakov --- xstatbar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index f703ec2..2d7aaf2 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -58,7 +58,7 @@ main (int argc, char *argv[]) /* set defaults */ x = 0; y = 0; - w = 1280; + w = 0; h = 13; font = "*-fixed-*-9-*"; time_fmt = "%a %d %b %Y %I:%M:%S %p"; @@ -244,7 +244,7 @@ setup_x(int x, int y, int w, int h, const char *font) /* setup various defaults/settings */ XINFO.screen = DefaultScreen(XINFO.disp); - XINFO.width = w; + XINFO.width = w ? w : DisplayWidth(XINFO.disp, XINFO.screen); XINFO.height = h; XINFO.depth = DefaultDepth(XINFO.disp, XINFO.screen); XINFO.vis = DefaultVisual(XINFO.disp, XINFO.screen); From ea97ef1f0f5222f4823fafbc2efc9e3f5fce6ee5 Mon Sep 17 00:00:00 2001 From: Ryan Flannery Date: Thu, 10 Feb 2011 19:00:38 -0500 Subject: [PATCH 02/15] Patch from Alexander Polakov to add support for window manager hints (specifically _NET_WM_PARTIAL_STRUTS). --- xstatbar.c | 24 +++++++++++++++++++++++- xstatbar.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/xstatbar.c b/xstatbar.c index 2d7aaf2..83583e7 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -237,6 +237,8 @@ void setup_x(int x, int y, int w, int h, const char *font) { XSetWindowAttributes x11_window_attributes; + Atom type; + unsigned long struts[12]; /* open display */ if (!(XINFO.disp = XOpenDisplay(NULL))) @@ -249,7 +251,7 @@ setup_x(int x, int y, int w, int h, const char *font) XINFO.depth = DefaultDepth(XINFO.disp, XINFO.screen); XINFO.vis = DefaultVisual(XINFO.disp, XINFO.screen); XINFO.gc = DefaultGC(XINFO.disp, XINFO.screen); - x11_window_attributes.override_redirect = 1; + x11_window_attributes.override_redirect = 0; /* create window */ XINFO.win = XCreateWindow( @@ -261,6 +263,25 @@ setup_x(int x, int y, int w, int h, const char *font) CWOverrideRedirect, &x11_window_attributes ); + /* setup window manager hints */ + type = XInternAtom(XINFO.disp, "_NET_WM_WINDOW_TYPE_DOCK", False); + XChangeProperty(XINFO.disp, XINFO.win, XInternAtom(XINFO.disp, "_NET_WM_WINDOW_TYPE", False), + XA_ATOM, 32, PropModeReplace, (unsigned char*)&type, 1); + bzero(struts, sizeof(struts)); + enum { left, right, top, bottom, left_start_y, left_end_y, right_start_y, + right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x }; + if (y <= DisplayHeight(XINFO.disp, XINFO.screen)/2) { + struts[top] = y + XINFO.height; + struts[top_start_x] = x; + struts[top_end_x] = x + XINFO.width; + } else { + struts[bottom] = DisplayHeight(XINFO.disp, XINFO.screen) - y; + struts[bottom_start_x] = x; + struts[bottom_end_x] = x + XINFO.width; + } + XChangeProperty(XINFO.disp, XINFO.win, XInternAtom(XINFO.disp, "_NET_WM_STRUT_PARTIAL", False), + XA_CARDINAL, 32, PropModeReplace, (unsigned char*)struts, 12); + /* create pixmap used for double buffering */ XINFO.buf = XCreatePixmap( XINFO.disp, DefaultRootWindow(XINFO.disp), @@ -278,6 +299,7 @@ setup_x(int x, int y, int w, int h, const char *font) /* connect window to display */ XMapWindow(XINFO.disp, XINFO.win); + XMoveWindow(XINFO.disp, XINFO.win, x, y); /* setup colors */ setup_colors(); } diff --git a/xstatbar.h b/xstatbar.h index 4812ab0..655a724 100644 --- a/xstatbar.h +++ b/xstatbar.h @@ -20,6 +20,7 @@ /* X */ #include #include +#include #include /* structure to wrap all necessary x stuff */ From a6652349f121620b886bc95d9aa2872bda9be140 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 16:24:46 +0400 Subject: [PATCH 03/15] Skip 2 pixels from right and left Looks a bit better to me --- stats.c | 2 +- xstatbar.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stats.c b/stats.c index 80ff6d1..d6da89c 100644 --- a/stats.c +++ b/stats.c @@ -696,7 +696,7 @@ time_draw(XColor color, int x, int y) strftime(timestr, sizeof(timestr), time_fmt, localtime(&now)); /* XXX hack to right-align it - rethink a more general way for this */ - width = XTextWidth(XINFO.font, timestr, strlen(timestr)); + width = XTextWidth(XINFO.font, timestr, strlen(timestr)) + 2; return render_text(color, XINFO.width - width, y, timestr); } diff --git a/xstatbar.c b/xstatbar.c index 83583e7..f9bbc0a 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -330,7 +330,7 @@ draw() /* determine starting x and y */ y = XINFO.height - XINFO.font->descent; - x = 0; + x = 2; /* start drawing stats */ for (cpu = 0; cpu < sysinfo.ncpu; cpu++) From 04bb308c25a20c96e6ad6fc0f90a5f1045a4a3b3 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 16:27:04 +0400 Subject: [PATCH 04/15] Use COLOR_BLACK instead of BlackPixel() --- xstatbar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xstatbar.c b/xstatbar.c index f9bbc0a..b8a2936 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -324,7 +324,7 @@ draw() int cpu; /* paint over the existing pixmap */ - XSetForeground(XINFO.disp, XINFO.gc, BlackPixel(XINFO.disp, XINFO.screen)); + XSetForeground(XINFO.disp, XINFO.gc, COLOR_BLACK.pixel); XFillRectangle(XINFO.disp, XINFO.buf, XINFO.gc, 0, 0, XINFO.width, XINFO.height); From 53ad269736c64528a6e5f22961d29ae848a8fa98 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 16:28:04 +0400 Subject: [PATCH 05/15] Center text vertically --- xstatbar.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index b8a2936..fc69bd7 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -320,7 +320,7 @@ void draw() { static int spacing = 10; - int x, y; + int x, y, h; int cpu; /* paint over the existing pixmap */ @@ -329,7 +329,8 @@ draw() 0, 0, XINFO.width, XINFO.height); /* determine starting x and y */ - y = XINFO.height - XINFO.font->descent; + h = XINFO.font->ascent + XINFO.font->descent; + y = (XINFO.height / 2) - (h / 2) + XINFO.font->ascent; x = 2; /* start drawing stats */ From 0908adb09adfe148916f834bb0ff878ef67eb3e1 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 16:40:18 +0400 Subject: [PATCH 06/15] Store window name. This allows WM's to match on it. --- xstatbar.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xstatbar.c b/xstatbar.c index fc69bd7..f3f1b01 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -296,6 +296,7 @@ setup_x(int x, int y, int w, int h, const char *font) XSetFont(XINFO.disp, XINFO.gc, XINFO.font->fid); + XStoreName(XINFO.disp, XINFO.win, "xstatbar"); /* connect window to display */ XMapWindow(XINFO.disp, XINFO.win); From 917c6f3a60178baad76770ba4a23adc9683d7e16 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 16:58:51 +0400 Subject: [PATCH 07/15] Make use of X Resource Database for colors Correct lookup order (not implemented here): * classname in app-defaults directory * classname in XUSERFILESEARCHPATH & XAPPLRESDIR * XresourceManagerString() and ~/.Xdefaults * XENVIROMENT, if not set ~/.Xdefaults-hostname * command line. We do only (3). --- xstatbar.c | 40 +++++++++++++++++++++++++++++++++++----- xstatbar.h | 2 ++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index f3f1b01..ddaf3d4 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -193,6 +193,7 @@ void cleanup() { /* x teardown */ + XrmDestroyDatabase(XINFO.xrdb); XClearWindow(XINFO.disp, XINFO.win); XFreePixmap(XINFO.disp, XINFO.buf); XDestroyWindow(XINFO.disp, XINFO.win); @@ -206,6 +207,25 @@ cleanup() exit(0); } +/* get resource from X Resource database */ +const char * +get_resource(const char *resource) +{ + static char name[256], class[256], *type; + XrmValue value; + + if (!XINFO.xrdb) + return NULL; +#define RESCLASS "xstatbar" +#define RESNAME "XStatBar" + snprintf(name, sizeof(name), "%s.%s", RESNAME, resource); + snprintf(class, sizeof(class), "%s.%s", RESCLASS, resource); + XrmGetResource(XINFO.xrdb, name, class, &type, &value); + if (value.addr) + return value.addr; + return NULL; +} + /* setup all colors used */ void setup_colors() @@ -218,17 +238,21 @@ setup_colors() &COLOR_WHITE, &COLOR_BLACK }; const int num_colors = 8; + const char *color; + char resname[8]; int i; Colormap cm; cm = DefaultColormap(XINFO.disp, 0); for (i = 0; i < num_colors; i++) { - if (XParseColor(XINFO.disp, cm, color_names[i], xcolors[i]) == 0) - errx(1, "failed to parse color \"%s\"", color_names[i]); + snprintf(resname, sizeof(resname), "color%d", i); + color = get_resource(resname); + if (XParseColor(XINFO.disp, cm, color ? color : color_names[i], xcolors[i]) == 0) + errx(1, "failed to parse color \"%s\"", color ? color : color_names[i]); if (XAllocColor(XINFO.disp, cm, xcolors[i]) == 0) - errx(1, "failed to allocate color \"%s\"", color_names[i]); + errx(1, "failed to allocate color \"%s\"", color ? color : color_names[i]); } } @@ -239,11 +263,13 @@ setup_x(int x, int y, int w, int h, const char *font) XSetWindowAttributes x11_window_attributes; Atom type; unsigned long struts[12]; + char *xrms = NULL; /* open display */ if (!(XINFO.disp = XOpenDisplay(NULL))) errx(1, "can't open X11 display."); - + /* initialize resource manager */ + XrmInitialize(); /* setup various defaults/settings */ XINFO.screen = DefaultScreen(XINFO.disp); XINFO.width = w ? w : DisplayWidth(XINFO.disp, XINFO.screen); @@ -252,7 +278,11 @@ setup_x(int x, int y, int w, int h, const char *font) XINFO.vis = DefaultVisual(XINFO.disp, XINFO.screen); XINFO.gc = DefaultGC(XINFO.disp, XINFO.screen); x11_window_attributes.override_redirect = 0; - + if(!(XINFO.xrdb = XrmGetDatabase(XINFO.disp))) { + xrms = XResourceManagerString(XINFO.disp); + if (xrms) + XINFO.xrdb = XrmGetStringDatabase(xrms); + } /* create window */ XINFO.win = XCreateWindow( XINFO.disp, DefaultRootWindow(XINFO.disp), diff --git a/xstatbar.h b/xstatbar.h index 655a724..f9720a3 100644 --- a/xstatbar.h +++ b/xstatbar.h @@ -21,6 +21,7 @@ #include #include #include +#include #include /* structure to wrap all necessary x stuff */ @@ -31,6 +32,7 @@ typedef struct xinfo { Visual *vis; GC gc; XFontStruct *font; + XrmDatabase xrdb; int screen; int depth; From a2d4e720197e9634458402afd8ab669cba60430a Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 21:26:31 +0400 Subject: [PATCH 08/15] Add new color COLOR_GREY for future use --- xstatbar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index ddaf3d4..e1195bd 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -30,7 +30,7 @@ xinfo_t XINFO; XColor COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN, - COLOR_WHITE, COLOR_BLACK; + COLOR_WHITE, COLOR_BLACK, COLOR_GREY; /* signal flags */ @@ -231,13 +231,13 @@ void setup_colors() { static char *color_names[] = { "red", "green", "blue", "yellow", - "magenta", "cyan", "white", "black" }; + "magenta", "cyan", "white", "black", "grey" }; static XColor *xcolors[] = { &COLOR_RED, &COLOR_GREEN, &COLOR_BLUE, &COLOR_YELLOW, &COLOR_MAGENTA, &COLOR_CYAN, - &COLOR_WHITE, &COLOR_BLACK }; + &COLOR_WHITE, &COLOR_BLACK, &COLOR_GREY }; - const int num_colors = 8; + const int num_colors = 9; const char *color; char resname[8]; int i; From 906b4c5a1a50de6e6a452f95ce1d021240b9bdc4 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Fri, 25 Nov 2011 21:31:54 +0400 Subject: [PATCH 09/15] Inner border support * it's drawn inside the window * set width with -b (0 by default) * window border isn't used because some WMs reset it to 0 --- stats.c | 11 +++++++++++ stats.h | 1 + xstatbar.1 | 4 ++++ xstatbar.c | 19 ++++++++++++++----- xstatbar.h | 1 + 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/stats.c b/stats.c index d6da89c..a7a7f09 100644 --- a/stats.c +++ b/stats.c @@ -700,3 +700,14 @@ time_draw(XColor color, int x, int y) return render_text(color, XINFO.width - width, y, timestr); } +int +border_draw(XColor color, int x, int y) +{ + int bw = XINFO.border; + if (!bw) + return 0; + XSetForeground(XINFO.disp, XINFO.gc, color.pixel); + XSetLineAttributes(XINFO.disp, XINFO.gc, bw, LineSolid, CapNotLast, JoinMiter); + XDrawRectangle(XINFO.disp, XINFO.buf, XINFO.gc, bw/2, bw/2, XINFO.width-bw, XINFO.height-bw); + return 0; +} diff --git a/stats.h b/stats.h index 36805c4..6e743b0 100644 --- a/stats.h +++ b/stats.h @@ -135,5 +135,6 @@ int cpu_draw(int cpu, XColor c, int x, int y); int mem_draw(XColor c, int x, int y); int procs_draw(XColor c, int x, int y); int time_draw(XColor c, int x, int y); +int border_draw(XColor c, int x, int y); #endif diff --git a/xstatbar.1 b/xstatbar.1 index 1ce7fb0..83a084b 100644 --- a/xstatbar.1 +++ b/xstatbar.1 @@ -68,6 +68,10 @@ edit the source. .Pp The following options are supported: .Bl -tag -width Fl +.It Fl b Ar width +Inner border width, in pixels. +.Pp +The default is 0. .It Fl x Ar offset The x coordinate, in pixels, of the upper-left corner of the window. .Pp diff --git a/xstatbar.c b/xstatbar.c index e1195bd..78aca62 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -42,7 +42,7 @@ void signal_handler(int sig); void process_signals(); void cleanup(); void usage(const char *pname); -void setup_x(int x, int y, int w, int h, const char *font); +void setup_x(int x, int y, int w, int h, int b, const char *font); void draw(); @@ -52,7 +52,7 @@ main (int argc, char *argv[]) const char *errstr; char *font; char ch; - int x, y, w, h; + int x, y, w, h, b; int sleep_seconds; /* set defaults */ @@ -60,13 +60,20 @@ main (int argc, char *argv[]) y = 0; w = 0; h = 13; + b = 0; font = "*-fixed-*-9-*"; time_fmt = "%a %d %b %Y %I:%M:%S %p"; sleep_seconds = 1; /* parse command line */ - while ((ch = getopt(argc, argv, "x:y:w:h:s:f:t:T")) != -1) { + while ((ch = getopt(argc, argv, "b:x:y:w:h:s:f:t:T")) != -1) { switch (ch) { + case 'b': + b = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(1, "illegal b value \"%s\": %s", optarg, errstr); + break; + case 'x': x = strtonum(optarg, 0, INT_MAX, &errstr); if (errstr) @@ -127,7 +134,7 @@ main (int argc, char *argv[]) sysinfo_init(45); /* setup X window */ - setup_x(x, y, w, h, font); + setup_x(x, y, w, h, b, font); /* shutdown function */ signal(SIGINT, signal_handler); @@ -258,7 +265,7 @@ setup_colors() /* setup x window */ void -setup_x(int x, int y, int w, int h, const char *font) +setup_x(int x, int y, int w, int h, int b, const char *font) { XSetWindowAttributes x11_window_attributes; Atom type; @@ -274,6 +281,7 @@ setup_x(int x, int y, int w, int h, const char *font) XINFO.screen = DefaultScreen(XINFO.disp); XINFO.width = w ? w : DisplayWidth(XINFO.disp, XINFO.screen); XINFO.height = h; + XINFO.border = b; XINFO.depth = DefaultDepth(XINFO.disp, XINFO.screen); XINFO.vis = DefaultVisual(XINFO.disp, XINFO.screen); XINFO.gc = DefaultGC(XINFO.disp, XINFO.screen); @@ -373,6 +381,7 @@ draw() x += power_draw(COLOR_WHITE, x, y) + spacing; x += volume_draw(COLOR_WHITE, x, y) + spacing; time_draw(COLOR_CYAN, x, y); + border_draw(COLOR_GREY, 0, 0); /* copy the buffer to the window and flush */ XCopyArea(XINFO.disp, XINFO.buf, XINFO.win, XINFO.gc, diff --git a/xstatbar.h b/xstatbar.h index f9720a3..b7b491a 100644 --- a/xstatbar.h +++ b/xstatbar.h @@ -38,6 +38,7 @@ typedef struct xinfo { int depth; unsigned int width; unsigned int height; + unsigned int border; } xinfo_t; extern xinfo_t XINFO; From 5a4def402b8e0e906d7a65d46bcf6374cd0fea9f Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Sat, 26 Nov 2011 02:29:25 +0400 Subject: [PATCH 10/15] Make cpu_draw() to be like other *_draw functions --- stats.c | 14 +++++++++++++- stats.h | 2 +- xstatbar.c | 5 +---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/stats.c b/stats.c index a7a7f09..19e7c8d 100644 --- a/stats.c +++ b/stats.c @@ -512,7 +512,7 @@ sysinfo_close() } int -cpu_draw(int cpu, XColor color, int x, int y) +cpu_draw_one(int cpu, XColor color, int x, int y) { static char str[1000]; static char *cpuStateNames[] = { "u", "n", "s", "i", "I" }; @@ -587,6 +587,18 @@ cpu_draw(int cpu, XColor color, int x, int y) return x - startx; } +int +cpu_draw(XColor color, int x, int y) +{ + int cpu, startx; + int spacing = 10; + + startx = x; + for (cpu = 0; cpu < sysinfo.ncpu; cpu++) + x += cpu_draw_one(cpu, COLOR_WHITE, x, y) + spacing; + return x - startx; +} + int mem_draw(XColor color, int x, int y) { diff --git a/stats.h b/stats.h index 6e743b0..49b1528 100644 --- a/stats.h +++ b/stats.h @@ -131,7 +131,7 @@ void sysinfo_close(); int volume_draw(XColor c, int x, int y); int power_draw(XColor c, int x, int y); -int cpu_draw(int cpu, XColor c, int x, int y); +int cpu_draw(XColor c, int x, int y); int mem_draw(XColor c, int x, int y); int procs_draw(XColor c, int x, int y); int time_draw(XColor c, int x, int y); diff --git a/xstatbar.c b/xstatbar.c index 78aca62..b545d34 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -360,7 +360,6 @@ draw() { static int spacing = 10; int x, y, h; - int cpu; /* paint over the existing pixmap */ XSetForeground(XINFO.disp, XINFO.gc, COLOR_BLACK.pixel); @@ -373,9 +372,7 @@ draw() x = 2; /* start drawing stats */ - for (cpu = 0; cpu < sysinfo.ncpu; cpu++) - x += cpu_draw(cpu, COLOR_WHITE, x, y) + spacing; - + x += cpu_draw(COLOR_WHITE, x, y) + spacing; x += mem_draw(COLOR_WHITE, x, y) + spacing; x += procs_draw(COLOR_WHITE, x, y) + spacing; x += power_draw(COLOR_WHITE, x, y) + spacing; From 1472f541e73464256a58389842fc8a8e662b2df9 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Sat, 26 Nov 2011 02:35:13 +0400 Subject: [PATCH 11/15] Introduce struct applet At the moment it contains applet drawing function and color argument. Can be extended for something more interesting. This allows us to iterate over an array of applets. --- xstatbar.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index b545d34..191c4bf 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -45,6 +45,18 @@ void usage(const char *pname); void setup_x(int x, int y, int w, int h, int b, const char *font); void draw(); +struct applet { + int (*draw) (XColor, int, int); + XColor *color; +} applets[] = { + { cpu_draw, &COLOR_WHITE }, + { mem_draw, &COLOR_WHITE }, + { procs_draw, &COLOR_WHITE }, + { power_draw, &COLOR_WHITE }, + { volume_draw, &COLOR_WHITE }, + { time_draw, &COLOR_CYAN }, + { border_draw, &COLOR_GREY }, +}; int main (int argc, char *argv[]) @@ -359,7 +371,7 @@ void draw() { static int spacing = 10; - int x, y, h; + int x, y, h, i; /* paint over the existing pixmap */ XSetForeground(XINFO.disp, XINFO.gc, COLOR_BLACK.pixel); @@ -371,14 +383,9 @@ draw() y = (XINFO.height / 2) - (h / 2) + XINFO.font->ascent; x = 2; - /* start drawing stats */ - x += cpu_draw(COLOR_WHITE, x, y) + spacing; - x += mem_draw(COLOR_WHITE, x, y) + spacing; - x += procs_draw(COLOR_WHITE, x, y) + spacing; - x += power_draw(COLOR_WHITE, x, y) + spacing; - x += volume_draw(COLOR_WHITE, x, y) + spacing; - time_draw(COLOR_CYAN, x, y); - border_draw(COLOR_GREY, 0, 0); + /* draw stats */ + for (i = 0; i < sizeof(applets)/sizeof(applets[0]); i++) + x += applets[i].draw(*(applets[i].color), x, y) + spacing; /* copy the buffer to the window and flush */ XCopyArea(XINFO.disp, XINFO.buf, XINFO.win, XINFO.gc, From 7bdc7b5a8a35106b5e33063f3dc15520d090ace6 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Sat, 26 Nov 2011 02:48:42 +0400 Subject: [PATCH 12/15] Implement `grow-only' policy for applets So they don't move from left to right and back. --- stats.c | 11 ++++++++--- xstatbar.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/stats.c b/stats.c index 19e7c8d..1c79d29 100644 --- a/stats.c +++ b/stats.c @@ -591,11 +591,16 @@ int cpu_draw(XColor color, int x, int y) { int cpu, startx; - int spacing = 10; + int nw, spacing = 10; + static int width = 0; startx = x; - for (cpu = 0; cpu < sysinfo.ncpu; cpu++) - x += cpu_draw_one(cpu, COLOR_WHITE, x, y) + spacing; + for (cpu = 0; cpu < sysinfo.ncpu; cpu++) { + nw = cpu_draw_one(cpu, COLOR_WHITE, x, y) + spacing; + width = nw > width ? nw : width; + x += width; + } + x -= spacing; /* trailing spacing */ return x - startx; } diff --git a/xstatbar.c b/xstatbar.c index 191c4bf..8b73134 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -48,6 +48,7 @@ void draw(); struct applet { int (*draw) (XColor, int, int); XColor *color; + int width; } applets[] = { { cpu_draw, &COLOR_WHITE }, { mem_draw, &COLOR_WHITE }, @@ -371,7 +372,7 @@ void draw() { static int spacing = 10; - int x, y, h, i; + int x, y, h, i, w; /* paint over the existing pixmap */ XSetForeground(XINFO.disp, XINFO.gc, COLOR_BLACK.pixel); @@ -384,8 +385,12 @@ draw() x = 2; /* draw stats */ - for (i = 0; i < sizeof(applets)/sizeof(applets[0]); i++) - x += applets[i].draw(*(applets[i].color), x, y) + spacing; + for (i = 0; i < sizeof(applets)/sizeof(applets[0]); i++) { + w = applets[i].draw(*(applets[i].color), x, y); + if (w > applets[i].width) + applets[i].width = w + spacing; + x += applets[i].width; + } /* copy the buffer to the window and flush */ XCopyArea(XINFO.disp, XINFO.buf, XINFO.win, XINFO.gc, From 1d898ac3d2b9681ddcc56485b01eac4d917ca85f Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Sat, 26 Nov 2011 03:18:40 +0400 Subject: [PATCH 13/15] Use select instead of sleep() and handle Expose events --- xstatbar.c | 56 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index 8b73134..f673227 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -13,6 +13,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include #include #include #include @@ -67,6 +69,10 @@ main (int argc, char *argv[]) char ch; int x, y, w, h, b; int sleep_seconds; + fd_set rd; + int xfd, rv; + struct timeval tv; + XEvent ev; /* set defaults */ x = 0; @@ -148,25 +154,42 @@ main (int argc, char *argv[]) /* setup X window */ setup_x(x, y, w, h, b, font); + xfd = ConnectionNumber(XINFO.disp); /* shutdown function */ - signal(SIGINT, signal_handler); + signal(SIGINT, signal_handler); - while (1) { - - /* handle any signals */ - process_signals(); - - /* update stats */ - volume_update(); - power_update(); - sysinfo_update(); + volume_update(); + power_update(); + sysinfo_update(); - /* draw */ - draw(); - - /* sleep */ - sleep(sleep_seconds); + while (1) { + tv.tv_sec = sleep_seconds; + tv.tv_usec = 0; + FD_ZERO(&rd); + FD_SET(xfd, &rd); + + rv = select(xfd + 1, &rd, NULL, NULL, &tv); + if (rv == -1) { + process_signals(); + perror("select()"); + return 1; + } else if (rv > 0) { /* X event */ + while (XPending(XINFO.disp)) { + XNextEvent(XINFO.disp, &ev); + if (ev.type == Expose) + draw(); + } + } else if (rv == 0) { /* timeout */ + /* handle any signals */ + process_signals(); + /* update stats */ + volume_update(); + power_update(); + sysinfo_update(); + /* draw */ + draw(); + } } /* UNREACHABLE */ @@ -298,6 +321,7 @@ setup_x(int x, int y, int w, int h, int b, const char *font) XINFO.depth = DefaultDepth(XINFO.disp, XINFO.screen); XINFO.vis = DefaultVisual(XINFO.disp, XINFO.screen); XINFO.gc = DefaultGC(XINFO.disp, XINFO.screen); + x11_window_attributes.event_mask = ExposureMask; x11_window_attributes.override_redirect = 0; if(!(XINFO.xrdb = XrmGetDatabase(XINFO.disp))) { xrms = XResourceManagerString(XINFO.disp); @@ -311,7 +335,7 @@ setup_x(int x, int y, int w, int h, int b, const char *font) XINFO.width, XINFO.height, 1, CopyFromParent, InputOutput, XINFO.vis, - CWOverrideRedirect, &x11_window_attributes + CWOverrideRedirect|CWEventMask, &x11_window_attributes ); /* setup window manager hints */ From ef704fd0af63c750280344424c3fc2bf2f7680d9 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Tue, 29 Nov 2011 21:50:31 +0400 Subject: [PATCH 14/15] Invert swap detection logic (nswaps == 0 means no swap) --- stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stats.c b/stats.c index 1c79d29..99c5c29 100644 --- a/stats.c +++ b/stats.c @@ -443,7 +443,7 @@ sysinfo_update() /* get swap status */ sysinfo.swap_used = sysinfo.swap_total = 0; - if ((nswaps = swapctl(SWAP_NSWAP, 0, 0)) == 0) { + if ((nswaps = swapctl(SWAP_NSWAP, 0, 0)) != 0) { if ((swapdev = calloc(nswaps, sizeof(*swapdev))) == NULL) err(1, "sysinfo update: swapdev calloc failed (%d)", nswaps); if (swapctl(SWAP_STATS, swapdev, nswaps) == -1) From 04ef8c8dd58392a61d2f07887a23bd517695a9b3 Mon Sep 17 00:00:00 2001 From: Alexander Polakov Date: Tue, 4 Dec 2012 03:42:56 +0400 Subject: [PATCH 15/15] Change the order of colors to match XTerm resources --- xstatbar.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xstatbar.c b/xstatbar.c index f673227..ffdea18 100644 --- a/xstatbar.c +++ b/xstatbar.c @@ -273,12 +273,12 @@ get_resource(const char *resource) void setup_colors() { - static char *color_names[] = { "red", "green", "blue", "yellow", - "magenta", "cyan", "white", "black", "grey" }; + static char *color_names[] = { "black", "red", "green", "blue", "yellow", + "magenta", "cyan", "white", "grey" }; - static XColor *xcolors[] = { &COLOR_RED, &COLOR_GREEN, &COLOR_BLUE, - &COLOR_YELLOW, &COLOR_MAGENTA, &COLOR_CYAN, - &COLOR_WHITE, &COLOR_BLACK, &COLOR_GREY }; + static XColor *xcolors[] = { &COLOR_BLACK, &COLOR_RED, &COLOR_GREEN, + &COLOR_BLUE, &COLOR_YELLOW, &COLOR_MAGENTA, &COLOR_CYAN, + &COLOR_WHITE, &COLOR_GREY }; const int num_colors = 9; const char *color;