Keyboard Mapping

Table of Contents

I am using the RK61 keyboard which is a great little keyboard, but the mapping is not 100% right for me. Luckily we can change the keyboard map in X11.

1 vim arrow keys

The RK61 has an arrow cluster on the FN level in the lower righton the FN level. However, I like the vim keys hjkl to work as my arrow keys. I change the bahaviour of the CAPS LOCK key so it

  • acts as a modifier that brings hjkl to the third level
  • acts as ESC when pressed and released (using xcape)

2 Userspace Modification

This option can be used if you cannot or don’t want to modify the system wide xkb-data files.

2.1 Double meaning of CAPS LOCK

This is an easy one. The tool xcape does that easily. So a simple:

xcape -e 'Caps_Lock=Escape'

added to .profile does the trick.

2.2 hjkl mapping to direction keys on 3rd level

This one is a bit trickier and involves messing with the xkbmaps.

2.2.1 Create a keymap file from the default config:

xkbcomp $DISPLAY keymap.xkb

2.2.2 Edit the keymap.xkb file

This is taken from the Arch Wiki.

The types section (which defines layer mapping) must contain an entry such that:

When no modifiers are pressed, the first level of keysyms is used (lowercase letters). When Shift only is pressed, the second level of keysyms is used (capital letters). When Lock only is pressed, the third level of keysyms is used (the arrow keys) When Shift and Lock are pressed, the third level of keysyms is also used (shift+arrow keys).

Add this to the bottom of your types section:

 xkb_types "complete" {
   ...
   type "CUST_CAPSLOCK" {
       modifiers= Shift+Lock;
       map[Shift] = Level2;            //maps shift and no Lock. Shift+Alt goes here, too, because Alt isn't in modifiers.
       map[Lock] = Level3;
       map[Shift+Lock] = Level3;       //maps shift and Lock. Shift+Lock+Alt goes here, too.
       level_name[Level1]= "Base";
       level_name[Level2]= "Shift";
       level_name[Level3]= "Lock";
   };
 };

Now change caps from a lock (toggle) to a set (press) by modifying the already existing definition in compatability from LockMods to SetMods:

(Note that this means you can’t use capslock like normal)

 xkb_compatibility "complete" {
   ...
   interpret Caps_Lock+AnyOfOrNone(all) {
       action= SetMods(modifiers=Lock);
   };
   ...
 };

And, finally, change the key symbols as follows:

    key <AC06> {
        type= "CUST_CAPSLOCK",
        symbols[Group1]= [               h,               H,        Left ],
        actions[Group1]= [      NoAction(),     NoAction(),    RedirectKey(Keycode=<LEFT>, clearmods=Lock) ]
    };
    key <AC07> {
        type= "CUST_CAPSLOCK",
        symbols[Group1]= [               j,               J,       Down ],
        actions[Group1]= [      NoAction(),     NoAction(),    RedirectKey(Keycode=<DOWN>, clearmods=Lock) ]
    };
    key <AC08> {
        type= "CUST_CAPSLOCK",
        symbols[Group1]= [               k,               K,       Up ],
        actions[Group1]= [      NoAction(),     NoAction(),    RedirectKey(Keycode=<UP>, clearmods=Lock) ]
    };
    key <AC09> {
        type= "CUST_CAPSLOCK",
        symbols[Group1]= [               l,               L,       Right ],
        actions[Group1]= [      NoAction(),     NoAction(),    RedirectKey(Keycode=<RGHT>, clearmods=Lock) ]
    };

2.2.3 Swap left Win/Alt

On my RK61 the “Mac” mode (Fn-S) has the Function keys active with Fn + [1 - =] for F1 - F12. The “Win” mode (Fn-A) seems to have the Apple media keys there.

But the left Alt and Win keys are swapped, so I need to swap these in the keymap.

Find the lines for these two and change them as:

    <LWIN> = 64;
    <LALT> = 133;

2.2.4 Load the new keymapping file

Copy the keymap file to .Xkeymap and load it:

test -f ~/.Xkeymap && xkbcomp ~/.Xkeymap $DISPLAY

This needs to be followed by the xcape command above, since it will reset that.

Note: There will be a way to do the double mapping in xkbcomp as well. I’ll need to play with that a bit longer.

But with this I can am happy so far. I can use direction keys that I can use without leaving the home row. I even found that I sometimes have the left pinky on Caps Lock even when I’m in Normal Mode.

3 Modify the xkb files in /usr/share/X11/xkb

The above solution works well with window managers. For DEs we need to provide a selectable config. For this we need to modify the files in the system installation of xkb.

  • Insert a block in /usr/share/X11/xkb/symbols/gb:
    partial alphanumeric_keys
    xkb_symbols "vim" {


        // Describes the differences between a very simple en_US
        // keyboard and a very simple U.K. keyboard layout defined by
        // the SVR4 European Language Supplement and sometimes also
        // known as the IBM 166 layout.

        include "latin"

        name[Group1]="English (UK) with VIM cluster";

        key <AE02>	{ [         2,   quotedbl,  twosuperior,    oneeighth ]	};
        key <AE03>	{ [         3,   sterling, threesuperior,    sterling ]	};
        key <AE04>	{ [         4,     dollar,     EuroSign,   onequarter ]	};

        key <AC11>	{ [apostrophe,         at, dead_circumflex, dead_caron]	};
        key <TLDE>	{ [     grave,    notsign,          bar,          bar ]	};

        key <BKSL>	{ [numbersign, asciitilde,   dead_grave,   dead_breve ]	};
        key <LSGT>	{ [ backslash,        bar,          bar,    brokenbar ]	};


        // VIM style direction keys on the third level
        // fourth layer will allow text selection with Shift + Level3 (CapsLock)
        key <AC06> { [          h,               H,       Left,     Left ] };
        key <AC07> { [          j,               J,       Down,     Down ] };
        key <AC08> { [          k,               K,         Up,       Up ] };
        key <AC09> { [          l,               L,      Right,    Right ] };

        // PgUp/PgDown on less/greater
        key <AB08> {        [     comma,       less,     Prior        ] };
        key <AB09> {        [    period,    greater,      Next        ] };

        // PrtScr Home End Insert  on y u i o
        key <AD06> {        [     y,    Y,      Print,    NoSymbol    ] };
        key <AD07> {        [     u,    U,       Home,    NoSymbol    ] };
        key <AD08> {        [     i,    I,        End,    NoSymbol    ] };
        key <AD09> {        [     o,    O,     Insert,    NoSymbol    ] };

        // Right Alt and Caps Lock select third layer
        // very conveniently hold down Caps Lock to use hjkl
        include "level3(caps_switch)"
        include "level3(ralt_switch_multikey)"
    };
  • Add to /usr/share/X11xkb/rules/evdev.xml:

        <variant>
            <configItem>
            <name>vim</name>
            <description>English (UK, extended, with VIM nav keys)</description>
            </configItem>
        </variant>
    
  • Add to usr/share/X11/rules/evdev.lst:

        vim		  gb: English (UK, extended, with VIM nav keys)
    

3.1 Double meaning of CAPS LOCK

With the above setting include "level3(caps_switch)" we have defined Caps Lock as a level 3 modifier, so the xcape call will use ISO_Level3_Shift instead of Caps_Lock!

xcape -e 'ISO_Level3_Shift=Escape'

added to .profile does the trick.