diff --git a/.gnupg/gpg-agent.conf b/.gnupg/gpg-agent.conf
index 2569ab926883f5f42e71cd3d699329d1f5881395..ea69a24ff7e7ca39200b2f31ee53ae176c828990 100644
--- a/.gnupg/gpg-agent.conf
+++ b/.gnupg/gpg-agent.conf
@@ -1,7 +1,8 @@
 default-cache-ttl 3600
 max-cache-ttl 7200
 enable-ssh-support
-pinentry-program /usr/bin/pinentry-tty
+# pinentry-program /usr/bin/pinentry-tty
+pinentry-program pinentry-auto
 
 # 3 Hours cache on SSH-keys
 default-cache-ttl-ssh 10800
diff --git a/.gnupg/pinentry-auto.sh b/.gnupg/pinentry-auto.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9ce44c511d25b9542215fd324468f20508c484b0
--- /dev/null
+++ b/.gnupg/pinentry-auto.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Choose between pinentry-tty and pinentry-x11 based on whether
+# $PINENTRY_USER_DATA contains USE_TTY=1
+#
+# Based on:
+# https://kevinlocke.name/bits/2019/07/31/prefer-terminal-for-gpg-pinentry
+#
+# Note: Environment detection is difficult.
+# - stdin is Assuan pipe, preventing tty checking
+# - configuration info (e.g. ttyname) is passed via Assuan pipe, preventing
+#   parsing or fallback without implementing Assuan protocol.
+# - environment is sanitized by atfork_cb in call-pinentry.c (removing $GPG_TTY)
+#
+# $PINENTRY_USER_DATA is preserved since 2.08 https://dev.gnupg.org/T799
+#
+# Format of $PINENTRY_USER_DATA not specified (that I can find), pinentry-mac
+# assumes comma-separated sequence of NAME=VALUE with no escaping mechanism
+# https://github.com/GPGTools/pinentry-mac/blob/v0.9.4/Source/AppDelegate.m#L78
+# and recognizes USE_CURSES=1 for curses fallback
+# https://github.com/GPGTools/pinentry-mac/pull/2
+#
+# To the extent possible under law, Kevin Locke <kevin@kevinlocke.name> has
+# waived all copyright and related or neighboring rights to this work
+# under the terms of CC0: https://creativecommons.org/publicdomain/zero/1.0/
+
+set -Ceu
+
+# Use pinentry-tty if $PINENTRY_USER_DATA contains USE_TTY=1
+case "${PINENTRY_USER_DATA-}" in
+*USE_TTY=1*)
+	# Note: Change to pinentry-curses if a Curses UI is preferred.
+	exec pinentry-tty "$@"
+	;;
+esac
+
+# Otherwise, use any UI (configured by Debian Alternatives System)
+# Note: Will fall back to curses if $DISPLAY is not available.
+exec pinentry-qt "$@"
\ No newline at end of file