diff options
| author | Craig Jennings <c@cjennings.net> | 2026-01-25 19:31:39 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-01-25 19:31:39 -0600 |
| commit | be7fc75bdd2b9702106dd77b915361b70218104c (patch) | |
| tree | 13a8da39be83ae2c5836f12c403bb6dae4f69e26 | |
| parent | 4211501b901d530ee621399e07b81427ca497040 (diff) | |
feat(hyprland): add fuzzel launcher and pinentry-fuzzel
- Replace wofi with fuzzel in archsetup
- Add fuzzel config with waybar-matching theme
- Add pinentry-fuzzel script for GPG passphrase prompts
- Add Hyprland-specific gpg-agent.conf using pinentry-fuzzel
| -rwxr-xr-x | archsetup | 2 | ||||
| -rw-r--r-- | dotfiles/hyprland/.config/fuzzel/fuzzel.ini | 31 | ||||
| -rw-r--r-- | dotfiles/hyprland/.gnupg/gpg-agent.conf | 18 | ||||
| -rwxr-xr-x | dotfiles/hyprland/.local/bin/pinentry-fuzzel | 107 |
4 files changed, 157 insertions, 1 deletions
@@ -1305,7 +1305,7 @@ hyprland() { action="Hyprland Utilities" && display "subtitle" "$action" pacman_install waybar # status bar - pacman_install wofi # app launcher + pacman_install fuzzel # app launcher (native Wayland, pinentry support) pacman_install swww # wallpaper pacman_install grim # screenshot pacman_install slurp # region select diff --git a/dotfiles/hyprland/.config/fuzzel/fuzzel.ini b/dotfiles/hyprland/.config/fuzzel/fuzzel.ini new file mode 100644 index 0000000..ce46448 --- /dev/null +++ b/dotfiles/hyprland/.config/fuzzel/fuzzel.ini @@ -0,0 +1,31 @@ +# Fuzzel config - matching waybar DWM-inspired theme +# Colors from waybar: bg=#222222, cpu=#bbbbbb, clock=#eeeeee, accent=#daa520 + +[main] +font=BerkeleyMono Nerd Font:size=14 +prompt=Search: +icon-theme=hicolor +icons-enabled=yes +width=30 +lines=12 +horizontal-pad=20 +vertical-pad=12 +inner-pad=8 +layer=overlay +exit-on-keyboard-focus-loss=yes + +[colors] +# Format: RRGGBBAA +background=222222f0 +text=eeeeeeff +selection=daa520ff +selection-text=222222ff +border=daa520ff +match=daa520ff +prompt=bbbbbbff +placeholder=888888ff +input=eeeeeeff + +[border] +width=2 +radius=16 diff --git a/dotfiles/hyprland/.gnupg/gpg-agent.conf b/dotfiles/hyprland/.gnupg/gpg-agent.conf new file mode 100644 index 0000000..068f889 --- /dev/null +++ b/dotfiles/hyprland/.gnupg/gpg-agent.conf @@ -0,0 +1,18 @@ +# Pinentry configuration (Wayland/Hyprland) +pinentry-program ~/.local/bin/pinentry-fuzzel +pinentry-timeout 10 +allow-loopback-pinentry + +# Cache passphrases for entire login session (400 days) +default-cache-ttl 34560000 +max-cache-ttl 34560000 + +# Enable SSH support (use gpg-agent for SSH keys too) +enable-ssh-support + +# Prevent external programs from clearing cache +no-allow-external-cache + +# Keep running even when no connections +keep-display +keep-tty diff --git a/dotfiles/hyprland/.local/bin/pinentry-fuzzel b/dotfiles/hyprland/.local/bin/pinentry-fuzzel new file mode 100755 index 0000000..4cbe6b7 --- /dev/null +++ b/dotfiles/hyprland/.local/bin/pinentry-fuzzel @@ -0,0 +1,107 @@ +#!/bin/sh + +ENABLE_LOGGING="TRUE" +logger() { + if [ "$ENABLE_LOGGING" == "TRUE" ]; then + /usr/bin/logger -t "${0} [$]" "$@"; + fi +} + +# Decode URL-encoded characters (%0A = newline, %20 = space, etc.) +decode() { + printf '%b' "$(echo "$1" | sed 's/%\([0-9A-Fa-f][0-9A-Fa-f]\)/\\x\1/g')" +} + +# Base command and misc variables +DESC="" +PROMPT="" +COUNTFILE="/tmp/pinentry-fuzzel-count-$$" + +# Check if this is a repeat prompt (within 5 seconds of last) +LASTFILE="/tmp/pinentry-fuzzel-last" +NOW=$(date +%s) +if [ -f "$LASTFILE" ]; then + LAST=$(cat "$LASTFILE") + if [ $((NOW - LAST)) -lt 5 ]; then + REPEAT=1 + else + REPEAT=0 + fi +else + REPEAT=0 +fi +echo "$NOW" > "$LASTFILE" + +echo "OK Please go ahead" +while read cmd rest; do + logger "RAW=< ${cmd} ${rest} >" + logger "cmd=<${cmd}> rest=<${rest}>" + + case $cmd in + GETINFO) + case "$rest" in + flavor) + echo "D fuzzel" + echo "OK" + ;; + version) + echo "D 0.1" + echo "OK" + ;; + ttyinfo) + echo "D - - -" + echo "OK" + ;; + pid) + echo "D $$" + echo "OK" + ;; + esac + ;; + + SETDESC) + DESC=$(decode "$rest") + echo "OK" + ;; + + SETERROR) + logger "ERROR $rest" + # Silently acknowledge errors (e.g., empty passphrase on escape) + echo "OK" + ;; + + SETPROMPT) + PROMPT=$(decode "$rest") + # Remove trailing colon if present (we add our own) + PROMPT="${PROMPT%:}" + echo "OK" + ;; + + GETPIN | getpin) + if [ "$REPEAT" -eq 0 ]; then + LABEL="password: " + else + LABEL="reenter: " + fi + PASS=$(fuzzel --prompt "$LABEL" --width 25 --lines 0 --cache /dev/null --password --dmenu) + if [ -z "$PASS" ]; then + # User cancelled - return error to GPG + rm -f "$LASTFILE" + echo "ERR 83886179 Operation cancelled" + else + echo "D $PASS" + echo "OK" + fi + ;; + + BYE|bye) + echo "OK closing connection" + logger "EXITING" + exit 0 + ;; + + *) + echo "OK" + ;; + esac +done |
