diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-12 10:03:54 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-12 10:03:54 +0200 |
| commit | 9cf3aaea8cc356a87321f3a8df96fdf68ff921b0 (patch) | |
| tree | 257c0591e876eddc835f15e7263f9fbb471587f1 /mail-overview | |
| parent | c747c95c49e681160da8de7f4fe3eed6adc47bba (diff) | |
| download | quickshell-9cf3aaea8cc356a87321f3a8df96fdf68ff921b0.tar.gz quickshell-9cf3aaea8cc356a87321f3a8df96fdf68ff921b0.zip | |
feat(mail-overview): waybar watcher in continuous mode
Prints one JSON line per notmuch commit rather than polling on an interval,
so the count drops the moment mail is read in qtmaildir and rises the moment
mbsync commits, and waybar owns the watcher process: nothing to supervise on
a machine with no systemd.
The watch is on the xapian directory, not on a file inside it, because a
commit replaces files and a watch held on a filename dies with it. The short
sleep coalesces the several writes of one commit into one redraw.
notmuch exits 0 even for a malformed query, printing something that is not a
count, so the output is validated as an integer rather than trusting the exit
status. A failure there renders as an error glyph: a count that silently
reads zero would look exactly like an empty inbox.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
Diffstat (limited to 'mail-overview')
| -rwxr-xr-x | mail-overview/waybar-mail.sh | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/mail-overview/waybar-mail.sh b/mail-overview/waybar-mail.sh new file mode 100755 index 0000000..06f8427 --- /dev/null +++ b/mail-overview/waybar-mail.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# Waybar custom module in continuous mode: prints one JSON line per notmuch +# commit, forever, and waybar redraws on each line. Waybar owns this process, +# which is why there is no daemon to supervise and no interval to tune. +# +# The count is the total across every account. A per account breakdown is the +# drawer's job; see mail-overview/README.md. + +set -u + +QUERY='tag:unread and tag:inbox' + +# notmuch knows where its own database is, so this follows a moved database +# without an edit here. +db="$(notmuch config get database.path 2>/dev/null)/xapian" + +emit() { + local n + n="$(notmuch count "$QUERY" 2>/dev/null)" + + # notmuch exits 0 even for a malformed query, printing something that is + # not a count, so the exit status is not the test: the output is. Anything + # that is not a plain number is a failure, and a failure must not render + # as "no new mail". + if [[ ! "$n" =~ ^[0-9]+$ ]]; then + printf '{"text":"!","tooltip":"notmuch count failed","class":"error"}\n' + return + fi + + if [[ "$n" -eq 0 ]]; then + printf '{"text":"","class":"empty"}\n' + else + printf '{"text":"%s","class":"unread"}\n' "$n" + fi +} + +if [[ ! -d "$db" ]]; then + printf '{"text":"!","tooltip":"no notmuch database","class":"error"}\n' + exit 1 +fi + +emit + +while inotifywait -qq -e close_write,moved_to "$db" 2>/dev/null; do + # One commit touches several files. Without this the module redraws three + # or four times per sync with intermediate counts. + sleep 0.3 + emit +done + +# Falling out of the loop means inotifywait itself failed. Say so rather than +# exiting silently, which looks like an empty inbox. +printf '{"text":"!","tooltip":"mail watcher stopped","class":"error"}\n' +exit 1 |
