XMonad: Difference between revisions
imported>Zach-hill m Added to "Window managers" and "Applications" categories |
m →Adding Haskell Modules: fix typo |
||
(8 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
[https://xmonad.org/ xmonad] is a tiling [ | [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. | ||
== Installation == | == 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 <code>enableContribAndExtras</code> option. | |||
{{file|/etc/nixos/configuration.nix|nix| | |||
<nowiki> | |||
services.xserver.windowManager.xmonad = { | |||
enable = true; | |||
enableContribAndExtras = true; | |||
}; | |||
</nowiki> | |||
}} | |||
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. | |||
=== 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, ... }: | |||
{ | |||
... | |||
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> | |||
}} | |||
Don't forget to add the module to your flake inputs: | |||
{{file|/etc/nixos/flake.nix|nix| | |||
<nowiki> | |||
inputs.xmonad-contexts = { | |||
url = "github:Procrat/xmonad-contexts"; | |||
flake = false; | |||
}; | |||
</nowiki> | |||
}} | |||
== 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| | |||
<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]. | |||
== Power management == | |||
Xmonad is a Window Manager (WM) and not a Desktop Environment (DE). Therefore, among other things, | |||
Xmonad does not handle [[Power Management|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 [[Xorg|XServer]] detect idle-situation | |||
* Inform "[[Systemd/logind|logind]]" (i.e. "systemd") about the situation | |||
* Let "logind" make the system sleep | |||
We'll configure the XServers screensaver-settings to pick up inactivity: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | {{file|/etc/nixos/configuration.nix|nix|<nowiki> | ||
services.xserver. | 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 & | |||
''; | |||
</nowiki>}} | </nowiki>}} | ||
== | You'll have to re-login for the settings above to be applied. | ||
=== | |||
The settings above will toggle the flag "IdleHint" within logind through [https://github.com/the-cavalry/light-locker#light-locker light-locker] (will work with "'lightdm'", there are alternatives). | |||
Next we'll have to pick-up the information within logindand select an [https://www.freedesktop.org/software/systemd/man/logind.conf.d.html#IdleAction= action to take]: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | |||
systemd.targets.hybrid-sleep.enable = true; | |||
services.logind.extraConfig = '' | |||
IdleAction=hybrid-sleep | |||
IdleActionSec=20s | |||
''; | |||
</nowiki>}} | |||
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: | |||
<syntaxhighlight lang="console"> | |||
$ watch "loginctl show-session | grep Idle" | |||
</syntaxhighlight> | |||
Try setting the flag manually (also need to disable manually): | |||
<syntaxhighlight lang="console"> | |||
$ dbus-send --system --print-reply \ | |||
--dest=org.freedesktop.login1 /org/freedesktop/login1/session/self \ | |||
"org.freedesktop.login1.Session.SetIdleHint" boolean:true | |||
</syntaxhighlight> | |||
Check if the xset-settings have been applied properly and activate the screensaver manually: | |||
= | <syntaxhighlight lang="console"> | ||
$ xset q | |||
$ sleep 1s && xset s activate | |||
</syntaxhighlight> | |||
== Developer Environment for XMonad == | |||
When developing modules for XMonad, it can help to install the following packages | |||
<syntaxHighlight lang="nix"> | |||
windowManager = { | windowManager = { | ||
xmonad = { | xmonad = { | ||
Line 31: | Line 189: | ||
haskellPackages.List | haskellPackages.List | ||
haskellPackages.monad-logger | haskellPackages.monad-logger | ||
]; | ]; | ||
}; | }; | ||
}; | }; | ||
</ | </syntaxHighlight> | ||
More information can be found [https://discourse.nixos.org/t/haskell-language-server-support-for-xmonad/12348 here] and [https://www.srid.ca/xmonad-conf-ide here]. | |||
==== | ==== Create a project around <code>xmonad.hs</code> ==== | ||
</ | |||
= | <syntaxHighlight lang="bash"> | ||
echo "xmonad" >> $HIE_BIOS_OUTPUT | echo "xmonad" >> $HIE_BIOS_OUTPUT | ||
</ | </syntaxHighlight> | ||
{{file|~/.config/xmonad/hie.yaml|yaml|<nowiki> | {{file|~/.config/xmonad/hie.yaml|yaml|<nowiki> | ||
Line 60: | Line 209: | ||
</nowiki>}} | </nowiki>}} | ||
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 | 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]] |