Merge pull request #100141 from xaverdh/xmonad-correct-path

xmonad: put the correct xmonad binary in PATH
This commit is contained in:
Lassulus 2020-10-13 19:01:56 +02:00 committed by GitHub
commit 53f810cb4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 22 deletions

View File

@ -4,13 +4,15 @@ with lib;
let let
inherit (lib) mkOption mkIf optionals literalExample; inherit (lib) mkOption mkIf optionals literalExample;
cfg = config.services.xserver.windowManager.xmonad; cfg = config.services.xserver.windowManager.xmonad;
xmonad = pkgs.xmonad-with-packages.override {
xmonad-vanilla = pkgs.xmonad-with-packages.override {
ghcWithPackages = cfg.haskellPackages.ghcWithPackages; ghcWithPackages = cfg.haskellPackages.ghcWithPackages;
packages = self: cfg.extraPackages self ++ packages = self: cfg.extraPackages self ++
optionals cfg.enableContribAndExtras optionals cfg.enableContribAndExtras
[ self.xmonad-contrib self.xmonad-extras ]; [ self.xmonad-contrib self.xmonad-extras ];
}; };
xmonadBin = pkgs.writers.writeHaskell "xmonad" {
xmonad-config = pkgs.writers.writeHaskellBin "xmonad" {
ghc = cfg.haskellPackages.ghc; ghc = cfg.haskellPackages.ghc;
libraries = [ cfg.haskellPackages.xmonad ] ++ libraries = [ cfg.haskellPackages.xmonad ] ++
cfg.extraPackages cfg.haskellPackages ++ cfg.extraPackages cfg.haskellPackages ++
@ -19,8 +21,10 @@ let
inherit (cfg) ghcArgs; inherit (cfg) ghcArgs;
} cfg.config; } cfg.config;
in xmonad = if (cfg.config != null) then xmonad-config else xmonad-vanilla;
{ in {
meta.maintainers = with maintainers; [ lassulus xaverdh ];
options = { options = {
services.xserver.windowManager.xmonad = { services.xserver.windowManager.xmonad = {
enable = mkEnableOption "xmonad"; enable = mkEnableOption "xmonad";
@ -62,19 +66,50 @@ in
default = null; default = null;
type = with lib.types; nullOr (either path str); type = with lib.types; nullOr (either path str);
description = '' description = ''
Configuration from which XMonad gets compiled. If no value Configuration from which XMonad gets compiled. If no value is
is specified, the xmonad config from $HOME/.xmonad is taken. specified, a vanilla xmonad binary is put in PATH, which will
If you use xmonad --recompile, $HOME/.xmonad will be taken as attempt to recompile and exec your xmonad config from $HOME/.xmonad.
the configuration, but on the next restart of display-manager This setup is then analogous to other (non-NixOS) linux distributions.
this config will be reapplied.
If you do set this option, you likely want to use "launch" as your
entry point for xmonad (as in the example), to avoid xmonads
recompilation logic on startup. Doing so will render the default
"mod+q" restart key binding dysfunctional though, because that attempts
to call your binary with the "--restart" command line option, unless
you implement that yourself. You way mant to bind "mod+q" to
<literal>(restart "xmonad" True)</literal> instead, which will just restart
xmonad from PATH. This allows e.g. switching to the new xmonad binary,
after rebuilding your system with nixos-rebuild.
If you actually want to run xmonad with a config specified here, but
also be able to recompile and restart it from a copy of that source in
$HOME/.xmonad on the fly, you will have to implement that yourself
using something like "compileRestart" from the example.
This should allow you to switch at will between the local xmonad and
the one NixOS puts in your PATH.
''; '';
example = '' example = ''
import XMonad import XMonad
import XMonad.Util.EZConfig (additionalKeys)
import Text.Printf (printf)
import System.Posix.Process (executeFile)
import System.Info (arch,os)
import System.Environment (getArgs)
import System.FilePath ((</>))
compiledConfig = printf "xmonad-%s-%s" arch os
compileRestart = whenX (recompile True) . catchIO $ do
dir <- getXMonadDataDir
args <- getArgs
executeFile (dir </> compiledConfig) False args Nothing
main = launch defaultConfig main = launch defaultConfig
{ modMask = mod4Mask -- Use Super instead of Alt { modMask = mod4Mask -- Use Super instead of Alt
, terminal = "urxvt" , terminal = "urxvt" }
} `additionalKeys`
[ ( (mod4Mask,xK_r), compileRestart )
, ( (mod4Mask,xK_q), restart "xmonad" True ) ]
''; '';
}; };
@ -101,10 +136,8 @@ in
services.xserver.windowManager = { services.xserver.windowManager = {
session = [{ session = [{
name = "xmonad"; name = "xmonad";
start = let start = ''
xmonadCommand = if (cfg.config != null) then xmonadBin else "${xmonad}/bin/xmonad"; systemd-cat -t xmonad -- ${xmonad}/bin/xmonad ${lib.escapeShellArgs cfg.xmonadCliArgs} &
in ''
systemd-cat -t xmonad -- ${xmonadCommand} ${lib.escapeShellArgs cfg.xmonadCliArgs} &
waitPID=$! waitPID=$!
''; '';
}]; }];

View File

@ -14,9 +14,16 @@ import ./make-test-python.nix ({ pkgs, ...} : {
extraPackages = with pkgs.haskellPackages; haskellPackages: [ xmobar ]; extraPackages = with pkgs.haskellPackages; haskellPackages: [ xmobar ];
config = '' config = ''
import XMonad import XMonad
import XMonad.Operations (restart)
import XMonad.Util.EZConfig import XMonad.Util.EZConfig
main = launch $ def `additionalKeysP` myKeys import XMonad.Util.SessionStart
myKeys = [ ("M-C-x", spawn "xterm") ]
main = launch $ def { startupHook = startup } `additionalKeysP` myKeys
startup = isSessionStart >>= \sessInit ->
if sessInit then setSessionStarted else spawn "xterm"
myKeys = [ ("M-C-x", spawn "xterm"), ("M-q", restart "xmonad" True) ]
''; '';
}; };
}; };
@ -30,12 +37,11 @@ import ./make-test-python.nix ({ pkgs, ...} : {
machine.send_key("alt-ctrl-x") machine.send_key("alt-ctrl-x")
machine.wait_for_window("${user.name}.*machine") machine.wait_for_window("${user.name}.*machine")
machine.sleep(1) machine.sleep(1)
machine.screenshot("terminal") machine.screenshot("terminal1")
machine.wait_until_succeeds("xmonad --restart") machine.send_key("alt-q")
machine.sleep(3) machine.sleep(3)
machine.send_key("alt-shift-ret")
machine.wait_for_window("${user.name}.*machine") machine.wait_for_window("${user.name}.*machine")
machine.sleep(1) machine.sleep(1)
machine.screenshot("terminal") machine.screenshot("terminal2")
''; '';
}) })