If you use GPG, you are probably familiar with the situation where suddenly the pinentry program pops up and interrupts whatever you're doing. Maybe you're in the middle of a game, maybe you are deeply engrossed in tracking down a bug, whatever. That pinentry is *intrusive*; it interrupts your thoughts and your actions, demanding immediate attention.
I was not surprised to find questions online asking how to make it non-intrusive; I *was* surprised that there was no solution offered. Eventually, after walking me into a nest of Biters one too many times, I hacked together a solution.
Caveat lector, as usual. For me, all this affects is the background syncing of my email and calendar, which is fairly infrequent in any case. It *blocks* pinentry until you tell it to go ahead and show you the dialog. You can check its state by calling it with `--bar`; it'll return `!!` if it needs attention, and `X` if it doesn't. This can be used to put the status in a bar, like i3bar or polybar. If your bar allows interactions, you can have it call the script with `--yes` on click, which will unblock the script and call your pinentry GUI.
Hopefully this helps other people fix a curious omission in the whole GPG pinentry workflow.
#!/bin/sh # A non-intrusive GPG pinentry. # The purpose of this script is to prevent GPG's pinentry from popping up and # interrupting the user. It does this by blocking on a lockfile; running it # with an argument removes the lockfile and unblocks the script, which can # then call the pinentry GUI program. # # HOW TO USE # 1. `cp THISSCRIPT ~/.local/bin/pinentry-preexec` # 2. `chmod +x ~/.local/bin/pinentry-preexec` # 3. Edit ~/.gnupg/gpg-agent.conf and change (or add) the line: # `pinentry-program ${HOME}/.local/bin/pinentry-preexec` # 4. Optionally, if you're using a WM bar, call this script with # the `--bar` argument to get the status of the agent, and set # the action command to `--yes`. An example for polybar is at the # end of this file. # 5. Reload your gpg agent: # `gpg-connect-agent reloadagent /bye` # 6. Test it! Do something to trigger pinentry. PINENTRY=/usr/bin/pinentry-rofi LOCKDIR="${HOME}/.local/share/pinentry-preexec" LOCKFILE="${LOCKDIR}/lock" UNBLOCKED="X" BLOCKED="!!" test -d "$LOCKDIR" || mkdir "$LOCKDIR" test "$1" == "--bar" && ( test -f "$LOCKFILE" && echo -n "$BLOCKED" || echo -n "$UNBLOCKED" ) && exit 0 test "$1" == "--yes" && rm -f "$LOCKFILE" && exit 0 test -f "$LOCKFILE" || touch "$LOCKFILE" while [[ -f "$LOCKFILE" ]]; do sleep 1 done rm -f "$LOCKFILE" exec $PINENTRY "$@" ############################################################################### # Polybar configuration example ############################################################################### # # # Create a module... # # [module/pinentry] # type = custom/script # interval = 1 # label-padding = 1 # exec = ${env:HOME}/.local/bin/pinentry-preexec --bar # click-left = ${env:HOME}/.local/bin/pinentry-preexec --yes # # # ... and add the module to your bar # # modules-right = alsa fm pinentry powermenu