diff --git a/config.def.h b/config.def.h index 1797a9b..0699351 100644 --- a/config.def.h +++ b/config.def.h @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ -/* how often to update the statusbar (min value == 1) */ -static const int update_interval = 1; +/* interval between updates (in ms) */ +static const int interval = 1000; /* text to show if no value can be retrieved */ static const char unknown_str[] = "n/a"; diff --git a/slstatus.c b/slstatus.c index cd6cc8f..cc6174a 100644 --- a/slstatus.c +++ b/slstatus.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -71,7 +70,6 @@ static const char *wifi_perc(const char *iface); static const char *wifi_essid(const char *iface); char *argv0; -static unsigned short int delay = 0; static unsigned short int done; static Display *dpy; @@ -196,6 +194,7 @@ cpu_freq(void) static const char * cpu_perc(void) { + struct timespec delay; int n, perc; long double a[4], b[4]; FILE *fp; @@ -210,8 +209,9 @@ cpu_perc(void) if (n != 4) return unknown_str; - delay++; - sleep(delay); + delay.tv_sec = (interval / 2) / 1000; + delay.tv_nsec = ((interval / 2) % 1000) * 1000000; + nanosleep(&delay, NULL); fp = fopen("/proc/stat", "r"); if (fp == NULL) { @@ -842,6 +842,14 @@ terminate(const int signo) done = 1; } +static void +difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) +{ + res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec); + res->tv_nsec = a->tv_nsec - b->tv_nsec + + (a->tv_nsec < b->tv_nsec) * 1000000000; +} + static void usage(void) { @@ -852,12 +860,11 @@ usage(void) int main(int argc, char *argv[]) { - struct arg argument; struct sigaction act; + struct timespec start, current, diff, intspec, wait; size_t i, len; int sflag = 0; - char status_string[MAXLEN]; - char *element; + char status[MAXLEN]; ARGBEGIN { case 's': @@ -876,44 +883,42 @@ main(int argc, char *argv[]) sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - if (!sflag) { - dpy = XOpenDisplay(NULL); - if (!dpy) { - fprintf(stderr, "slstatus: cannot open display"); - exit(1); - } + if (!sflag && !(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "slstatus: cannot open display"); + return 1; } - setlocale(LC_ALL, ""); - while (!done) { - status_string[0] = '\0'; + clock_gettime(CLOCK_MONOTONIC, &start); - for (element = status_string, i = len = 0; i < LEN(args); - ++i, element += len) { - argument = args[i]; - len = snprintf(element, sizeof(status_string)-1 - len, - argument.fmt, - argument.func(argument.args)); - if (len >= sizeof(status_string)) { - status_string[sizeof(status_string)-1] = '\0'; - break; + status[0] = '\0'; + for (i = len = 0; i < LEN(args); i++) { + len += snprintf(status + len, sizeof(status) - len, + args[i].fmt, args[i].func(args[i].args)); + + if (len >= sizeof(status)) { + status[sizeof(status) - 1] = '\0'; } } if (sflag) { - printf("%s\n", status_string); + printf("%s\n", status); } else { - XStoreName(dpy, DefaultRootWindow(dpy), status_string); + XStoreName(dpy, DefaultRootWindow(dpy), status); XSync(dpy, False); } - if ((update_interval - delay) <= 0) { - delay = 0; - continue; - } else { - sleep(update_interval - delay); - delay = 0; + if (!done) { + clock_gettime(CLOCK_MONOTONIC, ¤t); + difftimespec(&diff, ¤t, &start); + + intspec.tv_sec = interval / 1000; + intspec.tv_nsec = (interval % 1000) * 1000000; + difftimespec(&wait, &intspec, &diff); + + if (wait.tv_sec >= 0) { + nanosleep(&wait, NULL); + } } }