I've been able to change the keyboard layout/mapping when the X Window System is running using ~/.Xmodmap (and I suppose you could also do it through the X protocol directly, eg. using libxcb as a wrapper around X protocol calls).

I've been able to do the same (somewhat) on the console/tty (ie. when X is not running) using loadkeys.

Is there a way to customize the keyboard layout similarly, but from a single source, in such a way that it affects both X and the console, ie. in a way that is "X-and-console agnostic"?

(The only way I can think of is by writing a "keyboard driver" that talks to the kernel's input interface, evdev, and sends the input you want (through uinput?), or something, but I don't know if this even makes sense, or if there's an easier way.)

  • 2
    Possible duplicate of keyboard hard remap keys? Nov 4, 2018 at 1:16
  • Which distro? On debian there is a dpkg-reconfigure keyboard-configuration, on Red Hat: localectl set-keymap and similar. Is this what you need? Related1 and Related2
    – user232326
    Nov 4, 2018 at 1:33
  • The suggested duplicate doesn't involve adjusting the console keymapping -- the OP specified that they "did not try loadkeys, as [the affected app] is running on X".
    – JigglyNaga
    Nov 5, 2018 at 8:18

1 Answer 1


Yes, there is a way, and this is indeed how Debian's console-setup package does it.

  • Keyboard layouts are specified in XKB terms (model, layout, variant, and options) by the administrator in a file named keyboard, usually /etc/default/keyboard. This is the single source. It can be edited with a text editor.
  • The setxkbmap program is given these same XKB settings and configures an X11 server accordingly.
    • The keyboard-configuration package's post-installation maintainer script runs setxkbmap directly, with the /etc/default/keyboard settings, if it finds itself with an X11 display. Thus dpkg-reconfigure keyboard-configuration run from an X11 GUI terminal emulator will affect the X11 keyboard layout.
  • The setupcon script takes these XKB settings, passes them through the ckbcomp utility to generate a keyboard map, and loads that keyboard map into the kernel virtual terminals with loadkeys/kbdcontrol.
    • This script is run at system bootstrap by a service.
    • It can also be run manually elsewhen.

Other systemd operating systems work differently but also have a single source.

  • The XKB layout, variant, and options are stored in in /etc/X11/xorg.conf.d/00-keyboard.conf. This is the single source.
    • This file is directly read by the X11 server at startup and sets the X11 keyboard map directly.
    • This file is parsed by systemd-localed at startup. The file cannot be usefully edited with a text editor whilst systemd-localed is running, because the service will blithely overwrite it with its own in-memory information.
    • To change the XKB information, one runs localectl, which talks to another server which in turn talks to systemd-localed.
  • systemd-localed converts the XKB settings to a virtual terminal keyboard map name using the mappings in /usr/share/systemd/kbd-model-map, which it then writes out to /etc/vconsole.conf. Unlike the Debian system, it does not generate maps on the fly from the XKB information, but selects only pre-supplied static maps listed in the map file.
  • systemd-vconsole-setup runs at bootstrap, reads /etc/vconsole.conf, and loads the keyboard map into the kernel virtual terminals by running loadkeys.

Further reading

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .