XMonad: Difference between revisions
imported>Jooooscha Clean up rest of the entry, remove some nonsensical parts |
m →Adding Haskell Modules: fix typo |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
[https://xmonad.org/ xmonad] is a tiling [https://wiki.archlinux.org/title/Window_manager 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. | [https://xmonad.org/ xmonad] is a tiling [https://wiki.archlinux.org/title/Window_manager window manager] for [[Xorg|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 [ | 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. [[Wikipedia:Xinerama|Xinerama]] is fully supported, allowing windows to be tiled on several physical screens. | Layouts are applied dynamically, and different layouts may be used on each workspace. [[Wikipedia:Xinerama|Xinerama]] is fully supported, allowing windows to be tiled on several physical screens. | ||
Line 11: | Line 11: | ||
You probably also want to activate the <code>enableContribAndExtras</code> option. | You probably also want to activate the <code>enableContribAndExtras</code> option. | ||
{{file|/etc/nixos/configuration.nix|nix| | |||
<nowiki> | |||
services.xserver.windowManager.xmonad = { | services.xserver.windowManager.xmonad = { | ||
enable = true; | enable = true; | ||
enableContribAndExtras = true; | enableContribAndExtras = true; | ||
}; | }; | ||
</nowiki> | |||
}} | |||
The second options automatically adds the <code>xmonad-contrib</code> and <code>xmonad-extras</code> packages. | The second options automatically adds the <code>xmonad-contrib</code> and <code>xmonad-extras</code> packages. | ||
They are required to use the [https://hackage.haskell.org/package/xmonad-contrib Xmonad Contrib] extensions. | They are required to use the [https://hackage.haskell.org/package/xmonad-contrib Xmonad Contrib] extensions. | ||
=== Adding Haskell Modules === | |||
< | To add additional Haskell modules beyond xmonad-contrib and xmonad-extras, use the <code>extraPackages</code> option | ||
{{file|/etc/nixos/configuration.nix|nix| | |||
<nowiki> | |||
... | |||
services.xserver.windowManager.xmonad = { | |||
... | |||
extraPackages = haskellPackages: [ | |||
haskellPackages.monad-logger | |||
]; | |||
}; | |||
</nowiki> | |||
}} | |||
To add Haskell modules that are not in the Haskell Nix package set, you have to tell ghc where to find them. | |||
For example, you can use the following to add the [https://github.com/Procrat/xmonad-contexts xmonad-contexts] module. | |||
{{file|/etc/nixos/configuration.nix|nix| | |||
<nowiki> | |||
{ config, pkgs, ... }: | |||
let | |||
xmonad-contexts = pkgs.fetchFromGitHub { | |||
owner = "Procrat"; | |||
repo = "xmonad-contexts"; | |||
rev = "SOME_COMMIT_HASH"; # replace with an actual commit for reproducibility | |||
sha256 = "sha256-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; | |||
}; | |||
in { | |||
... | |||
services.xserver.windowManager.xmonad = { | |||
... | |||
ghcArgs = [ | |||
"-hidir /tmp" # place interface files in /tmp, otherwise ghc tries to write them to the nix store | |||
"-odir /tmp" # place object files in /tmp, otherwise ghc tries to write them to the nix store | |||
"-i${xmonad-contexts}" # tell ghc to search in the respective nix store path for the module | |||
]; | |||
}; | |||
} | |||
</nowiki> | |||
}} | |||
or if you are using Flakes | |||
{{file|/etc/nixos/configuration.nix|nix| | |||
<nowiki> | |||
{ xmonad-contexts, ... }: | { xmonad-contexts, ... }: | ||
{ | { | ||
... | ... | ||
services.xserver.windowManager.xmonad = { | services.xserver.windowManager.xmonad = { | ||
... | ... | ||
Line 35: | Line 82: | ||
}; | }; | ||
} | } | ||
</ | </nowiki> | ||
}} | |||
Don't forget to add the module to your inputs: | Don't forget to add the module to your flake inputs: | ||
< | {{file|/etc/nixos/flake.nix|nix| | ||
<nowiki> | |||
inputs.xmonad-contexts = { | inputs.xmonad-contexts = { | ||
url = "github:Procrat/xmonad-contexts"; | url = "github:Procrat/xmonad-contexts"; | ||
flake = false; | flake = false; | ||
}; | }; | ||
</ | </nowiki> | ||
}} | |||
== Configuration == | == Configuration == | ||
<code>$HOME/.xmonad</code> is the default path used for the configuration file. If your configuration is in a different location, give Nix your Xmonad config file like this: | |||
< | {{file|/etc/nixos/configuration.nix|nix| | ||
services.xserver.windowManager.xmonad.config = builtins.readFile ../path/to/xmonad.hs; | <nowiki> | ||
</ | services.xserver.windowManager.xmonad = { | ||
... | |||
config = builtins.readFile ../path/to/xmonad.hs; | |||
}; | |||
</nowiki> | |||
}} | |||
See [https://search.nixos.org/options?query=services.xserver.windowManager.xmonad services.xserver.windowManager.xmonad] for a full list of available options and their descriptions. | |||
More information on how to configure Xmonad can be found in the [https://wiki.archlinux.org/title/Xmonad Arch Wiki], and a list of starter configs can be found in the [https://wiki.haskell.org/Xmonad/Config_archive Xmonad Config Archive]. | More information on how to configure Xmonad can be found in the [https://wiki.archlinux.org/title/Xmonad Arch Wiki], and a list of starter configs can be found in the [https://wiki.haskell.org/Xmonad/Config_archive Xmonad Config Archive]. | ||
Line 59: | Line 116: | ||
Xmonad is a Window Manager (WM) and not a Desktop Environment (DE). Therefore, among other things, | 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. | Xmonad does not handle [[Power Management|power management]] related things such as sleeping. | ||
However, there are several ways of still adding this functionality. | However, there are several ways of still adding this functionality. | ||
Line 66: | Line 123: | ||
The approach goes through the following steps: | The approach goes through the following steps: | ||
* Let the XServer detect idle-situation | * Let the [[Xorg|XServer]] detect idle-situation | ||
* Inform "logind" (i.e. "systemd") about the situation | * Inform "[[Systemd/logind|logind]]" (i.e. "systemd") about the situation | ||
* Let "logind" make the system sleep | * Let "logind" make the system sleep | ||
Line 119: | Line 176: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Developer Environment for XMonad == | |||
When developing modules for XMonad, it can help to install the following packages | When developing modules for XMonad, it can help to install the following packages | ||
Line 153: | Line 210: | ||
The "with-ghc" should be ghc that's in the "ghc-with-packages" dependency of the "xmonad-with-packages". | 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", which shows dependencies between packages on the machine. | It can be easily found with "[https://github.com/utdemir/nix-tree nix-tree]", which shows dependencies between packages on the machine. | ||
[[Category:Window managers]] | [[Category:Window managers]] | ||
[[Category:Applications]] | [[Category:Applications]] |
Latest revision as of 05:51, 12 May 2025
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 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.
Adding Haskell Modules
To add additional Haskell modules beyond xmonad-contrib and xmonad-extras, use the extraPackages
option
...
services.xserver.windowManager.xmonad = {
...
extraPackages = haskellPackages: [
haskellPackages.monad-logger
];
};
To add Haskell modules that are not in the Haskell Nix package set, you have to tell ghc where to find them. For example, you can use the following to add the xmonad-contexts module.
{ config, pkgs, ... }:
let
xmonad-contexts = pkgs.fetchFromGitHub {
owner = "Procrat";
repo = "xmonad-contexts";
rev = "SOME_COMMIT_HASH"; # replace with an actual commit for reproducibility
sha256 = "sha256-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
};
in {
...
services.xserver.windowManager.xmonad = {
...
ghcArgs = [
"-hidir /tmp" # place interface files in /tmp, otherwise ghc tries to write them to the nix store
"-odir /tmp" # place object files in /tmp, otherwise ghc tries to write them to the nix store
"-i${xmonad-contexts}" # tell ghc to search in the respective nix store path for the module
];
};
}
or if you are using Flakes
{ xmonad-contexts, ... }:
{
...
services.xserver.windowManager.xmonad = {
...
ghcArgs = [
"-hidir /tmp" # place interface files in /tmp, otherwise ghc tries to write them to the nix store
"-odir /tmp" # place object files in /tmp, otherwise ghc tries to write them to the nix store
"-i${xmonad-contexts}" # tell ghc to search in the respective nix store path for the module
];
};
}
Don't forget to add the module to your flake inputs:
inputs.xmonad-contexts = {
url = "github:Procrat/xmonad-contexts";
flake = false;
};
Configuration
$HOME/.xmonad
is the default path used for the configuration file. If your configuration is in a different location, give Nix your Xmonad config file like this:
services.xserver.windowManager.xmonad = {
...
config = builtins.readFile ../path/to/xmonad.hs;
};
See services.xserver.windowManager.xmonad for a full list of available options and their descriptions.
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.
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:
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:
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
Developer Environment for XMonad
When developing modules for XMonad, it can help to install the following packages
windowManager = {
xmonad = {
enable = true;
enableContribAndExtras = true;
extraPackages = haskellPackages: [
haskellPackages.dbus
haskellPackages.List
haskellPackages.monad-logger
];
};
};
More information can be found here and here.
Create a project around xmonad.hs
echo "xmonad" >> $HIE_BIOS_OUTPUT
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", which shows dependencies between packages on the machine.