** One-handed keyboarding in linux using loadkeys and xmodmap

I have been interested in one-handed keyboarding for quite a while. Unfortunately, most hardware solutions are fairly expensive, see Frogpad, BAT keyboard, etc.

Recently I happened across an interesting one-handed keymap by Karl Dahlke, http://www.eklhad.net/linux/app/onehand.html which prompted me to buy an external numberpad (numpad.jpg) for my laptop and start on a one-handed keyboard mapping of my own. I originally wanted to create a binding which, like the reflection module mentioned on Dahlke's site, would be fairly invisible to a user expecting a normal keyboard. Using only the number pad, I had an idea that the entire keyboard could be reproduced by using some keys as modifiers, thus multiplying the number of typeable characters. I didn't exactly get it to do all that I wanted, but I have something that works a little, and that's a start.

I had no experience with either the loadkeys or xmodmap file structure before starting this project. I found xmodmap to be severely limiting, and as thorough as keymap files can be for loadkeys, I still ran into some problems with it as well.

My intention was to use the 1-9 keys on the number pad as letters, with the thumb operating Enter, Del, and Ins as modifiers allowing for the full alphabet, plus as much punctuation I could fit. The mappings that I have used are shown below for the console and X, but first, the regular layout as a reference:

      Arrow Layout      Num Lock On

       NL /  *  -        NL /  *  -
       Hm Up PU +        7  8  9  +
       Lf    Rt          4  5  6
       Ed Dn PD En       1  2  3  En
       In    De          0     .

** One handed keymap for the console

       no modifier      Enter modifier   Del/period modifier  Ins/zero modifier

       NL Sh .  Bk        NL Ct '  De        NL Al :  Es        NL Cp =  In
       o  e  r  Sp        c  f  d  En        k  j  v  Tb        &  (  )  _
       a  s  t            y  u  l            z  g  b            $  %  ^
       h  i  n  M1        q  m  p  M1        x  w  ?  M1        !  @  /  M1
       M3    M2           M3    M2           M3    M2           M3    M2

Download this keymap: keypad.kmap Load using: loadkeys keypad.kmap It only defines keycodes in the numberpad range, so your qwerty/dvorak/whatever keyboard should be unaffected. Use loadkeys -d to return to your default keys.

The labels M1, M2 and M3 in this diagram are actually defined as Left Shift, Right Shift and Left Ctrl, respectively. These do not actually act as shift or ctrl keys, but are used to switch 'levels' on the numberpad, allowing for all twenty-six letters, plus punctuation.

In addition to the use of all the letters, I wanted it to be possible to apply actual Shift, Ctrl and Alt modifiers to any of the keys. I attempted to implement this by making the Slash key, next to Num Lock, into Sticky Shift, Sticky Ctrl and Sticky Alt. A sticky key influences the next keypress, so the key sequence SCtrl, c would pass Ctrl+c to the system. This does not work out for my layout, since it seems that any additional modifier applied between the sticky modifier and the first non-modifier keystoke neutralizes the sticky modifier, so Sctrl, Shift+c would only pass 'C' rather than Ctrl+Shift+c.

What this means is that you can only make capital letters with the non-modified characters, that is, OER AST HIN. This keymap file fails to produce capital cfd, zgb, and so on. For the same reason, it seems, trying to define StickyAlt as Delete+/ and StickyCtrl to Enter+/ have no affect at all. I feel that I really ought to just give up on the StickyModifiers and use that key for something else, but I'm hoping someone will give me ideas on how to set it up the way I want it so that it works. An alternate usage would be to leave it as a StickyModifier, but change it so that the rest of the punctuation (which I have all laid out as the impossible StickyShift, InsMod+(1-9) key combinations) is available on top.

** Some preliminary notes on xmodmap

As disappointing as the sticky problems are, the situation in X is much worse. One strength of loadkeys is that it allows up to 255 (!) combinations to be individually defined for each key. That is, if you wanted it to, Alt+m could produce an exclamation mark while Ctrl+m makes a right square bracket, Alt+Ctrl+m makes a caret, Meta+Ctrl+m produces a capital G, and so on with any modifier combination you want to set.

With xmodmap, however, Ctrl+m will always produce Ctrl+m. (Note that you could swap Ctrl with, say, w, so that w+c would send Ctrl+c, or swap Ctrl and Alt, so that Ctrl+c sends Alt+c, but that's not what I'm talking about. The point is that it's apparently impossible to configure most modifier combination to send anything other than that modifier combination.) The only xmodmap equivilant is the Mode_Switch modifier, which allows for an alternate character to be produced with a key combination of Mode_Switch+key.

Here are a few sample lines from a usual xmodmap file for illustration:

    keycode 13 = 4  dollar  cent    currency
    keycode 26 = e  E       egrave  Egrave

I should say that I still don't know all that much about xmodmap. I couldn't seem to get much help out of the documentation, which is partly why I've decided to write so much about it here.

The first entry gives the character that will be produced when the key is pressed without modification, while the next two columns are the non-shifted and shifted characters created in conjunction with the Mode_Switch modifier.

In this case, I have key 13 (my 4 key) set to make a 4 and my key 26 (my e key) set to make an e. The second column is the character that is sent when the the key is pressed in conjunction with Shift, so Shift+4 is $, as would be expected on a standard American keyboard, and Shift+e is E.

I set Mode_Switch+4 to produce the American cent symbol, Shift+Mode_Switch+4 to produce the generic currency symbol. As the Mode_Switch seems to be most often used to provide some internationalization, Mode_Switch+e accordingly produces an e with a grave for this example.

To incorporate this, I defined KeyPadEnter as a Mode_Switch modifier and Del/period as another shift key. Also, X seems to interperet Shift+Space, as well as Shift combinations involving other non-letter keys, such as Shift+BackSpace or Shift+Period, as only the key itself (i.e. Shift+Space is just Space), making it impossible to recode them as much as the letters. Due to this limitation, there is a slightly different layout than the console mapping, and also a slightly less intuitive order to the Xmodmap file.

** One handed Xmodmap for X

       no modifier      Enter modifier   Del/period modifier   both modifiers

       NL /  .  Bk        NL ?  ,  Es        NL /  .  Bk        NL ?  ,  Es
       o  e  r  Sp        c  f  d  En        k  j  v  Sp        7  8  9  En
       a  s  t            y  u  l            z  g  b            4  5  6
       h  i  n  M1        q  m  p  M1        x  w  3  M1        1  2     M1
       '     M2           0     M2           '     M2           0     M2   

Download this Xmodmap: Xmodmap.keypad Load using: xmodmap Xmodmap.keypad It only defines keycodes in the numberpad range, so your qwerty/dvorak/whatever keyboard should be unaffected. I guess I don't know offhand how to restore your default keyboard layout. You might want to figure that out if you expect to want your numbers back.

Note that the slash next to Num Lock is a punctuation character rather than the StickyModifiers that were in the console map. The sticky modifiers don't work in the X map either, and I have less hope that they ever might.

For the X layout, I set up numbers rather than punctuation, because I tend to use them more often. I ought to do it for the console map, too, but I don't use it as much, and also I have some hope for a working Num Lock in the console (see next paragraph). Note that 3 is not defined where you might expect it. This is because my keypad won't recognize that I'm holding down all three of those particular keys, so no character can be made with that specific combination.

** Notes on the layout

In both the console and X, the Num Lock key seems to have no possible effect on keys other than KeyPad keys (that is, keys defined as KeyPadEnter, KeyPadHome, etc). I had planned to use Num Lock to toggle between the alphabet and the standard number layout, using a modifier in the number layout to use the arrows. I suspect that this might be possible with loadkeys, but I very much doubt that it would work with xmodmap. I really haven't tried it in either.

The logic behind this letter arrangement is partly reasonable and partly arbitrary. I found a order of letter commonality on the internet somewhere, divided it into three sections and assigned the most common letters to the non-modified keys, the second-most-common group to the Enter-Modified keys, and the remainder to the Del-Modifier. I did swap q and w between the second and third group so that q could be on the same level as u.

Originally, I arranged it so that the non-modified keys spelled out ONE HAT SIR, and I was very pleased with that. After some time spent typing, though, it was obvious that a layout slightly more similar to my conventional qwerty would be easier to use. In particular, I kept hitting 4 expecting it to be an a, and 7 expecting an o, so I swapped some keys in ways that seemed helpful.

** End

So that is all I know about keymaps. If you have ideas or comments, I have an email address as evan at nixsyspaus dot org. There is quite a lot that I don't know about these keyboard mappings still, and I would appreciate any kind of suggestions on improving them. That said, however, I don't think that there is much point pursuing this numberpad keyboard thing with xmodmap or loadkeys. They just don't seem to be robust enough to handle it.

Also note that this page and its contents have been placed in the public domain by Evan Hall, August 2004. Enjoy.