5

I am using manjaro i3 and am looking into revamping some of the key mappings I have made. Currently I am using xcape, xmodmap, and setxkbmap commands to remap the following keys:

  1. caps to contol when held, escape when pressed
  2. swap semi colon and colon

I have done this with this setup script:

setxkbmap -option 'caps:ctrl_modifier'
xcape -e 'Caps_Lock=Escape'
xmodmap -e "keycode 47 = colon semicolon"

I wanted to ask for some help or advice for the additional changes I am looking to make since I have already broken my key mappings and had to reinstall my os to get back to square one when playing around with the print screen remapping listed below. The changes I am looking to make are the following:

  1. print screen --> disable or use as another super key
  2. left alt --> mode_switch key
  3. escape key --> tilde and backtick
  4. original tild and back tick --> backspace
  5. backspace --> delete
  6. disable home, end, insert, delete keys and map them to run some script
  7. mode_switch + h, j, k, l --> additional arrow keys
  8. mode_switch + backspace --> home
  9. mode_switch + delete --> end

What tools should I be using to acccomplish these remappings? Also, if anyone has some similar examples they have used in the past that would be really helpful too! Thanks in advance for any help.

bwrabbit
  • 153

1 Answers1

8

I confirmed all of the following on a ThinkPad P1 running Pop!_OS (a derivative of Ubuntu 18.10) in GNOME.

Finding Key Codes

Run 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 keycode:

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.

Tools Needed

xmodmap

Dumping Your Current Bindings

You can print the current mappings to standard out by running xmodmap -pke. You'll save some potential headaches by first backing up your xmodmap layout to a file:

xmodmap -pke ~/.Xmodmap.orig

This file also serves as an easy reference for where keys are if they don't show up in xev.

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 xmodmap -pke again will reflect these changes.

Syntax

xmodmap uses space-delimited columns to denote the different modifiers/modes for a keycode. From left to right they are:

  • The key by itself
  • Shift + the key
  • Mode_switch + the key
  • Mode_switch + shift + the key

For example:

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 Shift.

Mode_switch

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 xmodmap.

# Set left Alt as Mode_switch
xmodmap -e "keycode 108 = Mode_switch"

Run scripts with GNOME Settings or xbindkeys

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 using the bindsym/bindcode directives in your ~/.config/i3/config file.

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.

GNOME

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.

Screen capture of GNOME settings pane for Keyboard Shortcuts

In my testing, GNOME doesn't let you use some keys, such as Home and End.

xbindkeys

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.

Your Examples

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 xmodmap

# 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
# https://github.com/alols/xcape/blob/master/README.md#examples
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
xmodmap ~/.Xmodmap

Adding the last command above to your ~/.profile or ~/.bash_profile will 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

Make sure xbindkeys is installed, and add this to your ~/.xbindkeysrc file:

# disable home, end, insert, delete keys and map them to run some script, and
"some-script-in-PATH"
  Home
"some-script-in-PATH"
  End
"some-script-in-PATH"
  Insert
"some-script-in-PATH"
  Delete

Then reload with xbindkeys -p.

Step 4: There Is No Step 4

Further Reading

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 keyboard layouts.

shender
  • 196