dwmbar: Create a DWM Status Bar
DWM is a window manager and its status bar is a customizable piece of text on the top right of the screen. I wrote a C program that populates the status bar with the time and ALSA volume, in the format of Thu Aug 11 11:03:23 AM EDT 2022 [ 36% ]
.
The code to set the window manager's name using Xlib was copied from dwmstatus. Compile with gcc main.c $(pkg-config --cflags --libs x11 alsa) -O3 -o dwmbar
.
#include <X11/Xlib.h>
#include <alsa/asoundlib.h>
#include <alsa/mixer.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
bool run = true;
void sigint_handler() {
run = false;
}
double get_volume(snd_mixer_t *handle) {
snd_mixer_handle_events(handle);
snd_mixer_selem_id_t *sid;
snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, "Master");
long min, max, volume;
snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume);
return (double)volume / (max/100);
}
snd_mixer_t *create_handle(void) {
snd_mixer_t *handle;
snd_mixer_open(&handle, 0);
snd_mixer_attach(handle, "default");
snd_mixer_selem_register(handle, NULL, NULL);
snd_mixer_load(handle);
return handle;
}
int main(void) {
Display *dpy = XOpenDisplay(NULL);
snd_mixer_t *handle = create_handle();
signal(SIGINT, sigint_handler);
while(run) {
char bar[128];
time_t t = time(NULL);
struct tm *tm = localtime(&t);
int n = strftime(bar, sizeof(bar), " %a %b %d %r %Z %Y ", tm);
sprintf(bar+n, "[ %.0f%% ]", get_volume(handle));
XStoreName(dpy, DefaultRootWindow(dpy), bar);
XSync(dpy, False);
usleep(1000000);
}
snd_mixer_close(handle);
XCloseDisplay(dpy);
}