From b1d1322e25459f1f7c79a866b2abf06fc5535e33 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 8 Dec 2022 16:12:00 +0100 Subject: tv pinentry-urxvt: show tinted screenshots --- tv/5pkgs/simple/pinentry-urxvt/default.nix | 74 ++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'tv/5pkgs/simple/pinentry-urxvt/default.nix') diff --git a/tv/5pkgs/simple/pinentry-urxvt/default.nix b/tv/5pkgs/simple/pinentry-urxvt/default.nix index 65b76c077..6e4f6b002 100644 --- a/tv/5pkgs/simple/pinentry-urxvt/default.nix +++ b/tv/5pkgs/simple/pinentry-urxvt/default.nix @@ -20,7 +20,11 @@ let type = lib.types.str; }; display = lib.mkOption { - default = ":0"; + default = null; + type = lib.types.nullOr lib.types.str; + }; + xwud.className = lib.mkOption { + default = "PinentryUrxvtXwudFloat"; type = lib.types.str; }; }; @@ -30,12 +34,76 @@ let 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" { "/bin/pinentry".link = pkgs.writeDash "pinentry-urxvt-wrapper" '' 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 - export DISPLAY=${lib.shell.escape cfg.display} - exec ${pkgs.rxvt_unicode}/bin/urxvt \ + ${pkgs.rxvt_unicode}/bin/urxvt \ -name ${lib.shell.escape cfg.appName} \ -e ${pkgs.writeDash "pinentry-urxvt-tty" '' set -efu -- cgit v1.2.3 From 6d64096cd99db27357bf2d038bdfdfc2d3a3aeae Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 9 Dec 2022 01:31:56 +0100 Subject: tv: normalize lib imports --- tv/5pkgs/simple/pinentry-urxvt/default.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tv/5pkgs/simple/pinentry-urxvt/default.nix') diff --git a/tv/5pkgs/simple/pinentry-urxvt/default.nix b/tv/5pkgs/simple/pinentry-urxvt/default.nix index 6e4f6b002..c768a9f5b 100644 --- a/tv/5pkgs/simple/pinentry-urxvt/default.nix +++ b/tv/5pkgs/simple/pinentry-urxvt/default.nix @@ -1,8 +1,7 @@ +with import ./lib; { pkgs, ... }@args: let - lib = import ; - # config cannot be declared in the input attribute set because that would # cause callPackage to inject the wrong config. Instead, get it from ... # via args. -- cgit v1.2.3 From fe01fe6bf411623582f8f21d5b8adb0e4729a7c1 Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 9 Dec 2022 21:53:09 +0100 Subject: tv pinentry-urxvt: kill only screenshot displayers --- tv/5pkgs/simple/pinentry-urxvt/default.nix | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'tv/5pkgs/simple/pinentry-urxvt/default.nix') diff --git a/tv/5pkgs/simple/pinentry-urxvt/default.nix b/tv/5pkgs/simple/pinentry-urxvt/default.nix index c768a9f5b..ad8039ff2 100644 --- a/tv/5pkgs/simple/pinentry-urxvt/default.nix +++ b/tv/5pkgs/simple/pinentry-urxvt/default.nix @@ -52,25 +52,26 @@ in trap cleanup EXIT cleanup() { + ${pkgs.utillinux}/bin/kill -- $(${pkgs.coreutils}/bin/cat "$displayers") + rm "$displayers" 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) + displayers=$(${pkgs.coreutils}/bin/mktemp -t pinentry-urxvt.$$.displayers.XXXXXXXX) + 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" { + display_screenshot() { + ${pkgs.exec "pinentry-urxvt.display_screenshot" { filename = "${pkgs.xorg.xwud}/bin/xwud"; argv = [ cfg.xwud.className "-noclick" ]; }} < "$screenshot" & - wait_for_screenshot $! + wait_for_screenshot $! && echo $! >>"$displayers" } # Wait for the xwud window by trying to intercept the call to munmap(). @@ -92,12 +93,12 @@ in fi } - show_screenshot + display_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 + display_screenshot fi ''} -- cgit v1.2.3