diff options
| author | Thomas Irgang <info@tomirgang.de> | 2026-08-16 10:16:46 +0200 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2026-08-29 21:41:34 -0700 |
| commit | 9423a676432fe9aa40675e4cdf94a4736e6f5a64 (patch) | |
| tree | e0e2999bf9d6a13b5b911bdf7bba992337371fc5 | |
| parent | f5897674f6f94d39499263a7dd21ffc667abd9ba (diff) | |
fix: Toggle all Waybar clock modules between 12H and 24H (#95)
ToggleWaybarTime.sh matched each clock format with its own hardcoded sed
pattern. Two of those patterns were missing the {:L...} locale prefix that
the corresponding lines in Modules carry:
Modules "format": "{:L%H:%M - %d/%b}"
script "format": "{:%H:%M - %d/%b}"
so clock#3 and clock#4 were never switched. clock#vertical was not covered
at all, because the script only ever edited Modules and never
ModulesVertical. sed -i reports no error when nothing matches, so the
script still restarted Waybar and claimed success while those modules kept
their previous format.
Replace the 18 hardcoded patterns with a table of 12H/24H format pairs and
build the sed expressions from it, so both directions are derived from the
same source of truth. Add ModulesVertical to the files being edited, and
list the Nerd Font glyphs as codepoints (U+F017, U+F073) rather than
literal characters, which are easy to replace with a look-alike from a
different Private Use range without any visible difference.
Warn on stderr about formats that no longer occur in any modules file, and
exit non-zero instead of restarting Waybar when a toggle changed nothing at
all, so future drift surfaces instead of failing silently.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
| -rwxr-xr-x | config/hypr/scripts/ToggleWaybarTime.sh | 142 |
1 files changed, 116 insertions, 26 deletions
diff --git a/config/hypr/scripts/ToggleWaybarTime.sh b/config/hypr/scripts/ToggleWaybarTime.sh index 54eefb57..ac58ec20 100755 --- a/config/hypr/scripts/ToggleWaybarTime.sh +++ b/config/hypr/scripts/ToggleWaybarTime.sh @@ -7,7 +7,48 @@ # ================================================== # Toggle Waybar clock format between 12H and 24H -MODULES_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/Modules" +WAYBAR_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/waybar" + +# Files that hold toggleable clock formats +MODULES_FILES=( + "$WAYBAR_DIR/Modules" # clock, clock#2, clock#3, clock#4, clock#5 + "$WAYBAR_DIR/ModulesVertical" # clock#vertical +) + +# Nerd Font clock glyph (U+F017) used by the "clock" and "clock#2" formats. +# Spelled out as a codepoint on purpose: a literal glyph here is easy to +# replace with a look-alike from a different Private Use range, which would +# make the patterns below stop matching without any visible difference. +CLOCK_GLYPH=$'\uf017' +# Nerd Font calendar glyph (U+F073), used by the clock#vertical formats +CAL_GLYPH=$'\uf073' + +# Clock format pairs. FORMATS_12H[n] and FORMATS_24H[n] belong to the same +# module: toggling comments out the one and uncomments the other. +# +# The strings must match the "format" values in MODULES_FILES *verbatim*, +# including the {:L...} locale prefix and every space. A format that is not +# listed here, or listed with a typo, is silently left on whatever it is +# currently set to - so keep this list in sync when adding or editing a clock +# module. +FORMATS_12H=( + "$CLOCK_GLYPH {:%I:%M %p}" # clock + "$CLOCK_GLYPH {:%I:%M %p}" # clock#2 + '{:L%I:%M %p - %d/%b}' # clock#3 + '{:L%B | %a %d, %Y | %I:%M %p}' # clock#4 + '{:%A, %I:%M %P}' # clock#5 + "$CLOCK_GLYPH\n{:%I\n%M\n%p\n\n$CAL_GLYPH \n%d\n%m\n%y}" # clock#vertical +) + +FORMATS_24H=( + "$CLOCK_GLYPH {:%H:%M:%S}" # clock + "$CLOCK_GLYPH {:%H:%M}" # clock#2 + '{:L%H:%M - %d/%b}' # clock#3 + '{:L%B | %a %d, %Y | %H:%M}' # clock#4 + '{:%a %d | %H:%M}' # clock#5 + "$CLOCK_GLYPH\n{:%H\n%M\n%S\n\n$CAL_GLYPH \n%d\n%m\n%y}" # clock#vertical +) + notify_swaync() { command -v notify-send >/dev/null 2>&1 || return 0 export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" @@ -22,37 +63,75 @@ notify_swaync() { notify-send -a "Waybar Time" -u low -t 2000 -i "$icon" "$@" >/dev/null 2>&1 || true } -if [ ! -f "$MODULES_FILE" ]; then - notify_swaync "Modules file not found: $MODULES_FILE" +# Only work on the files that are actually present +FILES=() +for f in "${MODULES_FILES[@]}"; do + [ -f "$f" ] && FILES+=("$f") +done + +if [ "${#FILES[@]}" -eq 0 ]; then + notify_swaync "No Waybar modules file found in: $WAYBAR_DIR" exit 1 fi +# Escape the characters that are special inside a sed BRE, plus the '#' we use +# as the s/// delimiter. Needed because the formats contain '.', '*' and the +# literal backslashes of clock#vertical. +escape_bre() { + printf '%s' "$1" | sed 's/[][\\.*^$#]/\\&/g' +} + +# Comment out / re-enable the "format" line carrying the given format string +comment_out() { + local file="$1" esc + esc=$(escape_bre "$2") + sed -i "s#^\([[:space:]]*\)\(\"format\":[[:space:]]*\"${esc}\".*\)#\1//\2#" "$file" +} + +uncomment() { + local file="$1" esc + esc=$(escape_bre "$2") + sed -i "s#^\([[:space:]]*\)//[[:space:]]*\(\"format\":[[:space:]]*\"${esc}\".*\)#\1\2#" "$file" +} + +# $1: 12h | 24h +apply_format() { + local target="$1" file i + for file in "${FILES[@]}"; do + for i in "${!FORMATS_12H[@]}"; do + if [ "$target" = "24h" ]; then + comment_out "$file" "${FORMATS_12H[$i]}" + uncomment "$file" "${FORMATS_24H[$i]}" + else + comment_out "$file" "${FORMATS_24H[$i]}" + uncomment "$file" "${FORMATS_12H[$i]}" + fi + done + done +} + +# True when any clock module is currently on a 12H format. %I is the 12-hour +# hour and appears in every 12H format; the anchor skips commented lines. is_12h_active() { - grep -qE '^[[:space:]]*"format":[[:space:]]*" {:%I:%M %p}"' "$MODULES_FILE" + grep -qE '^[[:space:]]*"format":.*%I' "${FILES[@]}" } -apply_12h() { - sed -i 's#^\([[:space:]]*\)//\("format": " {:%I:%M %p}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": " {:%H:%M:%S}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": " {:%H:%M}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": "{:%I:%M %p - %d/%b}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": "{:%H:%M - %d/%b}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": "{:%B | %a %d, %Y | %I:%M %p}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": "{:%B | %a %d, %Y | %H:%M}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": "{:%A, %I:%M %P}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": "{:%a %d | %H:%M}".*\)#\1//\2#' "$MODULES_FILE" +snapshot() { + cat "${FILES[@]}" | cksum } -apply_24h() { - sed -i 's#^\([[:space:]]*\)\("format": " {:%I:%M %p}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": " {:%H:%M:%S}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": " {:%H:%M}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": "{:%I:%M %p - %d/%b}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": "{:%H:%M - %d/%b}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": "{:%B | %a %d, %Y | %I:%M %p}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": "{:%B | %a %d, %Y | %H:%M}".*\)#\1\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)\("format": "{:%A, %I:%M %P}".*\)#\1//\2#' "$MODULES_FILE" - sed -i 's#^\([[:space:]]*\)//\("format": "{:%a %d | %H:%M}".*\)#\1\2#' "$MODULES_FILE" +# Report formats that are not present in any modules file at all. Catches the +# case where a format above drifts away from the modules files, which would +# otherwise leave that one clock module silently stuck on its old setting. +warn_unknown_formats() { + local i missing=0 + for i in "${!FORMATS_12H[@]}"; do + grep -qF "\"${FORMATS_12H[$i]}\"" "${FILES[@]}" || + { printf 'Waybar Time: 12H format not found in any modules file: %s\n' "${FORMATS_12H[$i]}" >&2; missing=1; } + grep -qF "\"${FORMATS_24H[$i]}\"" "${FILES[@]}" || + { printf 'Waybar Time: 24H format not found in any modules file: %s\n' "${FORMATS_24H[$i]}" >&2; missing=1; } + done + return $missing } restart_waybar() { @@ -88,14 +167,25 @@ restart_waybar() { fi } +warn_unknown_formats || true + +before=$(snapshot) + if is_12h_active; then - apply_24h + apply_format 24h mode="24H" else - apply_12h + apply_format 12h mode="12H" fi +# Nothing replaced means the formats above drifted away from the modules files +if [ "$before" = "$(snapshot)" ]; then + notify_swaync "Clock format unchanged - no known format matched" + printf 'Waybar Time: no clock format matched, nothing changed\n' >&2 + exit 1 +fi + restart_waybar sleep 0.3 |
