diff --git a/hosts/common/programs/sway/default.nix b/hosts/common/programs/sway/default.nix index 22af7a2e7..1a9745eb1 100644 --- a/hosts/common/programs/sway/default.nix +++ b/hosts/common/programs/sway/default.nix @@ -14,18 +14,6 @@ let test -e /tmp/.X11-unix || \ echo "warning: required directory not found (create it?): /tmp/.X11-unix" - # sway needs to know which virtual TTY to render to - setVtnr() { - local ttyPath="$(tty)" - case $ttyPath in - (/dev/tty*) - export XDG_VTNR=''${ttyPath#/dev/tty} - ;; - esac - } - if ! [ -v "$XDG_VTNR" ]; then - setVtnr - fi # delete DISPLAY-related vars from env before launch, else sway will try to connect to a remote display. # (consider: nested sway sessions, where sway actually has a reason to read these) exec env -u DISPLAY -u WAYLAND_DISPLAY "DESIRED_WAYLAND_DISPLAY=$WAYLAND_DISPLAY" ${configuredSway}/bin/sway 2>&1 diff --git a/hosts/common/programs/unl0kr/default.nix b/hosts/common/programs/unl0kr/default.nix index 215ae2e7d..91a58baf5 100644 --- a/hosts/common/programs/unl0kr/default.nix +++ b/hosts/common/programs/unl0kr/default.nix @@ -1,8 +1,6 @@ { config, lib, pkgs, ... }: let cfg = config.sane.programs.unl0kr; - - tty = "tty${builtins.toString cfg.config.vt}"; in { sane.programs.unl0kr = { @@ -18,34 +16,9 @@ in and allowing password auth via either keyboard, mouse, or touch. ''; }; - options.vt = mkOption { - type = types.int; - default = 1; - }; - options.delay = mkOption { - type = types.int; - default = 3; - description = '' - seconds to wait between successful login and running the `afterLogin` command. - this is a safety mechanism, to allow users an exit in case DE is broken. - ''; - }; }; }; - # TODO: lift this into toplevel s6 stuff - fs.".profile".symlink.text = '' - unl0krCheck() { - # if already running a desktop environment, or if running from ssh, then `tty` will show /dev/pts/NN. - # if the `sleep` call is `Ctrl+C'd`, then it'll exit false and the session commands won't be launched - [ "$(tty)" = "/dev/${tty}" ] && (( ''${#primarySessionCommands[@]} )) \ - && echo "launching primary session commands in ${builtins.toString cfg.config.delay}s: ''${primarySessionCommands[*]}" \ - && sleep ${builtins.toString cfg.config.delay} - } - primarySessionChecks+=('unl0krCheck') - - ''; - # N.B.: this sandboxing applies to `unl0kr` itself -- the on-screen-keyboard; # NOT to the wrapper which invokes `login`. sandbox.method = "bwrap"; @@ -64,7 +37,7 @@ in services.unl0kr = { description = "unl0kr framebuffer password entry/filesystem unlocker"; - partOf = [ "private-storage" ]; + partOf = lib.mkIf cfg.config.autostart [ "private-storage" ]; command = pkgs.writeShellScript "unl0kr-start" '' while ! test -f /mnt/persist/private/init; do if test -f /run/gocryptfs/private.key; then @@ -73,10 +46,12 @@ in ${lib.getExe' pkgs.inotify-tools "inotifywait"} --timeout 4 --event create --event delete /mnt/persist/private /run/gocryptfs else echo "starting unl0kr" - # switch back to the tty our session is running on (in case the user tabbed away after logging in), - # as only that TTY is sure to have echo disabled. - # this is racy, but when we race it's obvious from the UI that your password is being echo'd - ${lib.getExe' pkgs.kbd "chvt"} ${builtins.toString cfg.config.vt} + if [ -n "$XDG_VTNR" ]; then + # switch back to the tty our session is running on (in case the user tabbed away after logging in), + # as only that TTY is sure to have echo disabled. + # this is racy, but when we race it's obvious from the UI that your password is being echo'd + ${lib.getExe' pkgs.kbd "chvt"} "$XDG_VTNR" + fi unl0kr > /run/gocryptfs/private.key.incoming && cp /run/gocryptfs/private.key.incoming /run/gocryptfs/private.key echo "unl0kr exited" diff --git a/modules/users/default.nix b/modules/users/default.nix index 39b677a38..068ff00cb 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -241,14 +241,34 @@ let runCommands "''${sessionCommands[@]}" } maybeInitPrimarySession() { - for c in "''${primarySessionChecks[@]}"; do - if eval "$c"; then - runCommands "''${primarySessionCommands[@]}" - return - fi - done + local delay=3 + if test "$XDG_VTNR" -eq 1 \ + && (( ''${#primarySessionCommands[@]} )) \ + && echo "launching primary session commands in ''${delay}s: ''${primarySessionCommands[*]}" \ + && sleep $delay \ + ; then + runCommands "''${primarySessionCommands[@]}" + fi } + setVTNR() { + # some desktops (e.g. sway) need to know which virtual TTY to render to. + # it's also nice, to guess if a user logging into the "default" tty, or + # an auxiliary one + + local ttyPath=$(tty) + case $ttyPath in + (/dev/tty*) + export XDG_VTNR=''${ttyPath#/dev/tty} + ;; + (*) + # for terminals running inside a compositor, we do want to explicitly clear XDG_VTNR. + # otherwise, sway will be launched from tty1, then the user will launch a terminal emulator inside sway, but the application will think it's running directly on tty1 (which it isn't) + unset XDG_VTNR + ;; + esac + } + sessionCommands+=('setVTNR') # this is *probably not necessary*. # historically, Komikku needed to know if it was running under X or Wayland, and used XDG_SESSION_TYPE for that. # but unless this is a super common idiom, managing it here is just ugly.