From e331fd63eaa51a51a6af06560bbe226a6d47fa16 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Wed, 13 May 2026 13:43:29 +0100 Subject: feat(notifications): persistent-pending model + wofi history picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Notifications now behave like a phone: pop briefly, auto-disappear, and remain "pending" until the user explicitly acknowledges them. The waybar count reflects pending only; idle uses a quieter glyph. State model: pending = ids in mako history/list MINUS dismissed-set state file: $XDG_RUNTIME_DIR/mako-dismissed (per-session id list) Glyph change: idle (0 pending) bell_outline U+F009C has pending bell_ring U+F009E (the previous bell_check_outline U+F11E8 "history present but nothing pending" branch is gone — there is no separate history concept now) Bindings (all now go through wrappers that maintain the dismissed-set): Super+n dismiss top visible + mark seen Super+Shift+n dismiss all visible + mark seen Super+Ctrl+n restore most recent + pop it from dismissed-set XF86Favorites history picker (rewritten on wofi) History picker (dot_config/waybar/executable_mako-history.py): - wofi --hide-search: arrow-only navigation, no fuzzy input - lines tagged [pending] / [seen] with app + summary + body - Enter re-emit via notify-send (re-shows the bubble) + mark seen - Alt-c copy "summary\nbody" to clipboard via wl-copy - Alt-d mark seen without re-showing - empty history shows a sentinel, no-op on Enter New scripts: executable_dismiss-visible.sh capture id(s) then makoctl dismiss executable_restore-pending.sh capture top-of-history id, restore, then drop that id from dismissed-set executable_mako-history.py Python rewrite (parses makoctl text output, drives wofi) Other: meta/wayland.txt add wofi (only used by this picker) dot_config/wofi/style.css minimal gruvbox style; hides input row as belt-and-suspenders even though --hide-search already does it --- dot_config/waybar/executable_mako-status.sh | 55 +++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 15 deletions(-) (limited to 'dot_config/waybar/executable_mako-status.sh') diff --git a/dot_config/waybar/executable_mako-status.sh b/dot_config/waybar/executable_mako-status.sh index 791aabe..a4fdd31 100644 --- a/dot_config/waybar/executable_mako-status.sh +++ b/dot_config/waybar/executable_mako-status.sh @@ -1,26 +1,51 @@ #!/bin/sh -# Emit waybar JSON with the mako notification count. Falls back to 0 when -# mako is not running so waybar doesn't blink errors. +# Waybar status: count of *pending* notifications, where pending = ids in +# mako's history that have NOT been explicitly dismissed by the user via +# Mod+n / Mod+Shift+n / the history picker. +# +# State file: $XDG_RUNTIME_DIR/mako-dismissed (per-session, plain id list). + set -eu if ! command -v makoctl >/dev/null 2>&1; then - printf '{"text":"","tooltip":"mako not installed","class":"off"}\n' + printf '{"text":"","tooltip":"mako not installed","class":"off"} +' exit 0 fi -count=$(makoctl history 2>/dev/null | grep -c '^Notification ' || true) -pending=$(makoctl list 2>/dev/null | grep -c '^Notification ' || true) +state=${XDG_RUNTIME_DIR:-/tmp}/mako-dismissed +: >>"$state" -if [ "$pending" -gt 0 ]; then - text="󰂞 $pending" - class="pending" -elif [ "$count" -gt 0 ]; then - text="󱇨 $count" - class="history" +# Visible notifications also count as pending (they aren't in history yet). +visible_ids=$(makoctl list -f '%i' 2>/dev/null || true) +history_ids=$(makoctl history -f '%i' 2>/dev/null || true) +all_ids=$(printf '%s +%s +' "$visible_ids" "$history_ids" \ + | grep -E '^[0-9]+$' | sort -u || true) + +# Prune stale ids (no longer present in mako) from the dismissed file. +if [ -s "$state" ] && [ -n "$all_ids" ]; then + tmp=$(mktemp) + printf '%s +' "$all_ids" >"$tmp.all" + grep -Fxf "$tmp.all" "$state" >"$tmp" 2>/dev/null || : + mv "$tmp" "$state" + rm -f "$tmp.all" +fi + +if [ -z "$all_ids" ]; then + pending=0 else - text="󰂜" - class="empty" + pending=$(printf '%s +' "$all_ids" | grep -Fxvf "$state" | grep -c . || true) fi -printf '{"text":"%s","tooltip":"%s pending / %s history","class":"%s"}\n' \ - "$text" "$pending" "$count" "$class" +if [ "$pending" -gt 0 ]; then + printf '{"text":"󰂞 %s","tooltip":"%s pending","class":"pending"} +' \ + "$pending" "$pending" +else + printf '{"text":"󰂜","tooltip":"no pending notifications","class":"empty"} +' +fi -- cgit v1.3.1