9
votes

The question:

How can I remap (swap) modifier keys system-wide on Linux?

Explanation:

I want to install Debian Jessie on my PC to use it with Emacs. I have a MacBook with Emacs and use it primarily. Here is how keys are arranged on laptop:

fn ctrl alt cmd spacebar cmd alt

fn is unused in my Emacs workflow, other keys configured as listed below:

  • ctrl acts as Hyper
  • alt acts as Meta
  • cmd acts as Control

These configuration eases for me Emacs experience (big thumb hits Control cmd key) and I got used to this kind of key bindings.

by default alt is used as Meta, while ctrl is used as Control, the keys are swapped and big thumb lays on Meta

I want to configure my keys on Linux same way, here is what I have on my PC's keyboard:

ctrl win alt spacebar alt win menu ctrl

So, to correspond to my laptop keys, I want win keys to be mapped to Alt modifier, and alt keys to be mapped to Control modifier. In this case ctrl could be used as Super modifier, while menu could be kept untouched.

Is it possible to make such configuration system-wide on Linux (Debian)?


Finally, I have managed to achieve my goal with following configuration:

!file ~/.Xmodmap

clear control
clear mod1
clear mod4


keycode 37  = Super_L     
! left  Ctrl becomes Super
keycode 64  = Control_L
! left  Alt  becomes Control 
keycode 133 = Alt_L Meta_L
! left  Win  becomes Alt
keycode 108 = Control_R
! right Alt  becomes Control 
keycode 134 = Alt_R Meta_R
! right Win  becomes Alt
keycode 105 = Super_R
! right Ctrl becomes Super


add control = Control_L Control_R
add mod1 = Alt_L Meta_L
add mod4 = Super_L Super_R

Also, here is similar question with quite helpful and simple guides.

3

3 Answers

6
votes

Additionally to and possibly easier than using xmodmap might be to check in the keyboard layout options given by setxkbmap. These options implement common xmodmap changes, so they might well contain what you want.

For example, I like -option ctrl:nocaps which adds me another control where the caps lock was. Consider the file /usr/share/X11/xkb/rules/base.lst for a list of the standard options.

However, neither xmodmap nor setxkbmap include keyboard settings for the text-only tty terminals (non-X).

2
votes

xmodmap is the place to start, keeping in mind that X knows nothing about Hyper or Meta, so you have to investigate to see which numbered modifier (mod4, mod5, etc), emacs uses for these modifiers.

Here are a few useful links:

1
votes

Full Disclosure

I am the author of Kinto.

You may find Kinto to be useful. It's a project I recently created, after a few years of tackling this problem a few different ways and I just now feel like it's solid enough to share.

The Kinto installer simply uses python to do the initial install, after that it's just a systemd service, bash, xprop, setxkbmap and xkbcomp. As far as I am concerned it is the fastest and most native solution to this problem that you are going to find.

Also Xmodmap is defunct, it will not work going forward with Wayland.

https://github.com/rbreaves/kinto

https://medium.com/@benreaves/kinto-a-mac-inspired-keyboard-mapping-for-linux-58f731817c0

Here's a Gist as well, if you just want to see what is at the heart of it all, it will not alternate your keymap when needed though. The Gist also does not include custom xkb keymap files that setup macOS style cursors/word-wise manipulations that use Cmd and the arrow keys.

https://gist.github.com/rbreaves/f4cf8a991eaeea893999964f5e83eebb

gist content

# permanent apple keyboard keyswap
echo "options hid_apple swap_opt_cmd=1" | sudo tee -a /etc/modprobe.d/hid_apple.conf
update-initramfs -u -k all

# Temporary & instant apple keyboard keyswap
echo '1' | sudo tee -a /sys/module/hid_apple/parameters/swap_opt_cmd

# Windows and Mac keyboards - GUI (Physical Alt is Ctrl, Physical Super is Alt, Physical Ctrl is Super)
setxkbmap -option;setxkbmap -option altwin:ctrl_alt_win

# Windows and Mac keyboards - Terminal Apps (Physical Alt is Super, Physical Super is Alt, Physical Ctrl is Ctrl)
setxkbmap -option;setxkbmap -option altwin:swap_alt_win

#
# If you want a systemd service and bash script to help toggle between
# GUI and Terminal applications then look at project Kinto.
# https://github.com/rbreaves/kinto
#
# Note: The above may not work for Chromebooks running Linux, please look
# at project Kinto for that.
#
# If anyone would like to contribute to the project then please do!
#