From 318a6e23cf30f371a4174a1313e21ecb04eb6b0f Mon Sep 17 00:00:00 2001 From: Alan Sikora Date: Sat, 23 Aug 2025 03:26:31 -0300 Subject: [PATCH] Add status indicator cluster for waybar (#570) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add notification status indicator to waybar Adds a visual indicator in the waybar to show when notifications are silenced (do-not-disturb mode). - Shows a red dot when notifications are disabled - Shows a dimmed dot when notifications are enabled - Clicking the indicator toggles do-not-disturb mode - Syncs with the existing SUPER+CTRL+, keyboard shortcut This provides immediate visual feedback about notification status, making it easier for users to know when they've silenced notifications. * feat: Convert to unified status cluster that only shows active states - Only displays indicators when states are actually active - Supports multiple status types: DND, night light, screen recording, idle lock - Uses distinct symbols: • for DND, ◐ for night light, ● for recording, ◯ for idle lock - Completely hides module when no states are active (no visual clutter) - Extensible design for future status indicators - Improved performance with better error handling * Implement lightweight hybrid status monitoring * Enhance notification status cluster with modular design * Add waybar configuration for status cluster * Add recording click handler and fix process detection - Add wl-screenrec detection for non-nvidia systems - Add click handler to start/stop recording - Fix idle lock toggle functionality * minor alignment tweaks * improved recording detection to be more specific * Rely on Omarchy bin in PATH and lower interval to feel more snappy * Seperate out screencording stop so it doesn't start when trying to stop OBS * Add migration to add the status notifications --------- Co-authored-by: David Heinemeier Hansson --- bin/omarchy-cmd-screenrecord-stop | 7 ++++ bin/omarchy-status-daemon | 64 +++++++++++++++++++++++++++++++ bin/omarchy-status-dnd | 9 +++++ bin/omarchy-status-idle | 9 +++++ bin/omarchy-status-nightlight | 14 +++++++ bin/omarchy-status-recording | 12 ++++++ config/waybar/config.jsonc | 35 +++++++++++++++++ config/waybar/style.css | 32 ++++++++++++++++ migrations/1755930114.sh | 3 ++ 9 files changed, 185 insertions(+) create mode 100755 bin/omarchy-cmd-screenrecord-stop create mode 100755 bin/omarchy-status-daemon create mode 100755 bin/omarchy-status-dnd create mode 100755 bin/omarchy-status-idle create mode 100755 bin/omarchy-status-nightlight create mode 100755 bin/omarchy-status-recording create mode 100644 migrations/1755930114.sh diff --git a/bin/omarchy-cmd-screenrecord-stop b/bin/omarchy-cmd-screenrecord-stop new file mode 100755 index 00000000..5631920c --- /dev/null +++ b/bin/omarchy-cmd-screenrecord-stop @@ -0,0 +1,7 @@ +#!/bin/bash + +if pgrep -x wl-screenrec >/dev/null || pgrep -x wf-recorder >/dev/null; then + pkill -x wl-screenrec + pkill -x wf-recorder + notify-send "Screen recording stopped" -t 2000 +fi diff --git a/bin/omarchy-status-daemon b/bin/omarchy-status-daemon new file mode 100755 index 00000000..6fffb22b --- /dev/null +++ b/bin/omarchy-status-daemon @@ -0,0 +1,64 @@ +#!/bin/bash + +# Status indicator daemon for waybar +# Calls individual status scripts and caches results + +STATE_DIR="/tmp/omarchy-status" +DAEMON_PID_FILE="$STATE_DIR/daemon.pid" +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" + +mkdir -p "$STATE_DIR" + +# Update all status files by calling individual scripts +update_all_status_files() { + "$SCRIPT_DIR/omarchy-status-dnd" > "$STATE_DIR/dnd" + "$SCRIPT_DIR/omarchy-status-nightlight" > "$STATE_DIR/nightlight" + "$SCRIPT_DIR/omarchy-status-recording" > "$STATE_DIR/recording" + "$SCRIPT_DIR/omarchy-status-idle" > "$STATE_DIR/idle" +} + +# Generate hash for change detection +get_status_hash() { + echo "$(pgrep -c "mako|hyprsunset|wl-screenrec|wf-recorder|obs|hypridle" 2>/dev/null)$(makoctl mode 2>/dev/null | grep -c 'do-not-disturb')$(hyprctl hyprsunset temperature 2>/dev/null)" +} + +# Start background monitoring daemon +start_daemon() { + if [ -f "$DAEMON_PID_FILE" ] && kill -0 $(cat "$DAEMON_PID_FILE") 2>/dev/null; then + return 0 + fi + + { + last_hash="" + while true; do + current_hash=$(get_status_hash) + + if [ "$current_hash" != "$last_hash" ]; then + update_all_status_files + last_hash="$current_hash" + fi + + sleep 0.5 + done + } & + + echo $! > "$DAEMON_PID_FILE" +} + +# Main execution +MODULE="$1" + +if [ -z "$MODULE" ]; then + echo "Usage: $0 [dnd|nightlight|recording|idle]" + exit 1 +fi + +start_daemon + +# Return cached status for requested module +if [ -f "$STATE_DIR/$MODULE" ]; then + cat "$STATE_DIR/$MODULE" +else + update_all_status_files + cat "$STATE_DIR/$MODULE" 2>/dev/null || echo '{"text": "", "tooltip": "", "class": "hidden"}' +fi diff --git a/bin/omarchy-status-dnd b/bin/omarchy-status-dnd new file mode 100755 index 00000000..a8936600 --- /dev/null +++ b/bin/omarchy-status-dnd @@ -0,0 +1,9 @@ +#!/bin/bash + +# DND status indicator + +if makoctl mode 2>/dev/null | grep -q 'do-not-disturb'; then + echo '{"text": "󰂛", "tooltip": "Notifications silenced", "class": "status-dnd"}' +else + echo '{"text": "", "tooltip": "", "class": "hidden"}' +fi diff --git a/bin/omarchy-status-idle b/bin/omarchy-status-idle new file mode 100755 index 00000000..2d4dd9a6 --- /dev/null +++ b/bin/omarchy-status-idle @@ -0,0 +1,9 @@ +#!/bin/bash + +# Idle lock status indicator + +if command -v hypridle >/dev/null 2>&1 && ! pgrep -x hypridle >/dev/null 2>&1; then + echo '{"text": "󱫖", "tooltip": "Idle lock disabled", "class": "status-idle"}' +else + echo '{"text": "", "tooltip": "", "class": "hidden"}' +fi diff --git a/bin/omarchy-status-nightlight b/bin/omarchy-status-nightlight new file mode 100755 index 00000000..d5853328 --- /dev/null +++ b/bin/omarchy-status-nightlight @@ -0,0 +1,14 @@ +#!/bin/bash + +# Nightlight status indicator + +if pgrep -x hyprsunset >/dev/null 2>&1; then + temp=$(hyprctl hyprsunset temperature 2>/dev/null | grep -oE '[0-9]+') + if [ -n "$temp" ] && [ "$temp" -lt 6000 ]; then + echo '{"text": "󰔎", "tooltip": "Night light active", "class": "status-nightlight"}' + else + echo '{"text": "", "tooltip": "", "class": "hidden"}' + fi +else + echo '{"text": "", "tooltip": "", "class": "hidden"}' +fi diff --git a/bin/omarchy-status-recording b/bin/omarchy-status-recording new file mode 100755 index 00000000..72a98378 --- /dev/null +++ b/bin/omarchy-status-recording @@ -0,0 +1,12 @@ +#!/bin/bash + +# Recording status indicator + +if pgrep -x wl-screenrec >/dev/null 2>&1 || \ + pgrep -x wf-recorder >/dev/null 2>&1 || \ + pgrep -x obs >/dev/null 2>&1 || \ + pgrep -f "ffmpeg.*(x11grab|gdigrab|avfoundation)" >/dev/null 2>&1; then + echo '{"text": "󰻂", "tooltip": "Screen recording active", "class": "status-recording"}' +else + echo '{"text": "", "tooltip": "", "class": "hidden"}' +fi diff --git a/config/waybar/config.jsonc b/config/waybar/config.jsonc index ddbbfeeb..cec169de 100644 --- a/config/waybar/config.jsonc +++ b/config/waybar/config.jsonc @@ -9,6 +9,7 @@ "hyprland/workspaces" ], "modules-center": [ + "group/status-cluster", "clock", "custom/update" ], @@ -56,6 +57,7 @@ "tooltip-format": "Omarchy update available", "interval": 3600 }, + "cpu": { "interval": 5, "format": "󰍛", @@ -131,6 +133,39 @@ "tray" ] }, + "group/status-cluster": { + "orientation": "inherit", + "modules": [ + "custom/status-dnd", + "custom/status-nightlight", + "custom/status-recording", + "custom/status-idle" + ] + }, + "custom/status-dnd": { + "exec": "omarchy-status-daemon dnd", + "return-type": "json", + "interval": 1, + "on-click": "makoctl mode -t do-not-disturb" + }, + "custom/status-nightlight": { + "exec": "omarchy-status-daemon nightlight", + "return-type": "json", + "interval": 1, + "on-click": "omarchy-toggle-nightlight" + }, + "custom/status-recording": { + "exec": "omarchy-status-daemon recording", + "return-type": "json", + "interval": 1, + "on-click": "omarchy-cmd-screenrecord-stop" + }, + "custom/status-idle": { + "exec": "omarchy-status-daemon idle", + "return-type": "json", + "interval": 1, + "on-click": "omarchy-toggle-idle" + }, "custom/expand-icon": { "format": " ", "tooltip": false diff --git a/config/waybar/style.css b/config/waybar/style.css index 20a394e9..bb64ab03 100644 --- a/config/waybar/style.css +++ b/config/waybar/style.css @@ -53,3 +53,35 @@ tooltip { #custom-update { font-size: 10px; } + +#clock { + margin-left: 8.75px; +} + +#group-status-cluster { + margin-right: 8.75px; +} + +#custom-status-dnd, +#custom-status-nightlight, +#custom-status-recording, +#custom-status-idle { + min-width: 12px; + margin: 0 2px; + font-size: 10px; +} + +#custom-status-dnd.status-dnd, +#custom-status-nightlight.status-nightlight, +#custom-status-idle.status-idle { + opacity: 1; +} + +#custom-status-recording.status-recording { + color: #a55555; + opacity: 1; +} + +.hidden { + opacity: 0; +} diff --git a/migrations/1755930114.sh b/migrations/1755930114.sh new file mode 100644 index 00000000..8327f746 --- /dev/null +++ b/migrations/1755930114.sh @@ -0,0 +1,3 @@ +echo "Add status indicators for screen recordings, nightlight, dnd, and idle lock to Waybar" +echo +gum confirm "Replace current Waybar config (backup will be made)?" && omarchy-refresh-waybar