Custom Waybar modules for Sway, Hyprland, and other Wayland compositors. Nord-themed with animated hover effects.
- battering — Battery status with charging/discharging icons and color-coded low/mid/full states
- whyguard — WireGuard VPN switcher: scroll to select interface, click to toggle, color-coded online/offline/dead status
- clockodo — Clockodo time tracking: click to start/stop, shows daily total with work/break/overtime states
- claude — Claude Code session usage percentage via Anthropic OAuth API
- mako-history — Mako notification history with unread count and interactive fzf viewer
- JSON output for Waybar's
custommodule system - CSS class-based state styling (color-coded borders and hover fills)
- Nord color palette
- Animated fill-up hover gradients
- Systemd user service for WireGuard state polling
- Exponential backoff for API rate limits (claude)
jq— all scriptscurl— clockodopython3— claudefzf— mako-history viewermakoctl— mako-historyalacritty— mako-history viewer terminalswaymsg— mako-history viewer (focus app on selection, replace withhyprctlfor Hyprland)wg-quick,sudo— whyguard
Color palette used across all modules (Nord theme):
@define-color bg #3b4252;
@define-color bg-module #434c5e;
@define-color fg #d8dee9;
@define-color hover #5e81ac;
@define-color urgent #bf616a;
@define-color urgent-hover #E5989F;
@define-color negative #ebcb8b;
@define-color negative-hover #C29D53;
@define-color positive #a3be8c;
@define-color positive-hover #7FA062;Shared base styling (apply to all custom modules):
#custom-battering,
#custom-whyguard,
#custom-clockodo,
#custom-claude,
#custom-notifications {
background-color: @bg-module;
padding: 0 10px;
color: @fg;
}Waybar config:
Styling:
#custom-battering.low {
color: @urgent;
border-bottom: 3px solid @urgent;
}
#custom-battering.mid,
#custom-battering.full {
border-bottom: 3px solid @fg;
}Waybar config:
"custom/notifications": {
"exec": "$HOME/.config/waybar/scripts/mako-history/mako-history.sh --count",
"on-click": "$HOME/.config/waybar/scripts/mako-history/mako-history.sh --show",
"return-type": "json",
"format": "{text}",
"tooltip": false,
"interval": 5
}Styling:
#custom-notifications {
background-image: linear-gradient(to top, @hover 100%, transparent 100%);
background-size: 100% 0%;
background-repeat: no-repeat;
background-position: bottom;
border-bottom: 3px solid @fg;
transition:
background-size 0.25s ease,
border-bottom 0.2s ease;
}
#custom-notifications:hover {
background-size: 100% 100%;
}
#custom-notifications.new {
border-bottom: 3px solid @urgent;
background-image: linear-gradient(to top, @urgent-hover 100%, transparent 100%);
}Requires a polling daemon to update interface state. Install:
cp whyguard/whyguard-daemon.sh ~/.local/bin/whyguard
cp whyguard/whyguard-daemon.service ~/.config/systemd/user/
cp whyguard/whyguard.example.json ~/.local/state/whyguard.json
systemctl --user enable --now whyguard-daemon.servicePasswordless sudo for wg-quick and wg. Add to /etc/sudoers.d/whyguard:
youruser ALL=(ALL) NOPASSWD: /usr/bin/wg-quick up *, /usr/bin/wg-quick down *, /usr/bin/wg show *
Waybar config:
"custom/whyguard": {
"exec": "$HOME/.config/waybar/scripts/whyguard/whyguard.sh --show",
"on-click": "$HOME/.config/waybar/scripts/whyguard/whyguard.sh --toggle",
"on-click-right": "$HOME/.config/waybar/scripts/whyguard/whyguard.sh --right",
"on-scroll-up": "$HOME/.config/waybar/scripts/whyguard/whyguard.sh --left",
"on-scroll-down": "$HOME/.config/waybar/scripts/whyguard/whyguard.sh --right",
"return-type": "json",
"format": " {text} ",
"tooltip": false,
"interval": 2
}Styling:
#custom-whyguard {
transition: background-size 0.25s ease;
}
#custom-whyguard.offline {
border-bottom: 3px solid @fg;
background-image: linear-gradient(to top, @hover 100%, transparent 100%);
}
#custom-whyguard.offline:hover {
background-size: 100% 100%;
}
#custom-whyguard.dead {
border-bottom: 3px solid @urgent;
background-image: linear-gradient(to top, @urgent-hover 100%, transparent 100%);
}
#custom-whyguard.dead:hover {
background-size: 100% 100%;
}
#custom-whyguard.online {
border-bottom: 3px solid @positive;
background-image: linear-gradient(to top, @positive-hover 100%, transparent 100%);
}
#custom-whyguard.online:hover {
background-size: 100% 100%;
}Requires Claude Code to be installed — the script reads the OAuth token from ~/.claude/.credentials.json (created automatically on login).
Waybar config:
"custom/claude": {
"exec": "$HOME/.config/waybar/scripts/claude/claude.py",
"return-type": "json",
"format": "{text}",
"tooltip": true,
"interval": 60
}Styling:
#custom-claude {
border-bottom: 3px solid @fg;
transition: background-size 0.25s ease;
}Requires environment variables:
CLOCKODO_EMAIL=your-email@example.com
CLOCKODO_TOKEN=your-api-token
Known issue: The first "break" of the day before any clock entry may show incorrect duration.
Waybar config:
"custom/clockodo": {
"exec": "$HOME/.config/waybar/scripts/clockodo/clockodo.sh --status",
"on-click": "$HOME/.config/waybar/scripts/clockodo/clockodo.sh --toggle",
"return-type": "json",
"format": " {text} ",
"tooltip": false,
"interval": 1
}Styling:
#custom-clockodo {
transition: background-size 0.25s ease;
}
#custom-clockodo.work {
border-bottom: 3px solid @positive;
background-image: linear-gradient(to top, @positive-hover 100%, transparent 100%);
}
#custom-clockodo.work:hover {
background-size: 100% 100%;
}
#custom-clockodo.break {
border-bottom: 3px solid @fg;
background-image: linear-gradient(to top, @hover 100%, transparent 100%);
}
#custom-clockodo.break:hover {
background-size: 100% 100%;
}
#custom-clockodo.overtime {
border-bottom: 3px solid @urgent;
color: @fg;
background-color: @urgent-hover;
background-image: linear-gradient(to top, @urgent-hover 100%, transparent 100%);
}
#custom-clockodo.overtime:hover {
background-size: 100% 100%;
}MIT
