XMonad
xmonad is a tiling window manager for X. Windows are arranged automatically to tile the screen without gaps or overlap, maximizing screen use. Window manager features are accessible from the keyboard: a mouse is optional.
xmonad is written, configured and extensible in Haskell. Custom layout algorithms, key bindings and other extensions may be written by the user in configuration files.
Layouts are applied dynamically, and different layouts may be used on each workspace. Xinerama is fully supported, allowing windows to be tiled on several physical screens.
Installation
The simplest way to install Xmonad is to activate the corresponding NixOS module. You can do this by adding the following to your NixOS configuration. You probably also want to activate the <core>enableContribAndExtras option.
services.xserver.windowManager.xmonad = { enable = true; enableContribAndExtras = true; };
The second options automatically adds the xmonad-contrib
and xmonad-extras
packages.
They are required to use the Xmonad Contrib extensions.
Configuration
To configure Xmonad you give Nix your config file like this:
services.xserver.windowManager.xmonad.config = builtins.readFile ../path/to/xmonad.hs;
More information on how to configure Xmonad can be found in the Arch Wiki, and a list of starter configs can be found in the Xmonad Config Archive.
Configuring XMonad with IDE support
To edit XMonad configuration with IDE support, see https://www.srid.ca/xmonad-conf-ide
Another way to set up lsp support
Previous way to set up lsp support didn't work for me. This post helped:
if setting up xmonad with extra packages:
~/.config/home-config.nix
e.g:
windowManager = {
xmonad = {
enable = true;
enableContribAndExtras = true;
extraPackages = haskellPackages: [
haskellPackages.dbus
haskellPackages.List
haskellPackages.monad-logger
haskellPackages.xmonad
];
};
};
having ghc and other things for the lsp server in the system:
~/.config/home-config.nix
home.packages = with pkgs; [
haskellPackages.haskell-language-server
haskellPackages.hoogle
cabal-install
stack
]
(but I'm not sure whether all of those are required, maybe only one of cabal \ stack?)
creating project around `xmonad.hs` file
~/.config/xmonad/hie-bios.sh
echo "xmonad" >> $HIE_BIOS_OUTPUT
~/.config/xmonad/hie.yaml
cradle:
bios:
program: "./hie-bios.sh"
with-ghc: "/nix/store/waa0dlvlszwbplrz5c7j674ab6v1n5wi-ghc-8.8.4-with-packages/bin/ghc"
The "with-ghc" should be ghc that's in the "ghc-with-packages" dependency of the "xmonad-with-packages" It can be easily found with "nix-tree" utili, get with "nix-shell -p nix-tree" this shows dependencies between packages on the machine, "/" is for searching for "with-packages" see the store path in the bottom of the screen
to check what are the problems
I try to manually run "haskell-language-server" in the directory with `xmonad.hs`, `hie.yaml` and `hie-bios.sh` when there are no errors, my editor also successfully starts lsp
Power management
Xmonad is a Window Manager (WM) and not a Desktop Environment (DE). Therefore, among other things, Xmonad does not handle power management related things such as sleeping. However, there are several ways of still adding this functionality.
Suspend system after inactivity
The approach goes through the following steps:
- Let the XServer detect idle-situation
- Inform "logind" (i.e. "systemd") about the situation
- Let "logind" make the system sleep
We'll configure the XServers screensaver-settings to pick up inactivity:
/etc/nixos/configuration.nix
services.xserver.displayManager.sessionCommands = ''
xset -dpms # Disable Energy Star, as we are going to suspend anyway and it may hide "success" on that
xset s blank # `noblank` may be useful for debugging
xset s 300 # seconds
${pkgs.lightlocker}/bin/light-locker --idle-hint &
'';
You'll have to re-login for the settings above to be applied.
The settings above will toggle the flag "IdleHint" within logind through light-locker (will work with "'lightdm'", there are alternatives). Next we'll have to pick-up the information within logindand select an action to take:
/etc/nixos/configuration.nix
systemd.targets.hybrid-sleep.enable = true;
services.logind.extraConfig = ''
IdleAction=hybrid-sleep
IdleActionSec=20s
'';
The configuration above will let the system go to "hybrid-sleep" `20s` after the screen-saver triggered.
Troubleshooting
Check if the values of "IdleSinceHint" and "IdleSinceHintMonotonic" update using the command:
$ watch "loginctl show-session | grep Idle"
Try setting the flag manually (also need to disable manually):
$ dbus-send --system --print-reply \
--dest=org.freedesktop.login1 /org/freedesktop/login1/session/self \
"org.freedesktop.login1.Session.SetIdleHint" boolean:true
Check if the xset-settings have been applied properly and activate the screensaver manually:
$ xset q
$ sleep 1s && xset s activate