40

I have a Macbook Air that runs Linux. I want to swap the alt and super keys in both sides of the keyboard with each other.

How do I do this with cli tools?

Update

Following Drav Sloan's answer I used the following:

keycode 64 = Alt_L
keycode 133 = Super_L
remove Mod1 = Alt_L
remove Mod4 = Super_L
add Mod1 = Super_L
add Mod4 = Alt_L

keycode 108 = Alt_R
keycode 134 = Super_R
remove Mod1 = Alt_R
remove Mod4 = Super_R
add Mod1 = Super_R
add Mod4 = Alt_R
  • 1
    Oddly, things worked for me (mac air) for when I took only the first 6 lines and not the bototm once into a file and ran xmobmap file on it. With the bottom lines I had errors. – Leo Ufimtsev Apr 11 '15 at 16:05

7 Answers7

43

If you only want to swap left alt and super key execute the command in your terminal:

setxkbmap -option altwin:swap_alt_win

To restore the default behavior just use:

setxkbmap -option

Note: This is temporary. If you want the effects permanently add it to your startup file.

coljamkop
  • 551
  • 4
  • 4
  • 8
    This should be the accepted solution, as it is clean and uses a built in function. You should have mentioned, that to **restore the default behaviour** you could just use `setxkbmap -option`. And if you only want to **swap left alt and super key**, then use this command: `setxkbmap -option altwin:swap_lalt_lwin`. – erik Jan 26 '18 at 13:20
  • 1
    I have Logitech keyboard and this worked to switch my windows key (Super_L) with the the left alt (Alt_L). Thanks! – Derek Jun 03 '18 at 01:49
  • It seems pretty intuitive and others have said that it works but for me it doesn't I am not sure why..!Anyone who can help.! – Md Faisal Nov 04 '20 at 05:20
  • @MdFaisal which operating system are you using? – coljamkop Nov 11 '20 at 13:15
  • I am using CentOS 8 – Md Faisal Nov 17 '20 at 10:31
  • Just another update that this method is working in ElementaryOS, and yes it is still not working in CentOS 8(although from gnome-tweaks I am able to swap them) – Md Faisal Nov 26 '20 at 12:31
  • I would think any OS using X Keyboard Extension would work. Unfortunately, I have little experience with CentOS and wouldn't be the best person to answer as to why it isn't working there even though gnome-tweaks does the job fine. – coljamkop Nov 30 '20 at 23:23
  • This is the best answer because it doesn't assume that Apple manufactured the keyboard. I'm not using Apple-anything, but an LMP keyboard *designed* for Apple, on a PC laptop running Linux. So there's no `/sys/modules/hid_apple` on my system. But there certainly is `setxkbmap`. Great answer, thanks! – Teekin Jul 20 '22 at 09:36
42

If you're wanting to do this on an Apple keyboard, try this out:

echo 1|sudo tee /sys/module/hid_apple/parameters/swap_opt_cmd

To get this to work for a lower version of Linux you can try this out: http://blog.chaselambda.com/2014/10/09/apple-keyboard-on-linux-3.8.html

theicfire
  • 621
  • 5
  • 10
23

One way to achieve that is via xmodmap. You can run xev to get key events. On running xev a box should appear and you can focus it and press the keys you want to swap. It should output details similar to for the Alt key:

KeyPress event, serial 28, synthetic NO, window 0x8800001,
  root 0x25, subw 0x0, time 2213877115, (126,91), root:(1639,475),
  state 0x0, keycode 14 (keysym 0xffe9, Alt_L), same_screen YES,
  XLookupString gives 0 bytes: 
  XmbLookupString gives 0 bytes: 
  XFilterEvent returns: False

I'm on a PC, and don't have a "Command Key", but have the equivalent "Windows Key", and xev gives:

KeyPress event, serial 28, synthetic NO, window 0x8000001,
  root 0x25, subw 0x0, time 2213687746, (111,74), root:(1624,98),
  state 0x0, keycode 93 (keysym 0xffeb, Super_L), same_screen YES,
  XLookupString gives 0 bytes: 
  XmbLookupString gives 0 bytes: 
  XFilterEvent returns: False

Because xmodmap has no idea of state, and can easily break key mappings, I suggest you do a:

xmodmap -pke > defaults

Then we create a xmodmap file:

keycode 14 = Alt_L
keycode 93 = Super_L
remove Mod1 = Alt_L
remove Mod4 = Super_L
add Mod1 = Super_L
add Mod4 = Alt_L

Note how I'm using the keycodes that xev returned. Also here I'm only replacing the left super and alt keys (and leaving the right ones to their old behavior). Then we can simply run xmodmap, to set these keys:

$ xmodmap -v modmap.file
! modmap:
! 1:  keycode 14 = Alt_L
        keycode 0xe = Alt_L
! 2:  keycode 93 = Super_L
        keycode 0x5d = Super_L
! 3:  remove Mod1 = Alt_L
! Keysym Alt_L (0xffe9) corresponds to keycode(s) 0xe
        remove mod1 =  0xe
! 4:  remove Mod4 = Super_L
! Keysym Super_L (0xffeb) corresponds to keycode(s) 0x5d
        remove mod4 =  0x5d
! 5:  add Mod1 = Super_L
        add mod1 = Super_L
! 6:  add Mod4 = Alt_L
        add mod4 = Alt_L
!
! executing work queue
!
        keycode 0xe = Alt_L
        keycode 0x5d = Super_L
        remove mod1 =  0xe
        remove mod4 =  0x5d
        add mod1 = Super_L
        add mod4 = Alt_L

You can run without the -v (verbose) switch for silent running, but I find it useful if you made mistakes in your modmap file. If things go messy then just reapply your defaults:

xmodmap defaults

Modmap is often ran at start up of X, so you can have these applied as defaults if you put your modmap commands in ~/.xmodmaprc.

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Drav Sloan
  • 14,145
  • 4
  • 45
  • 43
  • Is there a way of doing this with `setxkbmap`? I would like to use `setxkbmap -option compose:ralt` option together with this. –  Aug 15 '13 at 22:48
  • I used the swap_opt_cmd solution in another answer, but this one deserves an upvote because it is so thorough and clearly written. Bravo, sir. – John Franklin Oct 03 '15 at 21:23
  • Thanks. I got xmodmap mess up and appreciate if you could help https://askubuntu.com/questions/1026246/why-doesnt-my-substitution-of-the-super-key-for-the-alt-l-key-not-work-in-all-t – Tim Apr 19 '18 at 01:50
4
$ xmodmap -pke

Take note of which keycodes alt and super are bound to, then in your home folder open/make a new file .xmodmaprc. For example, my super/alt keys are bound as such

keycode  64 = Alt_L Meta_L Alt_L Meta_L
keycode 108 = Alt_R Meta_R Alt_R Meta_R
keycode 133 = Super_L NoSymbol Super_L
keycode 134 = Super_R NoSymbol Super_R

But to swap the keys, you would put the following in .xmodmaprc

keycode  64 = Super_L NoSymbol Super_L
keycode 108 = Super_R NoSymbol Super_R
keycode 133 = Alt_L Meta_L Alt_L Meta_L
keycode 134 = Alt_R Meta_R Alt_R Meta_R
cepkos
  • 59
  • 3
  • Overwriting the keycode / role associations... simple, and it works. Wonder if there is any drawback compared to the `remove ...` solution. – Déjà vu Oct 19 '17 at 08:53
  • Remember you can use `grep` to filter output so `xmodmap -pke | grep -i "super\|alt"` should make it easier to see what you need. – Benjamin R Oct 05 '19 at 21:08
1

In addition to coljamkop answer. If you need to swap other combination of service keys (Ctrl, Alt, etc.), you could use many other options for setxkbmap. Run the following command to see desired options along with their descriptions (replace "alt" and/or "win" for other keys):

$ grep -E "(alt|win):" /usr/share/X11/xkb/rules/base.lst

Then set chosen option by setxkbmap:

$ setxkbmap -option *chosen option*

This method is fully described at Archlinux Wiki.

WizKI
  • 11
  • 1
0

If you are one of the unfortunate people like me that could not get xmodmap to switch right Alt with right Ctrl, then maybe this will help.

If you press right Alt and e and you get é then this solution is for you (needs improvement).

Run this in the terminal (check your keycodes with xev):

xmodmap -e "keycode 108 = Alt_R Meta_R Alt_R Meta_R"

then put this code in your .Xmodmap:

remove Control = Control_R
remove Mod1 = Alt_R
keycode 105 = Alt_R
keycode 108 = Control_R
add Control = Control_R
add Mod1 = Alt_R

This code sets your Alt_Gr key to Alt_R, and then it swaps Alt_r with Ctrl_R.

If you want this to remain after you logout, put the following commands in any of your startup shell files, for example ~/.profile:

if [ -f $HOME/.Xmodmap ]; then
  xmodmap -e "keycode 108 = Alt_R Meta_R Alt_R Meta_R"
  /usr/bin/xmodmap $HOME/.Xmodmap
fi

sources: question1 question2

0

If you're on sway-wm you can add

input type:keyboard {
    xkb_options altwin:swap_alt_win
}

to you're sway config file. Or get your keyboard id with swaymsg -t get_inputs and replace input type:keyboard with input "12:34:your_id".

adabru
  • 240
  • 2
  • 5