I confirmed all of the following on a ThinkPad P1 running Pop!_OS (a derivative
of Ubuntu 18.10) in GNOME.
Finding Key Codes
xev in a terminal and start typing. There's a lot of data, but what you're
looking for is usually the second 3rd line of a block after the word
KeyRelease event, serial 37, synthetic NO, window 0x3c00001,
root 0x1a5, subw 0x0, time 291165043, (404,446), root:(454,634),
state 0x0, **keycode 107** (keysym 0xff67, Menu), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
There are some keys that
xev won't print a key code for, such as Print Screen.
For these, you can grep through the file created in the next section.
Dumping Your Current Bindings
You can print the current mappings to standard out by running
You'll save some potential headaches by first backing up your
to a file:
xmodmap -pke ~/.Xmodmap.orig
This file also serves as an easy reference for where keys are if they don't show
cat ~/.Xmodmap | grep Print
keycode 107 = Print Sys_Req Print Sys_Req
Command To Quickly Change A Binding
You already know this, but just to reaffirm:
xmodmap -e "keycode [number] = [keys...]"
This will temporarily rebind a key for your session. Running
again will reflect these changes.
xmodmap uses space-delimited columns to denote the different modifiers/modes
keycode. From left to right they are:
- The key by itself
- Shift + the key
- Mode_switch + the key
- Mode_switch + shift + the key
xmodmap -e "44 = j J Down Next"
This sets the "J" key "j" by itself, "J" when pressed with Shift, Down Arrow
when pressed with Mode_switch, and Page Down when pressed with Mode_switch and
Mode_switch is a separate generic modifier, similar to Shift. I don't think
many keyboards come with a dedicated
Mode_switch (AltGr) key anymore, but you
can set one up with
# Set left Alt as Mode_switch
xmodmap -e "keycode 108 = Mode_switch"
Run scripts with GNOME Settings or
I'm not aware of a way to run arbitrary scripts with
xmodmap. There are,
however, a few easy ways.
From i3 config
The i3 docs have examples on
bindcode directives in your
bindcode 214 exec /home/you/some_script.sh
I don't have i3 set up yet, haven't tested this, but it's straight from the user
manual. I'm guessing the codes match what you find in
xmodmap & friends.
Check out Settings > Devices > Keyboard > Keyboard Shortcuts. Click plus and
add a script/key combo. Note that you must put the full path (from the root) to
the script and ensure it's executable.
In my testing, GNOME doesn't let you use some keys, such as Home and End.
xbindkeys can intercept any
key press and run a script instead.
Too see some config file examples, run
xbindkeys --defaults > $HOME/.xbindkeysrc and view the file.
Note that it won't open a terminal, just execute the file in a process.
Here's the actual commands to run for what you want. Be sure to confirm your own
key codes, these are just what I happen to have.
Step 1: Remap With
# print screen --> use as another super key, print screen with Mode_switch
# Note: On GNOME, it appears Super_R doesn't work the same as Super_L
xmodmap -e "keycode 107 = Super_L NoSymbol Print Sys_Req"
# left alt --> mode_switch key
xmodmap -e "keycode 64 = Mode_switch NoSymbol"
# escape key --> tilde and backtick
# Note: this can have unexpected consequences if you use `xcape` to map
# Control/Caps to send Escape when tapped. It will instead send `/~ when you
# press Caps Lock attempting to get Escape.
# A solution might be to switch the keys around and use a non-op key as a
# placeholder, like in the xcape README
xmodmap -e "keycode 9 = grave asciitilde grave asciitilde"
# original tild and back tick --> backspace
xmodmap -e "keycode 49 = BackSpace"
# backspace --> delete, and
# mode_switch + backspace --> home
xmodmap -e "keycode 22 = Delete NoSymbol Home"
# mode_switch + delete --> end
# Note: This won't work when combined with `xbindkeys`, since `xbindkeys`
# hijacks the entire Delete key from X.
xmodmap -e "keycode 119 = Delete NoSymbol End"
# mode_switch + h, j, k, l --> additional arrow keys
# Bonus: capital J/K are Page Down/Up, H/L are Home/End with Mode_switch + Shift
xmodmap -e "keycode 43 = h H Left Home"
xmodmap -e "keycode 44 = j J Down Next"
xmodmap -e "keycode 45 = k K Up Prior"
xmodmap -e "keycode 46 = l L Right End"
Step 2: Save Changes
# Write current config to a file
xmodmap -pke > ~/.Xmodmap
# Load the config into xmodmap
Adding the last command above to your
load it whenever you log in, assuming you have a standard set up. For me it was
kinda slow, you may want to just add all of the
xmodmap -e commands manually.
Step 3: Set Bindings For Custom Scripts With
xbindkeys is installed, and add this to your
# disable home, end, insert, delete keys and map them to run some script, and
Then reload with
Step 4: There Is No Step 4
Emacs Wiki Page on remapping
Emacs Wiki Page on xmodmap
Arch Wiki about Xmodmap
More about Mode_switch on StackExchange
A more comprehensive and effort intensive solution is to just write your own