tv pinentry-urxvt: show tinted screenshots
This commit is contained in:
parent
d7341bbff6
commit
b1d1322e25
@ -20,7 +20,11 @@ let
|
|||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
display = lib.mkOption {
|
display = lib.mkOption {
|
||||||
default = ":0";
|
default = null;
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
};
|
||||||
|
xwud.className = lib.mkOption {
|
||||||
|
default = "PinentryUrxvtXwudFloat";
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -30,12 +34,76 @@ let
|
|||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
|
# pinentry-urxvt - A mechanism for PIN entry utilizing rxvt-unicode
|
||||||
|
#
|
||||||
|
# This spawns a PIN entry terminal on top of a tinted screenshot of the
|
||||||
|
# current display's root window. The display for spawning the terminal can
|
||||||
|
# be predefined, in which case both the current and the predefined display
|
||||||
|
# will show the screenshot.
|
||||||
|
#
|
||||||
|
# The purpose of the screenshot, aside from looking nice, is to prevent entry
|
||||||
|
# of the PIN into the wrong window, e.g. by accidentally moving the cursor
|
||||||
|
# while typing. If necessary, the screenshot can be closed by sending 'q',
|
||||||
|
# 'Q', or ctrl-c while its focused.
|
||||||
|
#
|
||||||
pkgs.write "pinentry-urxvt" {
|
pkgs.write "pinentry-urxvt" {
|
||||||
"/bin/pinentry".link = pkgs.writeDash "pinentry-urxvt-wrapper" ''
|
"/bin/pinentry".link = pkgs.writeDash "pinentry-urxvt-wrapper" ''
|
||||||
set -efu
|
set -efu
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm "$screenshot"
|
||||||
|
# Kill process group in order to kill screenshot windows.
|
||||||
|
${pkgs.utillinux}/bin/kill 0
|
||||||
|
}
|
||||||
|
|
||||||
|
screenshot=$(${pkgs.coreutils}/bin/mktemp -t pinentry-urxvt.screenshot.XXXXXXXX)
|
||||||
|
|
||||||
|
${pkgs.xorg.xwd}/bin/xwd -root |
|
||||||
|
${pkgs.imagemagick}/bin/convert xwd:- -fill \#424242 -colorize 80% xwd:"$screenshot"
|
||||||
|
|
||||||
|
show_screenshot() {
|
||||||
|
${pkgs.exec "pinentry-urxvt.show_screenshot" {
|
||||||
|
filename = "${pkgs.xorg.xwud}/bin/xwud";
|
||||||
|
argv = [
|
||||||
|
cfg.xwud.className
|
||||||
|
"-noclick"
|
||||||
|
];
|
||||||
|
}} < "$screenshot" &
|
||||||
|
wait_for_screenshot $!
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for the xwud window by trying to intercept the call to munmap().
|
||||||
|
# If it cannot be intercepted within 0.1s, assume that attaching strace
|
||||||
|
# wasn't fast enough or xwud doesn't call munmap() anymore. In either
|
||||||
|
# case fall back to search the window by class name, assuming there can
|
||||||
|
# be only one per display.
|
||||||
|
wait_for_screenshot() {
|
||||||
|
if ! \
|
||||||
|
${pkgs.coreutils}/bin/timeout 0.1 \
|
||||||
|
${pkgs.strace}/bin/strace -p "$1" -e munmap 2>&1 |
|
||||||
|
read -r _
|
||||||
|
then
|
||||||
|
until ${pkgs.xdotool}/bin/xdotool search \
|
||||||
|
--classname ${lib.shell.escape cfg.xwud.className}
|
||||||
|
do
|
||||||
|
${pkgs.coreutils}/bin/sleep 0.1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
show_screenshot
|
||||||
|
|
||||||
|
${lib.optionalString (cfg.display != null) /* sh */ ''
|
||||||
|
if test "$DISPLAY" != ${lib.shell.escape cfg.display}; then
|
||||||
|
export DISPLAY=${lib.shell.escape cfg.display}
|
||||||
|
show_screenshot
|
||||||
|
fi
|
||||||
|
''}
|
||||||
|
|
||||||
exec 3<&0 4>&1 5>&2
|
exec 3<&0 4>&1 5>&2
|
||||||
export DISPLAY=${lib.shell.escape cfg.display}
|
${pkgs.rxvt_unicode}/bin/urxvt \
|
||||||
exec ${pkgs.rxvt_unicode}/bin/urxvt \
|
|
||||||
-name ${lib.shell.escape cfg.appName} \
|
-name ${lib.shell.escape cfg.appName} \
|
||||||
-e ${pkgs.writeDash "pinentry-urxvt-tty" ''
|
-e ${pkgs.writeDash "pinentry-urxvt-tty" ''
|
||||||
set -efu
|
set -efu
|
||||||
|
Loading…
Reference in New Issue
Block a user