XMonad: Difference between revisions

From NixOS Wiki
imported>Efim
Adding way to get lsp support that worked for me
H7x4 (talk | contribs)
Add a few links
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[https://xmonad.org/ 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.
[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 [https://haskell.org/ Haskell]. Custom layout algorithms, key bindings and other extensions may be written by the user in configuration files.
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.
  services.xserver.windowManager.xmonad = {
    enable = true;
    enableContribAndExtras = true;
  };
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.
To add Haskell modules that are not included in the Xmonad-Contrib package, 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.
<syntaxHighlight lang="nix">
{ 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
    ];
  };
}
</syntaxHighlight>
Don't forget to add the module to your inputs:
<syntaxHighlight lang="nix">
inputs.xmonad-contexts = {
  url = "github:Procrat/xmonad-contexts";
  flake = false;
};
</syntaxHighlight>
== Configuration ==
To configure Xmonad you give Nix your config file like this:
<syntaxHighlight lang="nix">
services.xserver.windowManager.xmonad.config = builtins.readFile ../path/to/xmonad.hs;
</syntaxHighlight>
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>
  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>}}
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>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
services.xserver.windowManager.xmonad.enable = true;
  systemd.targets.hybrid-sleep.enable = true;
  services.logind.extraConfig = ''
    IdleAction=hybrid-sleep
    IdleActionSec=20s
  '';
</nowiki>}}
</nowiki>}}


== Configuration ==
The configuration above will let the system go to "hybrid-sleep" `20s` after the screen-saver triggered.
=== Configuring XMonad with IDE support ===
 
To edit XMonad configuration with IDE support, see https://www.srid.ca/xmonad-conf-ide
==== 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:


=== Another way to set up lsp support ===
<syntaxhighlight lang="console">
Previous way to set up lsp support didn't work for me.
$ xset q
[https://discourse.nixos.org/t/haskell-language-server-support-for-xmonad/12348 This post] helped:
$ sleep 1s && xset s activate
</syntaxhighlight>


=== Developer Environment for XMonad ===


==== if setting up xmonad with extra packages: ====
When developing modules for XMonad, it can help to install the following packages


{{file|~/.config/home-config.nix|nix|<nowiki>
<syntaxHighlight lang="nix">
e.g:
windowManager = {
windowManager = {
   xmonad = {
   xmonad = {
Line 31: Line 132:
       haskellPackages.List
       haskellPackages.List
       haskellPackages.monad-logger
       haskellPackages.monad-logger
      haskellPackages.xmonad
     ];
     ];
   };
   };
};
};
</nowiki>}}
</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].


==== having ghc and other things for the lsp server in the system: ====
==== Create a project around <code>xmonad.hs</code> ====
{{file|~/.config/home-config.nix|nix|<nowiki>
    home.packages = with pkgs; [
      haskellPackages.haskell-language-server
      haskellPackages.hoogle
      cabal-install
      stack
    ]
</nowiki>}}
(but I'm not sure whether all of those are required, maybe only one of cabal \ stack?)


==== creating project around `xmonad.hs` file ====
<syntaxHighlight lang="bash">
{{file|~/.config/xmonad/hie-bios.sh|sh|<nowiki>
echo "xmonad" >> $HIE_BIOS_OUTPUT  
echo "xmonad" >> $HIE_BIOS_OUTPUT  
</nowiki>}}
</syntaxHighlight>


{{file|~/.config/xmonad/hie.yaml|yaml|<nowiki>
{{file|~/.config/xmonad/hie.yaml|yaml|<nowiki>
Line 60: Line 152:
</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" utili, get with "nix-shell -p nix-tree"  
It can be easily found with "[https://github.com/utdemir/nix-tree nix-tree]", which shows dependencies between packages on the machine.
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 ====
[[Category:Window managers]]
I try to manually run "haskell-language-server" in the directory with `xmonad.hs`, `hie.yaml` and `hie-bios.sh`
[[Category:Applications]]
when there are no errors, my editor also successfully starts lsp

Latest revision as of 23:17, 15 September 2024

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.

To add Haskell modules that are not included in the Xmonad-Contrib package, you have to tell ghc where to find them. For example, you can use the following to add the [1] module.

{ 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 inputs:

inputs.xmonad-contexts = {
  url = "github:Procrat/xmonad-contexts";
  flake = false;
};

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.

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

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
~/.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", which shows dependencies between packages on the machine.