From 2be0042d4288a5eae3b28c0d2db2fb855e8a82fe Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Mon, 26 Nov 2018 14:49:13 +0100
Subject: [PATCH 01/16] tv dnsmasq service: init

---
 tv/3modules/default.nix |  1 +
 tv/3modules/dnsmasq.nix | 57 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 tv/3modules/dnsmasq.nix

diff --git a/tv/3modules/default.nix b/tv/3modules/default.nix
index 493cc8b72..6172feb03 100644
--- a/tv/3modules/default.nix
+++ b/tv/3modules/default.nix
@@ -1,6 +1,7 @@
 {
   imports = [
     ./charybdis
+    ./dnsmasq.nix
     ./ejabberd
     ./hosts.nix
     ./iptables.nix
diff --git a/tv/3modules/dnsmasq.nix b/tv/3modules/dnsmasq.nix
new file mode 100644
index 000000000..ec927f98a
--- /dev/null
+++ b/tv/3modules/dnsmasq.nix
@@ -0,0 +1,57 @@
+with import <stockholm/lib>;
+{ config, ... }: let
+  cfg = config.tv.dnsmasq;
+in {
+
+  options.tv.dnsmasq = {
+    enable = mkEnableOption "tv.dnsmasq";
+    dhcp-range = mkOption {
+      type = types.str;
+    };
+    interface = mkOption {
+      type = types.str;
+    };
+    address = mkOption {
+      type = types.str;
+    };
+    prefixLength = mkOption {
+      type = types.addCheck types.int (x: x >= 0 && x <= 32);
+    };
+  };
+
+  config = mkIf cfg.enable (mkMerge [
+    {
+      networking.dhcpcd.denyInterfaces = [ cfg.interface ];
+      services.dnsmasq.resolveLocalQueries = false;
+      networking.interfaces.${cfg.interface} = {
+        ipv4.addresses = singleton {
+          address = cfg.address;
+          prefixLength = cfg.prefixLength;
+        };
+      };
+      services.dnsmasq.enable = true;
+      services.dnsmasq.extraConfig = ''
+        dhcp-range=${cfg.dhcp-range}
+        interface=${cfg.interface}
+      '';
+      tv.iptables.extra.filter.INPUT = [
+        "-i ${cfg.interface} -p tcp -m tcp --dport bootps -j ACCEPT"
+        "-i ${cfg.interface} -p udp -m udp --dport bootps -j ACCEPT"
+        "-i ${cfg.interface} -p tcp -m tcp --dport domain -j ACCEPT"
+        "-i ${cfg.interface} -p udp -m udp --dport domain -j ACCEPT"
+      ];
+    }
+    {
+      # enable forwarding
+      boot.kernel.sysctl."net.ipv4.ip_forward" = true;
+      tv.iptables.extra.filter.FORWARD = [
+        "-m state --state RELATED,ESTABLISHED -j ACCEPT"
+        "-i ${cfg.interface} -j ACCEPT"
+      ];
+      tv.iptables.extra.nat.POSTROUTING = [
+        "-j MASQUERADE"
+      ];
+    }
+  ]);
+
+}

From 09144f173677ed33850e484cf46876d13bb37c9e Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Mon, 26 Nov 2018 16:50:46 +0100
Subject: [PATCH 02/16] tv disko: init at 16cd458

---
 tv/5pkgs/simple/disko.nix | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 tv/5pkgs/simple/disko.nix

diff --git a/tv/5pkgs/simple/disko.nix b/tv/5pkgs/simple/disko.nix
new file mode 100644
index 000000000..de8f1df22
--- /dev/null
+++ b/tv/5pkgs/simple/disko.nix
@@ -0,0 +1,13 @@
+{ fetchgit }:
+
+let
+  src = fetchgit {
+    url = https://cgit.krebsco.de/disko;
+    rev = "16cd458af06d3caf687eb7d80ca3df26b71fe28c";
+    sha256 = "16cd458af06d3caf687eb7d80ca3df26b71fe28c";
+  };
+in
+
+{
+  lib = import "${src}/lib";
+}

From eb5b054cb24f9b2615b176c7cdb08d0a480a9e7f Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Tue, 27 Nov 2018 11:52:23 +0100
Subject: [PATCH 03/16] tv querel: drop chromium

---
 tv/1systems/querel/config.nix | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tv/1systems/querel/config.nix b/tv/1systems/querel/config.nix
index 01d67b5f5..6e7944cdf 100644
--- a/tv/1systems/querel/config.nix
+++ b/tv/1systems/querel/config.nix
@@ -25,7 +25,6 @@ with import <stockholm/lib>;
   };
 
   environment.systemPackages = with pkgs; [
-    chromium
     firefoxWrapper
     gimp
     kate
@@ -63,8 +62,6 @@ with import <stockholm/lib>;
 
   networking.networkmanager.enable = true;
 
-  nixpkgs.config.chromium.enablePepperFlash = true;
-
   programs.ssh.startAgent = false;
 
   services.xserver.enable = true;

From dae35c44c7cf67d10152a4fb32d212310f86199a Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Tue, 27 Nov 2018 11:53:19 +0100
Subject: [PATCH 04/16] krebs: integrate 5pkgs as overlay

---
 krebs/default.nix | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/krebs/default.nix b/krebs/default.nix
index d99f60aaa..7ec791529 100644
--- a/krebs/default.nix
+++ b/krebs/default.nix
@@ -1,12 +1,14 @@
-{ config, lib, pkgs, ... }:
-with import <stockholm/lib>;
 {
+
   imports = [
     ./3modules
-    {
-      nixpkgs.config.packageOverrides =
-        import ../submodules/nix-writers/pkgs pkgs;
-    }
   ];
-  nixpkgs.config.packageOverrides = import ./5pkgs pkgs;
+
+  nixpkgs = {
+    overlays = [
+      (import ./5pkgs)
+      (import ../submodules/nix-writers/pkgs)
+    ];
+  };
+
 }

From 627a3800ce3b1fc417cba085d47560c0ad4c93a2 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Tue, 27 Nov 2018 11:55:12 +0100
Subject: [PATCH 05/16] tv: integrate 5pkgs as overlay

---
 tv/default.nix | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tv/default.nix b/tv/default.nix
index d077cc09f..10b09f2af 100644
--- a/tv/default.nix
+++ b/tv/default.nix
@@ -1,9 +1,15 @@
-{ pkgs, ... }:
 {
+
   imports = [
     ../krebs
     ./2configs
     ./3modules
   ];
-  nixpkgs.config.packageOverrides = import ./5pkgs pkgs;
+
+  nixpkgs = {
+    overlays = [
+      (import ./5pkgs)
+    ];
+  };
+
 }

From 88ac2f40812b52220c1e2db290440c5abf42964e Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Tue, 27 Nov 2018 12:09:19 +0100
Subject: [PATCH 06/16] tv xp332: add utsushi-customized

---
 tv/2configs/xp-332.nix | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tv/2configs/xp-332.nix b/tv/2configs/xp-332.nix
index 627401dc6..4a0b0ae16 100644
--- a/tv/2configs/xp-332.nix
+++ b/tv/2configs/xp-332.nix
@@ -11,7 +11,7 @@ with import <stockholm/lib>;
   hardware.sane = {
     enable = true;
     extraBackends = [
-      pkgs.utsushi
+      pkgs.utsushi-customized
     ];
   };
 
@@ -19,7 +19,7 @@ with import <stockholm/lib>;
     elem (parseDrvName pkg.name).name [ "imagescan-plugin-networkscan" ];
 
   nixpkgs.overlays = singleton (self: super: {
-    utsushi = super.utsushi.override {
+    utsushi-customized = self.utsushi.override {
       guiSupport = false;
       jpegSupport = false;
       networkSupport = true;

From 09556c7538565078ba9c55f834859ef6f96af90b Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 09:20:25 +0100
Subject: [PATCH 07/16] tv fzmenu: init

---
 tv/5pkgs/simple/fzmenu/bin/otpmenu  | 41 +++++++++++++++++++++++++++++
 tv/5pkgs/simple/fzmenu/bin/passmenu | 41 +++++++++++++++++++++++++++++
 tv/5pkgs/simple/fzmenu/default.nix  | 34 ++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100755 tv/5pkgs/simple/fzmenu/bin/otpmenu
 create mode 100755 tv/5pkgs/simple/fzmenu/bin/passmenu
 create mode 100644 tv/5pkgs/simple/fzmenu/default.nix

diff --git a/tv/5pkgs/simple/fzmenu/bin/otpmenu b/tv/5pkgs/simple/fzmenu/bin/otpmenu
new file mode 100755
index 000000000..ad8a0fda9
--- /dev/null
+++ b/tv/5pkgs/simple/fzmenu/bin/otpmenu
@@ -0,0 +1,41 @@
+#! /bin/sh
+set -efu
+
+#PATH=
+
+case ${FZMENU_PHASE-0} in
+  0)
+    export FZMENU_PHASE=1
+    exec setsid -f urxvt -name fzmenu-urxvt -e dash "$0"
+    ;;
+  1)
+    if result=$(
+      FZF_DEFAULT_OPTS=${FZMENU_FZF_DEFAULT_OPTS-}
+      if test -n "$FZF_DEFAULT_OPTS"; then
+        export FZF_DEFAULT_OPTS
+      fi
+      pass git ls-files '*/otp.gpg' | \
+      sed '
+
+        s/\/otp\.gpg$//
+      ' |
+      exec fzf \
+          --history=/dev/null \
+          --no-sort \
+          --prompt='OTP: ' \
+    )
+    then
+      export FZMENU_PHASE=2
+      export FZMENU_RESULT="$result"
+      setsid -f "$0"
+    fi
+    ;;
+  2)
+    pass=$(pass otp code "$FZMENU_RESULT/otp")
+    printf %s "$pass" |
+    xdotool type -f -
+    ;;
+  *)
+    echo "$0: error: bad phase: $FZMENU_PHASE" >&2
+    exit -1
+esac
diff --git a/tv/5pkgs/simple/fzmenu/bin/passmenu b/tv/5pkgs/simple/fzmenu/bin/passmenu
new file mode 100755
index 000000000..00b36c3af
--- /dev/null
+++ b/tv/5pkgs/simple/fzmenu/bin/passmenu
@@ -0,0 +1,41 @@
+#! /bin/sh
+set -efu
+
+#PATH=
+
+case ${FZMENU_PHASE-0} in
+  0)
+    export FZMENU_PHASE=1
+    exec setsid -f urxvt -name fzmenu-urxvt -e dash "$0"
+    ;;
+  1)
+    if result=$(
+      FZF_DEFAULT_OPTS=${FZMENU_FZF_DEFAULT_OPTS-}
+      if test -n "$FZF_DEFAULT_OPTS"; then
+        export FZF_DEFAULT_OPTS
+      fi
+      pass git ls-files '*/*.gpg' | \
+      sed '
+        /\/otp\.gpg$:/d
+        s/\.gpg$//
+      ' |
+      exec fzf \
+          --history=/dev/null \
+          --no-sort \
+          --prompt='pass: ' \
+    )
+    then
+      export FZMENU_PHASE=2
+      export FZMENU_RESULT="$result"
+      setsid -f "$0"
+    fi
+    ;;
+  2)
+    pass=$(pass show "$FZMENU_RESULT")
+    printf %s "$pass" |
+    xdotool type -f -
+    ;;
+  *)
+    echo "$0: error: bad phase: $FZMENU_PHASE" >&2
+    exit -1
+esac
diff --git a/tv/5pkgs/simple/fzmenu/default.nix b/tv/5pkgs/simple/fzmenu/default.nix
new file mode 100644
index 000000000..c49c903c6
--- /dev/null
+++ b/tv/5pkgs/simple/fzmenu/default.nix
@@ -0,0 +1,34 @@
+{ coreutils, dash, gnused, fzf, pass, runCommand, rxvt_unicode, stdenv, utillinux, xdotool }:
+
+runCommand "fzmenu" {
+} /* sh */ ''
+  mkdir $out
+
+  cp -r ${./bin} $out/bin
+
+  substituteInPlace $out/bin/otpmenu \
+      --replace '#! /bin/sh' '#! ${dash}/bin/dash' \
+      --replace '#PATH=' PATH=${stdenv.lib.makeBinPath [
+        coreutils
+        dash
+        fzf
+        gnused
+        pass
+        rxvt_unicode
+        utillinux
+        xdotool
+      ]}
+
+  substituteInPlace $out/bin/passmenu \
+      --replace '#! /bin/sh' '#! ${dash}/bin/dash' \
+      --replace '#PATH=' PATH=${stdenv.lib.makeBinPath [
+        coreutils
+        dash
+        fzf
+        gnused
+        pass
+        rxvt_unicode
+        utillinux
+        xdotool
+      ]}
+''

From 57ce731ffb28adfc854de3caa1987509e1939559 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 09:55:38 +0100
Subject: [PATCH 08/16] tv xmonad: use fzmenu

---
 tv/2configs/xserver/Xresources.nix    |  5 +++++
 tv/2configs/xserver/default.nix       |  5 +++++
 tv/5pkgs/simple/xmonad-tv/default.nix | 13 +++++++++----
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/tv/2configs/xserver/Xresources.nix b/tv/2configs/xserver/Xresources.nix
index 1d4044480..b8a4e822b 100644
--- a/tv/2configs/xserver/Xresources.nix
+++ b/tv/2configs/xserver/Xresources.nix
@@ -50,4 +50,9 @@ pkgs.writeText "Xresources" /* xdefaults */ ''
   root-urxvt*foreground: #e0c0c0
   root-urxvt*BorderColor: #400000
   root-urxvt*color0: #800000
+
+  fzmenu-urxvt*background: rgb:42/23/42
+  fzmenu-urxvt*externalBorder: 1
+  fzmenu-urxvt*externalBorder: 1
+  fzmenu-urxvt*geometry: 70x9
 ''
diff --git a/tv/2configs/xserver/default.nix b/tv/2configs/xserver/default.nix
index dbfa804d2..d1345723d 100644
--- a/tv/2configs/xserver/default.nix
+++ b/tv/2configs/xserver/default.nix
@@ -63,6 +63,11 @@ in {
     environment = {
       DISPLAY = ":${toString config.services.xserver.display}";
 
+      FZMENU_FZF_DEFAULT_OPTS = toString [
+        "--color=dark,border:126,bg+:090"
+        "--inline-info"
+      ];
+
       XMONAD_CACHE_DIR = cfg.cacheDir;
       XMONAD_CONFIG_DIR = cfg.configDir;
       XMONAD_DATA_DIR = cfg.dataDir;
diff --git a/tv/5pkgs/simple/xmonad-tv/default.nix b/tv/5pkgs/simple/xmonad-tv/default.nix
index 1168f10c8..a2525e06e 100644
--- a/tv/5pkgs/simple/xmonad-tv/default.nix
+++ b/tv/5pkgs/simple/xmonad-tv/default.nix
@@ -38,12 +38,12 @@ import Data.Map (Map)
 import qualified Data.Map as Map
 -- TODO import XMonad.Layout.WorkspaceDir
 import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
+import XMonad.Hooks.ManageHelpers (doCenterFloat)
 -- import XMonad.Layout.Tabbed
 --import XMonad.Layout.MouseResizableTile
 import XMonad.Layout.Reflect (reflectVert)
 import XMonad.Layout.FixedColumn (FixedColumn(..))
 import XMonad.Hooks.Place (placeHook, smart)
-import XMonad.Hooks.FloatNext (floatNextHook)
 import XMonad.Actions.PerWorkspaceKeys (chooseAction)
 import XMonad.Layout.PerWorkspace (onWorkspace)
 --import XMonad.Layout.BinarySpacePartition
@@ -85,7 +85,12 @@ mainNoArgs = do
             , layoutHook        = smartBorders $ FixedColumn 1 20 80 10 ||| Full
             -- , handleEventHook   = myHandleEventHooks <+> handleTimerEvent
             --, handleEventHook   = handleTimerEvent
-            , manageHook        = placeHook (smart (1,0)) <+> floatNextHook
+            , manageHook =
+                composeAll
+                  [ appName =? "fzmenu-urxvt" --> doCenterFloat
+                  , appName =? "pinentry" --> doCenterFloat
+                  , placeHook (smart (1,0))
+                  ]
             , startupHook =
                 whenJustM (liftIO (lookupEnv "XMONAD_STARTUP_HOOK"))
                           (\path -> forkFile path [] Nothing)
@@ -133,8 +138,8 @@ myKeys conf = Map.fromList $
     [ ((_4  , xK_Escape ), forkFile "/run/wrappers/bin/slock" [] Nothing)
     , ((_4S , xK_c      ), kill)
 
-    , ((_4  , xK_o      ), forkFile "${pkgs.otpmenu}/bin/otpmenu" [] Nothing)
-    , ((_4  , xK_p      ), forkFile "${pkgs.pass}/bin/passmenu" ["--type"] Nothing)
+    , ((_4  , xK_o      ), forkFile "${pkgs.fzmenu}/bin/otpmenu" [] Nothing)
+    , ((_4  , xK_p      ), forkFile "${pkgs.fzmenu}/bin/passmenu" [] Nothing)
 
     , ((_4  , xK_x      ), chooseAction spawnTermAt)
     , ((_4C , xK_x      ), spawnRootTerm)

From 0c7c964e7597f5f66e146c20b82d8a3e086d52eb Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 09:54:51 +0100
Subject: [PATCH 09/16] tv otpmenu: RIP

---
 tv/5pkgs/simple/otpmenu.nix | 15 ---------------
 1 file changed, 15 deletions(-)
 delete mode 100644 tv/5pkgs/simple/otpmenu.nix

diff --git a/tv/5pkgs/simple/otpmenu.nix b/tv/5pkgs/simple/otpmenu.nix
deleted file mode 100644
index b35e1601f..000000000
--- a/tv/5pkgs/simple/otpmenu.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{ dmenu, gnused, pass, writeDashBin, xdotool }:
-
-writeDashBin "otpmenu" ''
-  set -efu
-
-  x=$(
-    ${pass}/bin/pass git ls-files '*/otp.gpg' \
-      | ${gnused}/bin/sed 's:/otp\.gpg$::' \
-      | ${dmenu}/bin/dmenu -f -p OTP
-  )
-
-  otp=$(${pass}/bin/pass otp code "$x/otp")
-
-  printf %s "$otp" | ${xdotool}/bin/xdotool type -f -
-''

From 6d06ffa76a891c47b4516869ac9c8bbd0a6af5d4 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 13:37:58 +0100
Subject: [PATCH 10/16] krops: 1.7.2 -> 1.8.0

---
 submodules/krops | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/submodules/krops b/submodules/krops
index 4ce5dae7b..6f49342b2 160000
--- a/submodules/krops
+++ b/submodules/krops
@@ -1 +1 @@
-Subproject commit 4ce5dae7bceb635e96a9f8d5658a1bd2aada4f66
+Subproject commit 6f49342b2d5973478f1f5eb6f8d6307059e7bcf7

From d5551ed214479317925239a9801384c9c3aa9add Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 14:29:07 +0100
Subject: [PATCH 11/16] tv fzmenu-urxvt: add internalBorder

---
 tv/2configs/xserver/Xresources.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tv/2configs/xserver/Xresources.nix b/tv/2configs/xserver/Xresources.nix
index b8a4e822b..d032efc7d 100644
--- a/tv/2configs/xserver/Xresources.nix
+++ b/tv/2configs/xserver/Xresources.nix
@@ -53,6 +53,6 @@ pkgs.writeText "Xresources" /* xdefaults */ ''
 
   fzmenu-urxvt*background: rgb:42/23/42
   fzmenu-urxvt*externalBorder: 1
-  fzmenu-urxvt*externalBorder: 1
   fzmenu-urxvt*geometry: 70x9
+  fzmenu-urxvt*internalBorder: 1
 ''

From 1d7fddc064fef5e77c48602e3524949893a92997 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 14:41:56 +0100
Subject: [PATCH 12/16] tv xmonad: add currentSystem to executable name

This prevents journal messges like:
XMonad is recompiling and replacing itself another XMonad process because the current process is called "xmonad" but the compiled configuration should be called "xmonad-x86_64-linux"
---
 tv/2configs/xserver/default.nix       | 4 ++--
 tv/5pkgs/simple/xmonad-tv/default.nix | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tv/2configs/xserver/default.nix b/tv/2configs/xserver/default.nix
index d1345723d..a44ece8b1 100644
--- a/tv/2configs/xserver/default.nix
+++ b/tv/2configs/xserver/default.nix
@@ -100,8 +100,8 @@ in {
         "\${XMONAD_CONFIG_DIR}"
         "\${XMONAD_DATA_DIR}"
       ]}";
-      ExecStart = "${pkgs.xmonad-tv}/bin/xmonad";
-      ExecStop = "${pkgs.xmonad-tv}/bin/xmonad --shutdown";
+      ExecStart = "${pkgs.xmonad-tv}/bin/xmonad-${currentSystem}";
+      ExecStop = "${pkgs.xmonad-tv}/bin/xmonad-${currentSystem} --shutdown";
       User = cfg.user.name;
       WorkingDirectory = cfg.user.home;
     };
diff --git a/tv/5pkgs/simple/xmonad-tv/default.nix b/tv/5pkgs/simple/xmonad-tv/default.nix
index a2525e06e..430e6a809 100644
--- a/tv/5pkgs/simple/xmonad-tv/default.nix
+++ b/tv/5pkgs/simple/xmonad-tv/default.nix
@@ -1,6 +1,6 @@
 { pkgs, ... }:
 pkgs.writeHaskellPackage "xmonad-tv" {
-  executables.xmonad = {
+  executables."xmonad-${builtins.currentSystem}" = {
     extra-depends = [
       "containers"
       "extra"

From f57b5b72a418ae740dbb5c536bb8addafe055a2a Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 14:47:08 +0100
Subject: [PATCH 13/16] tv xmonad: liftIO -> io

---
 tv/5pkgs/simple/xmonad-tv/default.nix | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tv/5pkgs/simple/xmonad-tv/default.nix b/tv/5pkgs/simple/xmonad-tv/default.nix
index 430e6a809..18463b496 100644
--- a/tv/5pkgs/simple/xmonad-tv/default.nix
+++ b/tv/5pkgs/simple/xmonad-tv/default.nix
@@ -92,7 +92,7 @@ mainNoArgs = do
                   , placeHook (smart (1,0))
                   ]
             , startupHook =
-                whenJustM (liftIO (lookupEnv "XMONAD_STARTUP_HOOK"))
+                whenJustM (io (lookupEnv "XMONAD_STARTUP_HOOK"))
                           (\path -> forkFile path [] Nothing)
             , normalBorderColor  = "#1c1c1c"
             , focusedBorderColor = "#f000b0"
@@ -129,7 +129,7 @@ spawnRootTerm =
 
 spawnTermAt :: String -> X ()
 spawnTermAt ws = do
-    env <- liftIO getEnvironment
+    env <- io getEnvironment
     let env' = ("XMONAD_SPAWN_WORKSPACE", ws) : env
     forkFile urxvtcPath [] (Just env')
 

From ef418b19a05177b9cbac4febc77a79e437aa4851 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 17:03:53 +0100
Subject: [PATCH 14/16] tv xmonad: reduce cruft

---
 tv/5pkgs/simple/xmonad-tv/default.nix | 44 +--------------------------
 1 file changed, 1 insertion(+), 43 deletions(-)

diff --git a/tv/5pkgs/simple/xmonad-tv/default.nix b/tv/5pkgs/simple/xmonad-tv/default.nix
index 18463b496..97cc29917 100644
--- a/tv/5pkgs/simple/xmonad-tv/default.nix
+++ b/tv/5pkgs/simple/xmonad-tv/default.nix
@@ -25,30 +25,22 @@ import Graphics.X11.ExtraTypes.XF86
 import Text.Read (readEither)
 import XMonad
 import System.IO (hPutStrLn, stderr)
-import System.Environment (getArgs, withArgs, getEnv, getEnvironment, lookupEnv)
+import System.Environment (getArgs, getEnv, getEnvironment, lookupEnv)
 import System.Posix.Process (executeFile)
 import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace
                                         , removeEmptyWorkspace)
 import XMonad.Actions.GridSelect
 import XMonad.Actions.CycleWS (toggleWS)
---import XMonad.Actions.CopyWindow ( copy )
 import XMonad.Layout.NoBorders ( smartBorders )
 import qualified XMonad.StackSet as W
 import Data.Map (Map)
 import qualified Data.Map as Map
--- TODO import XMonad.Layout.WorkspaceDir
 import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
 import XMonad.Hooks.ManageHelpers (doCenterFloat)
--- import XMonad.Layout.Tabbed
---import XMonad.Layout.MouseResizableTile
-import XMonad.Layout.Reflect (reflectVert)
 import XMonad.Layout.FixedColumn (FixedColumn(..))
 import XMonad.Hooks.Place (placeHook, smart)
 import XMonad.Actions.PerWorkspaceKeys (chooseAction)
-import XMonad.Layout.PerWorkspace (onWorkspace)
---import XMonad.Layout.BinarySpacePartition
 
---import XMonad.Actions.Submap
 import XMonad.Stockholm.Pager
 import XMonad.Stockholm.Rhombus
 import XMonad.Stockholm.Shutdown
@@ -72,10 +64,6 @@ mainNoArgs :: IO ()
 mainNoArgs = do
     workspaces0 <- getWorkspaces0
     xmonad
-        -- $ withUrgencyHookC dzenUrgencyHook { args = ["-bg", "magenta", "-fg", "magenta", "-h", "2"], duration = 500000 }
-        --                   urgencyConfig { remindWhen = Every 1 }
-        -- $ withUrgencyHook borderUrgencyHook "magenta"
-        -- $ withUrgencyHookC BorderUrgencyHook { urgencyBorderColor = "magenta" } urgencyConfig { suppressWhen = Never }
         $ withUrgencyHook (SpawnUrgencyHook "echo emit Urgency ")
         $ def
             { terminal          = urxvtcPath
@@ -83,8 +71,6 @@ mainNoArgs = do
             , keys              = myKeys
             , workspaces        = workspaces0
             , layoutHook        = smartBorders $ FixedColumn 1 20 80 10 ||| Full
-            -- , handleEventHook   = myHandleEventHooks <+> handleTimerEvent
-            --, handleEventHook   = handleTimerEvent
             , manageHook =
                 composeAll
                   [ appName =? "fzmenu-urxvt" --> doCenterFloat
@@ -260,34 +246,6 @@ wGSConfig = def
     , gs_navigate = navNSearch
     }
 
--- wsGSConfig = def
---     { gs_cellheight = 20
---     , gs_cellwidth = 64
---     , gs_cellpadding = 5
---     , gs_font = myFont
---     , gs_navigate = navNSearch
---     }
-
--- custom navNSearch
---makeGSNav :: (KeyMask, KeySym) -> TwoD a (Maybe a)
---makeGSNav esc = nav
---    where
---    nav = makeXEventhandler $ shadowWithKeymap keyMap navNSearchDefaultHandler
---    keyMap = Map.fromList
---        [ (esc              , cancel)
---        , ((0,xK_Escape)    , cancel)
---        , ((0,xK_Return)    , select)
---        , ((0,xK_Left)      , move (-1, 0) >> nav)
---        , ((0,xK_Right)     , move ( 1, 0) >> nav)
---        , ((0,xK_Down)      , move ( 0, 1) >> nav)
---        , ((0,xK_Up)        , move ( 0,-1) >> nav)
---        , ((0,xK_BackSpace) , transformSearchString (\s -> if (s == "") then "" else init s) >> nav)
---        ]
---    -- The navigation handler ignores unknown key symbols, therefore we const
---    navNSearchDefaultHandler (_,s,_) = do
---        transformSearchString (++ s)
---        nav
-
 
 (&) :: a -> (a -> c) -> c
 (&) = flip ($)

From 2b9d361f7f8ef6334c4832d6eb87f2b6008e352f Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 17:03:15 +0100
Subject: [PATCH 15/16] tv xmonad: wait for shutdown to complete

---
 tv/2configs/xserver/default.nix       |  2 +-
 tv/5pkgs/simple/xmonad-tv/default.nix | 26 ++++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/tv/2configs/xserver/default.nix b/tv/2configs/xserver/default.nix
index a44ece8b1..199ffcaf8 100644
--- a/tv/2configs/xserver/default.nix
+++ b/tv/2configs/xserver/default.nix
@@ -101,7 +101,7 @@ in {
         "\${XMONAD_DATA_DIR}"
       ]}";
       ExecStart = "${pkgs.xmonad-tv}/bin/xmonad-${currentSystem}";
-      ExecStop = "${pkgs.xmonad-tv}/bin/xmonad-${currentSystem} --shutdown";
+      ExecStop = "${pkgs.xmonad-tv}/bin/xmonad-${currentSystem} --shutdown $MAINPID";
       User = cfg.user.name;
       WorkingDirectory = cfg.user.home;
     };
diff --git a/tv/5pkgs/simple/xmonad-tv/default.nix b/tv/5pkgs/simple/xmonad-tv/default.nix
index 97cc29917..ab4be91f3 100644
--- a/tv/5pkgs/simple/xmonad-tv/default.nix
+++ b/tv/5pkgs/simple/xmonad-tv/default.nix
@@ -19,6 +19,11 @@ pkgs.writeHaskellPackage "xmonad-tv" {
 
 module Main where
 
+import System.IO.Error (isDoesNotExistError, tryIOError)
+import System.Exit (exitFailure)
+import Control.Monad (forever)
+import Control.Concurrent (threadDelay)
+
 import Control.Exception
 import Control.Monad.Extra (whenJustM)
 import Graphics.X11.ExtraTypes.XF86
@@ -27,6 +32,8 @@ import XMonad
 import System.IO (hPutStrLn, stderr)
 import System.Environment (getArgs, getEnv, getEnvironment, lookupEnv)
 import System.Posix.Process (executeFile)
+import System.Posix.Signals (nullSignal, signalProcess)
+import System.Posix.Types (ProcessID)
 import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace
                                         , removeEmptyWorkspace)
 import XMonad.Actions.GridSelect
@@ -57,8 +64,23 @@ myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
 
 main :: IO ()
 main = getArgs >>= \case
-    ["--shutdown"] -> sendShutdownEvent
-    _ -> mainNoArgs
+    [] -> mainNoArgs
+    ["--shutdown", pidArg] -> mainShutdown (read pidArg)
+    args -> hPutStrLn stderr ("bad arguments: " <> show args) >> exitFailure
+
+mainShutdown :: ProcessID -> IO ()
+mainShutdown pid = do
+    sendShutdownEvent
+    hPutStrLn stderr ("waiting for: " <> show pid)
+    result <- tryIOError (waitProcess pid)
+    if isSuccess result
+      then hPutStrLn stderr ("result: " <> show result <> " [AKA success^_^]")
+      else hPutStrLn stderr ("result: " <> show result)
+  where
+    isSuccess = either isDoesNotExistError (const False)
+
+waitProcess :: ProcessID -> IO ()
+waitProcess pid = forever (signalProcess nullSignal pid >> threadDelay 10000)
 
 mainNoArgs :: IO ()
 mainNoArgs = do

From d1f81ace7241cf751f8a02c102b02bc1c8ad6c07 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Wed, 28 Nov 2018 18:30:19 +0100
Subject: [PATCH 16/16] tv urlwatch: remove nixos

---
 tv/2configs/urlwatch.nix | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/tv/2configs/urlwatch.nix b/tv/2configs/urlwatch.nix
index 77947dafa..7467e8e67 100644
--- a/tv/2configs/urlwatch.nix
+++ b/tv/2configs/urlwatch.nix
@@ -27,11 +27,6 @@ in {
       # 2014-09-24 ref https://github.com/4z3/xintmap
       http://www.mathstat.dal.ca/~selinger/quipper/
 
-      ## other
-
-      https://nixos.org/channels/nixos-18.03/git-revision
-      https://nixos.org/channels/nixos-unstable/git-revision
-
       ## 2014-10-17
       ## TODO update ~/src/login/default.nix
       #http://hackage.haskell.org/package/bcrypt