I think Archcraft uses dunst to display a pop-up when you adjust your computer’s volume wheel. I was wondering what configuration files to take from Archcraft to do this in Mabox.
Removed previous post by @muzqs because suggestions where useless to @ArchcraftHater.
I think it must be some script, not only configuration file. Take a look at Openbox’s config file ~/.config/openbox/rc.xml
in Archcraft. Probably keybinds/mousebinds and commands are defined there.
ob-volume (83 lines) script needs dunst + icons. Not a big deal but copyright protected.
by Aditya Shakya
ob-volume --dec
ob-volume --inc
ob-volume --toggle
Thanks for the help. Adding this to rc.xml works but creates a new notification box below the previous one for every volume increment.
@ArchcraftHater
Maybe insering -t switch for dunstify in ob-volume. Find an optimal value.
notify_cmd='dunstify -u low -t 100 -h string:x-dunst-stack-tag:obvolume'
I forked pa-notify
@ArchcraftHater … Is this kinda what you where looking for.
edit: simplified notification.
@muzqs Tested and have some problems.
The ‘TITEL version’ I could fix and use it.
I’m not a C coder but defined TITEL as char[0] and could compile.
Due to external HDMI monitor I use pulseaudio and pulsemixer and
the night version as of 24 May does not work for me. pa-notify works fine(ly).
Update:
Added another option to build. Instructions available.
With manjaro-pulse (if it matters) it blocks audio.
In case I start volnotify after boot:
Translate ID error: '-1' is not a valid ID (returned by default-nodes-api)
otherwise it shows 74% and does not reflect the actual value.
the Satuday early version worked for me. It has been overwritten here.
I’m not part of the target audience at the moment.
@zolw thanks for testing.
i will have a look at pulse and alsa support how they behave.
need some time to look at that.
Not sure if it is this version you mentioned.
Summary
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnotify/notify.h>
typedef enum { BACKEND_NONE, BACKEND_WPCTL, BACKEND_PACTL, BACKEND_AMIXER } AudioBackend;
// Detect which audio backend command is available
AudioBackend detect_backend() {
if (system("which wpctl > /dev/null 2>&1") == 0)
return BACKEND_WPCTL;
else if (system("which pactl > /dev/null 2>&1") == 0)
return BACKEND_PACTL;
else if (system("which amixer > /dev/null 2>&1") == 0)
return BACKEND_AMIXER;
return BACKEND_NONE;
}
// Get volume level and mute status depending on backend
int get_volume(AudioBackend backend, float *volume, int *muted) {
FILE *fp;
char output[256];
switch (backend) {
case BACKEND_WPCTL:
fp = popen("wpctl get-volume @DEFAULT_SINK@", "r");
if (!fp) return -1;
if (fgets(output, sizeof(output), fp)) {
sscanf(output, "Volume: %f", volume);
*muted = strstr(output, "[MUTED]") != NULL;
}
pclose(fp);
break;
case BACKEND_PACTL:
fp = popen("pactl get-sink-mute @DEFAULT_SINK@ && pactl get-sink-volume @DEFAULT_SINK@", "r");
if (!fp) return -1;
*muted = 0;
*volume = 0;
while (fgets(output, sizeof(output), fp)) {
if (strstr(output, "Mute:")) {
*muted = strstr(output, "yes") != NULL;
} else if (strstr(output, "Volume:")) {
char *percent = strrchr(output, '%');
if (percent) {
int v = 0;
sscanf(percent - 3, "%d", &v); // read 3 chars before %
*volume = v / 100.0f;
}
}
}
pclose(fp);
break;
case BACKEND_AMIXER:
fp = popen("amixer get Master", "r");
if (!fp) return -1;
*volume = 0;
*muted = 0;
while (fgets(output, sizeof(output), fp)) {
if (strstr(output, "%")) {
int v = 0;
sscanf(output, "%*[^[][%d", &v); // get number between first [ and %
*volume = v / 100.0f;
*muted = strstr(output, "[off]") != NULL;
break;
}
}
pclose(fp);
break;
default:
return -1;
}
return 0;
}
// Create a volume bar made of full and empty blocks
void make_volume_bar(int percent, char *bar, size_t size) {
const char *full = "█";
const char *empty = "░";
int total_blocks = 10;
int blocks = (percent * total_blocks) / 100;
bar[0] = '\0';
for (int i = 0; i < total_blocks && strlen(bar) + strlen(full) < size - 1; i++) {
strcat(bar, i < blocks ? full : empty);
}
}
// Return an appropriate volume icon based on volume and mute status
const char* get_volume_icon(int percent, int muted) {
if (muted) return "🔇";
if (percent <= 0) return "🔈";
if (percent <= 30) return "🔉";
if (percent <= 75) return "🔉";
return "🔊";
}
int main(void) {
float volume = -1.0, prev_volume = -1.0;
int muted = -1, prev_muted = -1;
AudioBackend backend = detect_backend();
if (backend == BACKEND_NONE) {
fprintf(stderr, "No supported audio backend found (wpctl, pactl, amixer).\n");
return 1;
}
notify_init("pa-notify");
NotifyNotification *n = notify_notification_new("Volume", "", NULL);
notify_notification_set_hint(n, "transient", g_variant_new_boolean(FALSE)); // Persistent notification
while (1) {
if (get_volume(backend, &volume, &muted) == 0) {
if ((int)(volume * 100) != (int)(prev_volume * 100) || muted != prev_muted) {
prev_volume = volume;
prev_muted = muted;
char icon[10];
char bar[32];
char message[128];
int percent = (int)(volume * 100);
strcpy(icon, get_volume_icon(percent, muted));
if (muted) {
snprintf(message, sizeof(message), "%s %-10s %3s", icon, "Muted", "");
} else {
make_volume_bar(percent, bar, sizeof(bar));
snprintf(message, sizeof(message), "%s %-10s %3d%%", icon, bar, percent);
}
notify_notification_update(n, "Volume", message, NULL);
notify_notification_show(n, NULL);
}
}
usleep(200000); // Sleep 200ms before updating again
}
notify_uninit();
return 0;
}
Updated version.
volnotify-next version.
I read your manual. Yes it works on Pipewire. If my TV worked with
pipewire I would have been on it.
yay manjaro-pulse
makes the ‘migration’ and these 2 lines back to pipewire
yay -Rns pulseaudio-bluetooth manjaro-pulse pulseaudio
yay manjaro-pipewire
This works after removing dunst. However, the padding on top of the bar is too high. I don’t understand how the install script chooses which C file to compile.
Example Install latest .C file of the README.
The name is volnotify-next
1: Create backup of original .c file.
cp volnotify.c volnotify.c.bak2
2: after that do
cp volnotify-next.c volnotify.c
3: Finaly
./Install
I can’t change the padding at the top.
This is what i can do. I don’t know that mutch about C myself. (expirimental)
:BIRD