Keyboard Layout Customization: Difference between revisions

From NixOS Wiki
imported>Heartbeast42
For the section on xmodmap: Fix heading size to match other headings, make heading clearer, reframe copy to be more general rather than being about 1 users experience.
mNo edit summary
Line 17: Line 17:


For desktop:
For desktop:
<source lang="nix">
<syntaxhighlight lang="nix">
services.xserver = {
services.xserver = {
   layout = "us,ru";
   layout = "us,ru";
Line 23: Line 23:
   xkbOptions = "grp:win_space_toggle";
   xkbOptions = "grp:win_space_toggle";
};
};
</source>
</syntaxhighlight>


For console:  
For console:  
<source lang="nix">
<syntaxhighlight lang="nix">
console.keyMap = "us";
console.keyMap = "us";
</source>
</syntaxhighlight>


You can find valid values for these options in <code>$(nix-build --no-out-link '&lt;nixpkgs&gt;' -A xkeyboard_config)/etc/X11/xkb/rules/base.lst</code>
You can find valid values for these options in <code>$(nix-build --no-out-link '&lt;nixpkgs&gt;' -A xkeyboard_config)/etc/X11/xkb/rules/base.lst</code>
Line 40: Line 40:
To load this file at the start of the X session, add the following to your <code>configuration.nix</code>. The extra compilation step (<code>xkbcomp</code>) helps catching layout errors at build time.
To load this file at the start of the X session, add the following to your <code>configuration.nix</code>. The extra compilation step (<code>xkbcomp</code>) helps catching layout errors at build time.


<source lang="nix">
<syntaxhighlight lang="nix">
let
let
   compiledLayout = pkgs.runCommand "keyboard-layout" {} ''
   compiledLayout = pkgs.runCommand "keyboard-layout" {} ''
Line 47: Line 47:
in
in
   services.xserver.displayManager.sessionCommands = "${pkgs.xorg.xkbcomp}/bin/xkbcomp ${compiledLayout} $DISPLAY";
   services.xserver.displayManager.sessionCommands = "${pkgs.xorg.xkbcomp}/bin/xkbcomp ${compiledLayout} $DISPLAY";
</source>
</syntaxhighlight>


If you are using home-manager, you also need to prevent home-manager from managing the keyboard by having <code>home.keyboard = null;</code> in your home-manager configuration.
If you are using home-manager, you also need to prevent home-manager from managing the keyboard by having <code>home.keyboard = null;</code> in your home-manager configuration.
Line 65: Line 65:
Some users have found xmodmap to be a helpful tool although reports of successful implementation are varied.
Some users have found xmodmap to be a helpful tool although reports of successful implementation are varied.


<source lang="nix">
<syntaxhighlight lang="nix">


cat /etc/nixos/configuration.nix
cat /etc/nixos/configuration.nix
Line 84: Line 84:
   ''}"
   ''}"


</source>
</syntaxhighlight>


Works after boot and after suspend/resume.
Works after boot and after suspend/resume.
Line 90: Line 90:
You may need to add some delay to make xmodmap command work.
You may need to add some delay to make xmodmap command work.


<source lang="nix">
<syntaxhighlight lang="nix">
   services.xserver.displayManager.sessionCommands = "sleep 5 && ${pkgs.xorg.xmodmap}/bin/xmodmap -e 'keycode 43 = h H Left H' &";
   services.xserver.displayManager.sessionCommands = "sleep 5 && ${pkgs.xorg.xmodmap}/bin/xmodmap -e 'keycode 43 = h H Left H' &";
</source>
</syntaxhighlight>

Revision as of 01:35, 5 April 2024

20.09 and later

In 20.09 there's services.xserver.extraLayouts for this.

Using xkbcomp

Simple

The easiest way to customize your keyboard layout on NixOS is with these options:

  • services.xserver.layout: Keyboard layout, or multiple keyboard layouts separated by commas.
  • services.xserver.xkbVariant: X keyboard variant or multiple variants separated by commas (a variant can be empty).
  • services.xserver.xkbModel: Keyboard model.
  • services.xserver.xkbOptions: X keyboard options; layout switching goes here.
Example:

For desktop:

services.xserver = {
  layout = "us,ru";
  xkbVariant = "workman,";
  xkbOptions = "grp:win_space_toggle";
};

For console:

console.keyMap = "us";

You can find valid values for these options in $(nix-build --no-out-link '<nixpkgs>' -A xkeyboard_config)/etc/X11/xkb/rules/base.lst

Advanced

If the above options aren't enough, you can instead create your own keyboard layout by going through xkb. To get started, install xorg.xkbcomp and run setxkbmap -print > layout.xkb to get an initial file. This corresponds to your current layout. Use xkbcomp layout.xkb $DISPLAY to load the file as your new layout. Refer to https://wiki.archlinux.org/index.php/X_KeyBoard_extension on how to edit this file.

Lots of examples can be found in $(nix-build --no-out-link '<nixpkgs>' -A xorg.xkeyboardconfig)/etc/X11/xkb/. For available key symbols, see $(nix-build --no-out-link '<nixpkgs>' -A xorg.xproto)/include/X11/keysymdef.h.

To load this file at the start of the X session, add the following to your configuration.nix. The extra compilation step (xkbcomp) helps catching layout errors at build time.

let
  compiledLayout = pkgs.runCommand "keyboard-layout" {} ''
    ${pkgs.xorg.xkbcomp}/bin/xkbcomp ${./path/to/layout.xkb} $out
  '';
in
  services.xserver.displayManager.sessionCommands = "${pkgs.xorg.xkbcomp}/bin/xkbcomp ${compiledLayout} $DISPLAY";

If you are using home-manager, you also need to prevent home-manager from managing the keyboard by having home.keyboard = null; in your home-manager configuration.

Relevant other options

  • services.xserver.exportConfiguration: Makes it so the above mentioned xkb directory (and the xorg.conf file) gets exported to /etc/X11/xkb, which is useful if you have to often look stuff up in it.
  • services.xserver.xkbDir: Allows you to set a different xkb directory altogether. All the above mentioned things will use this instead of the default one in regards to xkb stuff.
  • console.useXkbConfig: Makes it so the tty console has about the same layout as the one configured in the services.xserver options.

Configs

Advanced configuration with xmodmap

Some users have found xmodmap to be a helpful tool although reports of successful implementation are varied.

cat /etc/nixos/configuration.nix

services.xserver.displayManager.sessionCommands =
  ${pkgs.xorg.xmodmap}/bin/xmodmap "${pkgs.writeText  "xkb-layout" ''
    ! Map umlauts to RIGHT ALT + <key>
      keycode 108 = Mode_switch
      keysym e = e E EuroSign
      keysym c = c C cent
      keysym a = a A adiaeresis Adiaeresis
      keysym o = o O odiaeresis Odiaeresis
      keysym u = u U udiaeresis Udiaeresis
      keysym s = s S ssharp
    
      ! disable capslock
      ! remove Lock = Caps_Lock
  ''}"

Works after boot and after suspend/resume.

You may need to add some delay to make xmodmap command work.

  services.xserver.displayManager.sessionCommands = "sleep 5 && ${pkgs.xorg.xmodmap}/bin/xmodmap -e 'keycode 43 = h H Left H' &";