From 436d0abf80aa48553f8894a78c0fe82c5187b99e Mon Sep 17 00:00:00 2001 From: Thierry Pouplier Date: Wed, 6 May 2026 14:52:10 +0000 Subject: [PATCH] feat: disk space monitor with desktop notifications + waybar indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a disk monitor script that warns via notify-send (swaync) when disk usage exceeds 85% (warning) or 92% (critical), and shows a color-coded indicator in the waybar. Changes: - waybar/scripts/disk-monitor.sh — monitoring script with 3 modes: * daemon: background check every 5 min, sends desktop notifications * waybar: one-shot JSON for waybar custom module * check: single check for manual use - hyprland.conf — exec-once for daemon mode (runs on login) - config.jsonc — added custom/disk-monitor to modules-right - modules.json — custom module definition (60s refresh, color-coded) - style.css — normal/warning/critical styles with blink animation Usage: Normal: shows 💾 / 45% (green) Warning: 🟡 / 85% (orange) Critical: 🔴 / 92% (red, blinking) --- hypr/.config/hypr/hyprland.conf | 1 + waybar/.config/waybar/config.jsonc | 1 + waybar/.config/waybar/modules.json | 8 ++ waybar/.config/waybar/scripts/disk-monitor.sh | 119 ++++++++++++++++++ waybar/.config/waybar/style.css | 22 ++++ 5 files changed, 151 insertions(+) create mode 100755 waybar/.config/waybar/scripts/disk-monitor.sh diff --git a/hypr/.config/hypr/hyprland.conf b/hypr/.config/hypr/hyprland.conf index 8a57593..a8ecb53 100644 --- a/hypr/.config/hypr/hyprland.conf +++ b/hypr/.config/hypr/hyprland.conf @@ -73,6 +73,7 @@ exec-once = swww img ~/.config/wallpapers/green_yellow_forest.jpg --outputs $EXT exec-once = swww img ~/.config/wallpapers/buck_head.jpg --outputs $EXTERNAL_R1 exec-once = swww img ~/.config/wallpapers/buck_head.jpg --outputs $EXTERNAL_R2 exec-once = swaync +exec-once = ~/.config/waybar/scripts/disk-monitor.sh daemon exec-once = hypridle exec-once = hyprlock exec-once = /usr/bin/emacs --daemon diff --git a/waybar/.config/waybar/config.jsonc b/waybar/.config/waybar/config.jsonc index 22cf676..ed264d3 100644 --- a/waybar/.config/waybar/config.jsonc +++ b/waybar/.config/waybar/config.jsonc @@ -25,6 +25,7 @@ "modules-right": [ "group/hardware", + "custom/disk-monitor", "pulseaudio", "bluetooth", "network", diff --git a/waybar/.config/waybar/modules.json b/waybar/.config/waybar/modules.json index 80d301e..513e1f4 100644 --- a/waybar/.config/waybar/modules.json +++ b/waybar/.config/waybar/modules.json @@ -158,4 +158,12 @@ "on-click": "wlogout -b 2", "tooltip": false }, + + // disk space monitor (background daemon for notifications) + "custom/disk-monitor": { + "exec": "~/.config/waybar/scripts/disk-monitor.sh waybar", + "return-type": "json", + "interval": 60, + "signal": 8 + } } diff --git a/waybar/.config/waybar/scripts/disk-monitor.sh b/waybar/.config/waybar/scripts/disk-monitor.sh new file mode 100755 index 0000000..4555bd2 --- /dev/null +++ b/waybar/.config/waybar/scripts/disk-monitor.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +# Disk Space Monitor — warns you before you hit the wall. +# +# Two integration points: +# 1. Waybar: add "custom/disk" to modules-right in config.jsonc +# 2. Hyprland: add exec-once = ... disk-monitor.sh daemon +# +# Install: +# cp disk-monitor.sh ~/.config/waybar/scripts/ +# chmod +x ~/.config/waybar/scripts/disk-monitor.sh + +set -euo pipefail + +WARN_PCT=85 +CRIT_PCT=92 + +# ─── helpers ──────────────────────────────────────────────────────────────── + +_notify() { + local urgency="$1" title="$2" body="$3" + notify-send -u "$urgency" -a "disk-monitor" "$title" "$body" +} + +# ─── commands ─────────────────────────────────────────────────────────────── + +cmd_check() { + local alerts="" + local any_alert=false + + while IFS= read -r line; do + # Skip headers and pseudo-filesystems + target=$(echo "$line" | awk '{print $1}') + pct=$(echo "$line" | awk '{print $2}' | tr -d '%') + used=$(echo "$line" | awk '{print $3}') + size=$(echo "$line" | awk '{print $4}') + avail=$(echo "$line" | awk '{print $5}') + + case "$target" in + /dev|/sys|/proc|/run|tmpfs|devtmpfs|none|udev|overlay|shm|devpts|mqueue|pts) continue ;; + /boot*) continue ;; + *) ;; + esac + + if [ "$pct" -ge "$CRIT_PCT" ]; then + any_alert=true + alerts+="🔴 $target ${pct}% (${avail} free)\n" + elif [ "$pct" -ge "$WARN_PCT" ]; then + any_alert=true + alerts+="🟡 $target ${pct}% (${avail} free)\n" + fi + done < <(df -h --output=target,pcent,used,size,avail | tail -n +2) + + if [ -z "$alerts" ]; then + return 0 + fi + if echo "$alerts" | grep -q "🔴"; then + _notify critical "🚨 Disk CRITICAL" "$alerts" + else + _notify normal "⚠️ Disk space low" "$alerts" + fi +} + +cmd_daemon() { + local interval="${1:-300}" + echo "disk-monitor: checking every ${interval}s, warn@${WARN_PCT}% crit@${CRIT_PCT}%" + cmd_check + while true; do + sleep "$interval" + cmd_check + done +} + +cmd_waybar() { + local worst_pct=0 + local worst_target="/" + local tooltip="" + + while IFS= read -r line; do + target=$(echo "$line" | awk '{print $1}') + pct=$(echo "$line" | awk '{print $2}' | tr -d '%') + used=$(echo "$line" | awk '{print $3}') + size=$(echo "$line" | awk '{print $4}') + avail=$(echo "$line" | awk '{print $5}') + + case "$target" in + /dev|/sys|/proc|/run|tmpfs|devtmpfs|none|udev|overlay|shm|devpts|mqueue|pts) continue ;; + /boot*) continue ;; + *) ;; + esac + + tooltip+="${target}: ${pct}% (${avail} free)\\n" + [ "$pct" -gt "$worst_pct" ] && { worst_pct=$pct; worst_target=$target; } + done < <(df -h --output=target,pcent,used,size,avail | tail -n +2) + + local icon class + if [ "$worst_pct" -ge "$CRIT_PCT" ]; then + icon="🔴"; class="critical" + elif [ "$worst_pct" -ge "$WARN_PCT" ]; then + icon="🟡"; class="warning" + else + icon="💾"; class="normal" + fi + + printf '{"text": " %s %s %d%% ", "tooltip": "%s", "class": "%s"}\n' \ + "$icon" "$worst_target" "$worst_pct" "$tooltip" "$class" +} + +case "${1:-help}" in + daemon) cmd_daemon "${2:-300}" ;; + waybar|w) cmd_waybar ;; + check|notify) cmd_check ;; + *) + echo "Usage: $(basename "$0") {daemon|waybar|check}" + echo " daemon Background check every 5 min, desktop notifications" + echo " waybar One-shot JSON for Waybar custom module" + echo " check Single check, prints to stdout" + exit 1 + ;; +esac diff --git a/waybar/.config/waybar/style.css b/waybar/.config/waybar/style.css index a916161..d154dfc 100644 --- a/waybar/.config/waybar/style.css +++ b/waybar/.config/waybar/style.css @@ -213,6 +213,28 @@ tooltip label { } /* custom modules */ +#custom-disk-monitor { + margin: 0px 0px 0px 5px; + padding: 1px 8px 0px 8px; + font-size: 16px; + color: @text; + border-radius: 5px; + background-color: @set; +} +#custom-disk-monitor.warning { + background-color: #ff9a3c; + color: #FFFFFF; +} +#custom-disk-monitor.critical { + background-color: #dc2f2f; + color: #FFFFFF; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + #custom-exit { margin: 0px 18px 0px 5px; padding: 0px; -- 2.49.1