Change X keyboard and mouse mappings safely with xmodmap
You will inspect the current X mappings, try a reversible pointer change, and save a keyboard mapping you can restore later. The examples use xmodmap 1.0.11 from Debian package x11-xserver-utils version 7.7+10build2.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need an X session with a working DISPLAY, a shell, and permission to connect to that display. These commands change the mappings for the current X display only. They do not change the Linux console, Wayland compositor or a desktop environment's persistent keyboard settings.
Safety boundary
Changing a mapping can make keys or buttons behave unexpectedly. Save the current keymap before experimenting, and keep a second terminal available for recovery. Nothing here needs sudo.
1. Check the installed command and display
First confirm which executable and package version you are using. This is read-only:
$ command -v xmodmap
/usr/bin/xmodmap
$ xmodmap -version
xmodmap 1.0.11
$ dpkg-query -W -f='${Package} ${Version}\n' x11-xserver-utils
x11-xserver-utils 7.7+10build2
Check the display before attempting a mapping operation:
$ printf 'DISPLAY=%s\n' "${DISPLAY:-unset}"
DISPLAY=:0
Your value will differ. If it says unset, xmodmap normally cannot connect to an X server. If it names a display but access fails, use the shell belonging to that graphical session and check the session's X authorisation. Do not guess a display number.
Checkpoint
Continue only when DISPLAY refers to the X session whose mappings you intend to change.
2. Save a rollback copy
Use -pke to print the current keymap as xmodmap expressions, then redirect that output to a file in your home directory:
$ xmodmap -pke > "$HOME/xmodmap-before"
$ test -s "$HOME/xmodmap-before" && printf '%s\n' 'saved keymap'
saved keymap
This file is a snapshot of the keyboard map, not a universal configuration for another keyboard. Keep it private if the machine's layout is sensitive. The command does not save the pointer map, so record that separately if you plan to change buttons:
$ xmodmap -pp
There are 3 pointer buttons defined.
Physical Button
Button 1
Button 2
Button 3
The exact output is host-specific. For a complete pointer rollback, copy the numbered mapping from this output and use a pointer = ... expression later.
3. Inspect without changing anything
The default mode prints the modifier map. Use the other print modes when you need a different view:
$ xmodmap -pm
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock (0x42)
control Control_L (0x25), Control_R (0x69)
$ xmodmap -pk | sed -n '1,12p'
There are 4 KeySyms per KeyCode; KeyCodes start at 8
8 0x0000 (NoSymbol) 0x0000 (NoSymbol) 0x0000 (NoSymbol) 0x0000 (NoSymbol)
9 0xff1b (Escape) 0x0000 (NoSymbol) 0x0000 (NoSymbol) 0x0000 (NoSymbol)
10 0x0031 (1) 0x0021 (exclam) 0x0000 (NoSymbol) 0x0000 (NoSymbol)
Output depends on the server and keyboard. -pm shows modifier membership, -pk shows keycodes and keysyms, and -pke prints the latter in a form that can be fed back to xmodmap. A key being shown in the keymap does not by itself mean it belongs to a modifier.
4. Test a pointer mapping with dry run
Use -n to show what an expression would do without changing the mappings. For a three-button mouse, this tests a left-handed order:
$ xmodmap -n -e 'pointer = 3 2 1'
pointer = 3 2 1
The pointer list starts with physical button 1. A zero disables events from that button. The dry run is a parser and operation preview; it does not prove that the live pointer will feel right on every device.
Checkpoint
If the preview is acceptable, apply it in a separate command:
$ xmodmap -e 'pointer = 3 2 1'
$ xmodmap -pp
There are 3 pointer buttons defined.
Test the buttons before changing anything else. To undo this exact example, apply xmodmap -e 'pointer = 1 2 3', or use the actual order recorded from your earlier -pp output. That inverse is not automatically correct for a mouse with a different number of buttons.
5. Change a key without leaving a modifier behind
A keysym assignment changes the keymap, but a modifier map is separate. To swap Caps Lock and left Control, remove both old modifier memberships, change the keysyms, then add the new memberships:
$ xmodmap -n -e 'remove Lock = Caps_Lock' \
-e 'remove Control = Control_L' \
-e 'keysym Control_L = Caps_Lock' \
-e 'keysym Caps_Lock = Control_L' \
-e 'add Lock = Caps_Lock' \
-e 'add Control = Control_L'
remove Lock = Caps_Lock
remove Control = Control_L
keysym Control_L = Caps_Lock
keysym Caps_Lock = Control_L
add Lock = Caps_Lock
add Control = Control_L
Read the preview carefully. The command accepts multiple -e expressions and parses the input before executing it, which is why a swap can refer to the old names naturally. The installed manual also warns that each keycode change generates a MappingNotify event, so batching related expressions avoids unnecessary client churn.
When the preview is right, remove -n and run the same command. Then check both views:
$ xmodmap -pm
$ xmodmap -pk | grep -E 'Caps_Lock|Control_L'
The grep result is a quick inspection, not a fixed expected line: keycodes and unrelated columns vary by keyboard.
6. Restore the saved keyboard map
If the result is confusing, restore the snapshot you made in step 2:
$ xmodmap "$HOME/xmodmap-before"
$ xmodmap -pke > /tmp/xmodmap-after
$ cmp -s "$HOME/xmodmap-before" /tmp/xmodmap-after \
&& printf '%s\n' 'keyboard map restored'
keyboard map restored
The comparison can differ in harmless formatting on some servers, so also test the keys physically. If xmodmap reports that it cannot open the display, do not edit the saved file to compensate: reconnect to the correct X session first. Remove the temporary comparison file when you have finished with it.
For a persistent login setup, put only tested expressions in the session mechanism provided by your desktop environment. Do not blindly run a full -pke snapshot at every login, because that snapshot describes one keyboard and may overwrite changes made by the desktop or another input tool.
Done means
xmodmap -versionidentified the installed 1.0.11 command.- You confirmed the target X display and saved a keyboard rollback.
- You inspected the relevant keymap or pointer map before editing it.
- You previewed expressions with
-nbefore applying them. - You verified the live mapping and know how to restore the saved keyboard map.