UNIX / Linux keyboard.

How to Customize Your Linux Interface

Customize Your Keyboard and Mouse

You interact with your Linux system with the keyboard and mouse, so you should customize both of them to best match your personal tastes and habits. Most importantly, you need to know how to modify your keyboard layout so you get the expected character when you press a key. You may want to disable the Caps Lock key or otherwise modify or swap individual keys. Some people prefer to use a left-handed mouse, others need to directly enter enter non-ASCII or accented characters. Finally, you may need to reconfigure your display manager to change its behavior or have it start an SSH agent for the user.

You may be wondering how you are going to run commands or edit files when you don't know which characters the keys actually produce. You don't. Connect in over SSH from a machine with a well-configured keyboard and do the work there. Then walk over to the physical console of the machine you're working on and experiment with key presses. You will be looking at the login prompt, but you can enter and you should see any printing characters there. No, you're not going to log in as `~!@#$%^&*()_-+={}[]|\<>?, but you can try typing that to make sure that the punctuation marks are in their proper places.

Use the showkey command to display which key code is generated by each key press. You need to be logged in on the text keyboard for this. It will keep showing you key events as long as you keep pressing keys. When you're done, stop. The program terminates after 10 seconds of keyboard inactivity.

As for the keyboard layout, this can be set or changed three times between booting the system and setting up your graphical environment. First, the kernel applies a keyboard layout. Second, when the X server starts, it may change some of the keys. Third, after the user has logged in under an X environment, the keys may be modified further.

Configure the keyboard layout

A very early boot program sets the pre-configured keyboard details. The program doing this will be either /etc/rc.d/rc.sysinit on older systems with boot scripts, or something like the binary executable /lib/systemd/systemd-localed on systems using the newer systemd.

Whichever boot program is called, it will read the file /etc/{default,sysconfig}/keyboard. Here is what that file looks like on my main Linux system. Notice that it also specifies which key becomes the Compose key, something we will use below in order to enter accented characters or characters otherwise not on our keyboard.

XkbModel=pc105
XkbLayout=us
KEYBOARD=us
KEYTABLE=us
XkbOptions=compose:rwin 

See the XKB Configuration Guide for more details and advanced tricks, like having three national keyboard layouts that you switch between by pressing Alt+Shift or another combination of your choice.

On BSD, the keyboard type (if other than pc-xt) goes in /etc/kbdtype and the keyboard mapping and any other options go in /etc/wsconsctl.conf. Here we explicitly set the mapping to US and set the repeat function to start after a key is held down for 400 msec and then to output duplicates every 100 msec. That is, wait 0.4 seconds, then repeat at 10/second.

keyboard.encoding=us
keyboard.repeat.del1=400
keyboard.repeat.deln=100 

Modify the keyboard layout

Modify your keyboard layout after the system has been booted by running the appropriate command with a parameter naming the keymap. Most are pretty obvious country codes: fr, uk, us, or a country code with a modifier: uk-latin1, dvorak-uk, etc.

Linux

# loadkeys keymap 

If things get messed up, use the -d option to reset it to the default.

BSD

# kbd keymap 

Run the following command to see a list of available choices. The keymap file names on Linux end with ".map.gz", leave that off when loading that keymap.

Linux

# find /usr/lib/kbd/keymaps | sort 

BSD

# kbd -l 

Modify the Locale

You should have set this correctly when installing the system, based on the keyboard and the language you asked for. Hopefully you will never need to change this, as it can be confusing.

According to the manual pages, it should be set in /etc/locale.conf. However, it may be set in /etc/default/locale or perhaps /etc/sysconfig/i18n. And it seems that some settings may be reset, or not applied. For example, on my Mageia system I see the following. None agree!

# sort /etc/sysconfig/i18n
LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8:en_US:en
LC_ADDRESS=en_US.UTF-8
LC_COLLATE=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_IDENTIFICATION=en_US.UTF-8
LC_MEASUREMENT=en_US.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_MONETARY=en_US.UTF-8
LC_NAME=en_US.UTF-8
LC_NUMERIC=en_US.UTF-8
LC_PAPER=en_US.UTF-8
LC_TELEPHONE=en_US.UTF-8
LC_TIME=en_US.UTF-8
SYSFONT=lat0-16
# locale
LANG=
LC_ADDRESS="POSIX"
LC_ALL=
LC_COLLATE="POSIX"
LC_CTYPE=en_US
LC_IDENTIFICATION="POSIX"
LC_MEASUREMENT="POSIX"
LC_MESSAGES=en_US
LC_MONETARY=en_US
LC_NAME="POSIX"
LC_NUMERIC=en_US
LC_PAPER="POSIX"
LC_TELEPHONE="POSIX"
LC_TIME=en_US 

You should be able to see the list of all available locales:

# locale -a 

You may be able to see a list of available locales and charmaps:

# ls /usr/share/i18n/locales /usr/share/i18n/charmaps 

Like so many other subsystems, control of locale has been taken over by systemd. You can see the current locale, see the available choices, and set a new locale and charset.

# localectl status
    [...]
# localectl list-locales
    [...]
# localectl setlocale LANG="en_US.utf8" LC_CTYPE="en_US"
    [ or, more simply: ]
# localectl setlocale en_US.UTF-8 

It is very confusing that you select UTF-8 character encoding as "utf8" but it is reported in command output as "UTF-8".

Disabling the Caps Lock Key

Every keyboard has a Caps Lock key, but I only find it dangerous instead of helpful. Let's say you're in a vi session and you accidentally hit the Caps Lock key. You expect the h, j, k, and l keys to simply move the cursor one position left, down, up, and right, respectively. But suddenly things are radically and dangerously different:

Without Caps Lock
h One position left
j One position down
k One position up
l One position right
With Caps Lock
H Jump to first non-blank character on the top line within the visible buffer
J "Jerk" the next line so it is appended to the current line
K Do a man -k keyword lookup for the word currently under the cursor
L Jump to first non-blank character on the bottom line within the visible buffer

I don't want the dangerous and fairly useless Caps Lock key doing strange and unwanted things. I prefer to turn the Caps Lock key into another Control key. If I really need to UNLEASH THE RAGE OF ALL CAPS, I hold down a Shift key.

This is complicated by the existence of two keyboard mappings. The first is used by the kernel. You change the mapping between key codes, basically the numbers generated by key presses, and the associated characters or special keys (Shift, Control, etc) with the loadkeys command. Boot-time configfuration is defined by the KEYBOARD and KEYTABLE lines in /etc/sysconfig/keyboard or /etc/default/keyboard (In BSD it's the kbd command and /etc/kbdtype file).

In a graphical environment the X server handles keyboard and mouse input, possibly using a different keyboard mapping. This is defined by the Xkb* lines in /etc/{sysconfig,default}/keyboard on Linux. Or at least that's how the root-owned X server process starts. Once the user has logged in and has permission to control the X server, the xmodmap command can be used to further modify the mapping of the keyboard and mouse.

On an OpenBSD laptop, /var/log/Xorg.0.log contains this:

... many lines deleted ...
(II) config/wscons: checking input device /dev/wskbd
(II) wskbd: ignoring "user" layout
(II) LoadModule: "kbd"
(II) Loading /usr/X11R6/lib/modules/input/kbd_drv.so
(II) Module kbd: vendor="X.Org Foundation"
   compiled for 1.15.2, module version = 1.8.0
   Module class: X.Org XInput Driver
   ABI class: X.Org XInput driver, version 20.0
(II) Using input driver 'kbd' for '/dev/wskbd'
(**) /dev/wskbd: always reports core events
(**) /dev/wskbd: always reports core events
(**) Option "Protocol" "standard"
(**) Option "XkbRules" "base"
(**) Option "XkbModel" "pc105"
(**) Option "XkbLayout" "us"
(II) XINPUT: Adding extended input device "/dev/wskbd" (type: KEYBOARD, id 6)
... many lines deleted ...

Let's solve the text consoles first. As this changes the mapping used by the kernel, it changes the keyboard layout for all users. I'm OK with that. If it's a server, it's mounted in a rack in the server room and not many people even see that interface. If it's a desktop or laptop, it's a personal workstation and so it has been personalized for that one person.

Then we will solve the problem under X. Because X uses its own mapping, solving this for text consoles does not also solve the problem on X.

Text Console Fix — Simple on BSD

It is relatively simple on BSD to change Caps Lock to another Control key. To fix it on the text consoles, simply add this line to /etc/wsconsctl.conf. Note that "Control_L" refers to the Left Control key and not Ctrl-L:

keyboard.map+="keysym Caps_Lock = Control_L" 

Text Console Fix — Almost as Simple on Linux

The simplest solution for Linux would be to add this block to /etc/rc.d/rc.local. The bare "-" tells loadkeys to read its standard input rather than a file.

# Change the Caps_Lock key another Control
dumpkeys | sed 's/Caps_Lock/Control/g' | loadkeys - 

As an alternative, I could do this as root:

# cd /usr/lib/kbd/keymaps/i386/qwerty
# gunzip us.map.gz
# vim us.map
    [--------------------------------------]
    [  Change the line currently reading:  ]
    [    keycode  58 = Caps_Lock           ]
    [  to instead read:                    ]
    [    keycode  58 = Control             ]
    [--------------------------------------]
# gzip us.map 

But that seems like a kludge that will likely be overwritten in some future update...

Graphics / X Fix

On Linux, you could modify /etc/{default,sysconfig}/keyboard as follows to change the Caps Lock key under graphics:

XkbModel=pc105
XkbLayout=us
KEYBOARD=us
KEYTABLE=us
XkbOptions="compose:rwin,ctrl:nocaps"

An better alternative that works on both Linux and BSD is to use the xmodmap command to make the change just for your graphical sessions. First, put this into your ~/.xmodmaprc file:

!
!  Caps_Lock <- Control
!
remove Lock = Caps_Lock
keysym Caps_Lock = Control_L
add Control = Control_L 

Then put this into a shell startup file in a section used only during interactive shell sessions:

xmodmap ~/.xmodmaprc > /dev/null 

Another alternative is to put this into a shell startup file in a section used only during interactive shell sessions. The first "-option" unsets any previously set options (probably not needed), the second applies the two specified here:

setxkbmap -option -option compose:rwin,ctrl:nocaps 

The many available options are listed in /usr/share/X11/xkb/rules/base.lst.

Also be aware that Gnome, KDE, and other desktop environments provide ways of remapping keys through a Settings menu choice.

And finally, for much more about changing keys in many operating systems, see this Emacs-oriented page.

Reconfiguring the Mouse

Some left-handed people (not me) prefer to remap the mouse buttons so the primary button is pressed with the index finger of their left hand. Just add this to your ~/.xmodmaprc file:

pointer = 3 2 1 

Again, Gnome, KDE, and other desktop environments may provide a way of remapping mouse buttons through a Settings menu choice.

Disabling a Synaptics touchpad

I find a touchpad to be much more trouble than help. If I have plugged a mouse into my laptop, I do not want the touchpad to do anything.

If I don't have a mouse plugged in, the touchpad is a little less dangerous if I disable its click-and-drag vertical scroll, and if I disable it while I'm using the keyboard.

Put this into a shell startup file in a section used only during interactive shell sessions:

# Disable the click-and-drag vertical scroll
synclient VertScrollDelta=0
# Disable the synaptics touchpad in general for 2
# seconds after the last keyboard activity.
pkill syndaemon
if [ "$?" = "1" ]
then
	syndaemon -i 2 -d > /dev/null
fi
# Disable the touchpad if a mouse is plugged in
lsusb | grep -iq 'mouse'
if [ "$?" = "0" ]
then
	pointerID=$( xinput list |
			grep 'Synaptics TouchPad' |
			sed 's/.*=//' |
			sed 's/[^0-9].*//' )
	xinput set-prop $pointerID "Device Enabled" 0
fi 

Depending on your pointer device, you might need to check for wheel or track instead of mouse, look at your list of USB devices to see what's appropriate.

On OpenBSD, use usbdevs instead of lsusb.

Entering Non-ASCII or Accented Characters

You may need to enter accented or other special characters not represented on your keyboard. You need to type Æsir or Sainte-Mère-Église but you don't have those keys. The Compose key solves the problem!

First, run the showkey command and poke around the special keys you seldom or never use. You're looking for the key producing keycode 127. That's the Compose key. It's likely to be something like the right-side Alt key. And yes, you can use xmodmap to place it wherever you want!

Now, run this command to see what is available:

$ dumpkeys | grep compose 

All the characters you see there will be possible, likely with others that don't appear in this output. For example, the British Pound sign £ is created with the sequence <Compose>L-.

For an exhaustive list, see the file /usr/share/X11/locale/en_US.UTF-8/Compose. Of course, change en_US.UTF-8 to your locale! Where it says Multi_key, think Compose. That list is long, so search it with grep:

$ grep -i yen usr/share/X11/locale/en_US.UTF-8/Compose 

Let's say that you want to learn about the Norse pantheon. You go to Wikipedia, click in the search box, and press this sequence of keys:

<Compose> A E s i r <Enter>

The sequence <Compose>AE will have been turned into the single character Æ, and the above sequence of steps will take you to the Wikipedia page for Æsir.

Maybe you need to enter the string into a document or use it at the command line:

$ cp travel-pictures/Sainte-Mère-Église/* /media/usb/ 

Maybe You Don't Need to Use the Compose Key...

Wikipedia is clever enough to redirect you to the correct page when you enter aesir with ae in place of the single grapheme æ, but this is handy to know about. There is a Wikipedia page for Æ which you can find by entering ae, but good luck finding the page for the Norse character Þ or the Scandinavian letter Å if you only know what they look like and not their names "thorn" and "A-ring".

In my second example above, filename completion would have done this for us. Careful use of wildcards could also solve the problem.

Using Unicode and Other Encoding

This page doesn't include the literal special characters shown above, I used Unicode. The header of the page specifies a UTF-8 character set, and ÆèÉ are not in that set. "£", "Æsir", and "Sainte-Mère-Église" exist in this page as:

&#x00a3;
&#x00c6;sir
Sainte-M&#x00e8;re-&#x00c9;glise

And, when I copy the string "https://en.wikipedia.org/wiki/Æsir" out of Firefox and paste it into my vim editor session, I get a different encoding for Æ as URIs should only use a limited character set:

https://en.wikipedia.org/wiki/%C3%86sir

TeX / LaTeX typesetting uses its own descriptions of these types of characters:

\pounds
{\AE}sir
Sainte-M\`{e}re-\'{E}glise 

See some other pages of mine about representing Turkish and Russian in Unicode and TeX / LaTeX.

Configuring the KDM Display Manager

If you can't get KDM to start, you may need to generate a new default KDM configuration:

# genkdmconf 

If you have KDM running well enough to start, you can log in as an unprivileged user and then use the menus to modify the KDM login screen. It will ask you for the root password when needed.

See my SSH configuration page to see how to make KDM start an SSH agent at login.

To the Linux / Unix Page