You can kill the background for speed, if you wish.[x]

Friday, October 23, 2009

xmodmap: fixing the mistakes of others

For the past few weeks, I've been using my girlfriend's old Toshiba Satellite while wrestling with Dell to get them to fix my Vostro (it's currently somewhere in Texas, I think). Which has been great - I just put my hard drive into her computer (fortunately they were both SATA) and off we go (well, Windows isn't too happy about it, but that's not really of consequence). However, one quirk has bugged me: it suffers from the random placement of "unimportant" keys that many laptop keyboards do. Unfortunately, I, being a programmer and power user, find such keys rather important. Here's the problem, in a picture:

As you can see, whoever designed the keyboard was so overly concerned with the gigantic media button panel that they had to displace the tilde/grave key. Granted, this is one of the lesser used keys on the keyboard, but I still use it for one of my favorite Vim shortcuts, `., which is a magic marker that hops to the last line you edited. But it gets worse. They decided to put it down next to the space key, and moved the Windows key out of the way to make room for it. This also wouldn't be a huge deal - no one uses the Windows key, right? Except that I also run Compiz and Gnome-Do, and have the Windows key mapped to my Gnome-Do summon, as well as most of my multiple-desktop management. Win+Arrows moves between desktops, Win+Tab switches between all desktops, Ctrl+Win+Arrows moves the active window between desktops, Alt+Win moves a window by grabbing angwhere. Obviously all of these become very difficult when the windows key is six miles northeast of anything else.

The solution to this problem, of course, is to remap my keys where I want them. And since this is Linux, if I try hard enough, I can probably do whatever I want, oftentimes without downloading anything. This is the case today. Optimally I would like to use the Fn key as the Win key, but it's a really weird key, and evidently not touchable by xmodmap. So I settled for this: make the tilde key (next to the spacebar) my new Win key. I could just switch the two, but that puts my grave six miles away from everything as well. Instead, I decided to replace my Caps Lock with the grave, because like most programmers, I never, ever, ever use my Caps Lock. This makes it decently closeby, and pretty close to where it was. And for those times when Caps Lock goes haywire, I might as well move the Caps Lock up to the now-unused Windows Key. So, to summarize:

After some trial and error with xmodmap, I came to the following conclusions:

  • add/remove is to add/remove modifiers from key assignments (Caps, Numlock, Windows key, etc)
  • keycode ## = functionone functiontwo is the best way to simply map one key to the other
  • If you remap keys, but don't want the modifiers to come with them, you have to remove the modifiers, then add them back
  • If you want shiftable keys like the grave/tilde key to work properly with shift, you have to assign both functions (e.g. "grave" and "tilde") to the same keycode
  • xev, xmodmap -pm, and xmodmap -pke are relentlessley helpful in finding out what the keycodes are and what the keywords for the various modifiers and key functions are.
With these newfound conclusions, I went to work. Using xev, I found out that my winkey is keycode 133, grave/tilde is 49, and Caps Lock is 66. Additionally, xmodmap -pm told me that the Win key modifier is mod4 and the Caps modifier is lock. Finally, xmodmap -pke (in combination with the previous command) fleshed out the function names for the keys: Win is Super_L, Caps is Caps_Lock, and grave/tilde is grave asciitilde. From there it was just a hop, a skip, and a jump to come up with this xmodmap config file:
remove lock = Caps_Lock
remove mod4 = Super_L

keycode 49 = Super_L
keycode 133 = Caps_Lock
keycode 66 = grave asciitilde

add lock = Caps_Lock
add mod4 = Super_L
Which simply removes the two modifiers from their mappings so we can move stuff around, reassigns the keycodes to the functions I want them to perform (notice the combination grave asciitilde to make Shift function correctly), and then reassign the modifiers now that the functions are where I want them to be.

The sites I found regarding xmodmap were moderately helpful, but none of them quite spelled out what was happening, so I figured I would. This method should be pretty flexible, and plenty sufficient for any of your key-remapping needs. If you're playing around with it, xmodmap -e "[command]" will allow you to run commands (e.g. any one of the lines above) on a trial basis, just for this session. It was invaluable in getting this stuff working correctly. If you're having trouble, give a shout out in the comments, and I'll see what I can figure out.

No comments: