Mapping Super+hjkl to arrow keys under X

23

21

I'm trying to map:

Super+h -> Left
Super+j -> Down
Super+k -> Up
Super+l -> Right

globally under X. The idea is I don't want to leave my home row that often to use the arrow keys, so I'll use the Super modifier + hjkl to emulate the arrow keys under X. Is there any way to do this?

One thing I've tried is xbindkeys + xte using this configuration:

"xte 'keydown Up' 'keyup Up'"
  Mod4+k

"xte 'keydown Down' 'keyup Down'"
  Mod4+j

"xte 'keydown Left' 'keyup Left'"
  Mod4+h

"xte 'keydown Right' 'keyup Right'"
  Mod4+l

but there seems to a large delay between me pressing the key and noticing any result, and most of the time nothing happens at all.

Is there a more elegant way of doing this that actually works with no delay?

William Casarin

Posted 2010-01-15T16:38:41.117

Reputation: 720

2

Have found this to be great for doing this sort of thing: http://code.google.com/p/autokey/

– Tom Power – 2011-12-02T12:16:13.093

What is the OS? I also think you might be better off using Control-Super or some such combo. – harrymc – 2012-02-04T08:39:04.007

Answers

15

Capslock + HJKL to arrow keys

  1. Create ~/.Xmodmap and put this inside:

    clear Lock 
    keycode 66 = ISO_Level3_Shift
    
  2. Add Left, Down, Up, Right as a third item to the h,j,k,l key entries in /usr/share/X11/xkb/symbols/us (the first section):

    key { [ h, H, Left, Left ] }; 
    key { [ j, J, Down, Down ] };
    key { [ k, K, Up, Up ] }; 
    key { [ l, L, Right, Right ] };
    
  3. run xmodmap ~/.Xmodmap

Alternative: Capslock as Control and Control_L + HJKL to arrow keys

This is my current setup. I unmapped Control_L as a control key and use it as a special modifier (ISO_Level3_Shift), which corresponds to the third entry in the /usr/share/X11/xkb/symbols/us file for the hjkl mappings.

  1. I modified the first stanza of /usr/share/X11/xkb/symbols/us like before:

    key { [ h, H, Left, Left ] }; 
    key { [ j, J, Down, Down ] };
    key { [ k, K, Up, Up ] }; 
    key { [ l, L, Right, Right ] };
    
  2. Then I put this in my ~/.Xmodmap file:

    clear Control
    keycode 66 = Control_L
    add Control = Control_L
    add Control = Control_R
    keycode 37 = ISO_Level3_Shift
    

keycode 66 is capslock and keycode 37 is left control

  1. run xmodmap ~/.Xmodmap

With this setup I can use arrows keys with Control_L + hjkl as well as skip over words with Control_L + caps + hl. Easy!

William Casarin

Posted 2010-01-15T16:38:41.117

Reputation: 720

You may need to clear the cached xkb files in /var/lib/xkb/*.xkm for the changes to /usr/share/X11/xkb/symbols/us to take effect. – solo – 2015-04-02T02:24:54.233

1This works on Ubuntu 14.04. I had to make xmodmap /home/alex/.Xmodmap a startup application, and remove all *.xkm files form /var/lib/xkb. Warning: I trashed one Ubuntu VM doing this last step and then my keyboard wouldn't work at all any more, so be careful and have a backup ready :-) Shift+Control+Caps+hjkl to select text works well in Firefox and Thunderbird, but in some applications it does not (Chrome for example) – Alexander Rechsteiner – 2015-10-22T17:46:17.230

I used CapsLock as AltGr and added the del, backspace, home, end, pgUp and Down key too. xmodmap is not working properly any more (depricated) use an extra key binding in the xkb file for this too. see http://askubuntu.com/a/898462/34298

– rubo77 – 2017-03-30T21:50:49.030

@Mood it works everywhere except chrome/chromium. We should coordinate our efforts and submit a reasonable bug report. See https://superuser.com/a/1000320/521612

– Aleks-Daniel Jakimenko – 2017-09-23T22:59:42.690

1This works on Arch Linux too, but not immediately after the xmodmap command. After reboot, works almost perfectly. Just cannot do CTRL+SHIFT+arrow with CTRL+SHIFT+CAPS+hjkl, usually for seleting words. Any idea how to do this? – koss – 2012-05-24T00:56:33.610

Hmm you're right, best I could do is add Left, Down, Up, Right again into another column. This doesn't make highlighting work but it will skip words like normal. I'll have to look into this more. – William Casarin – 2012-05-25T17:17:05.830

This works well enough for me. The only problem I have, it does not work in Chrome and that is a nuisance. – Mood – 2012-08-03T19:42:46.270

8

The above mentioned changes in /usr/share/X11/xkb/symbols/us do NOT work for me:
Error loading new keyboard description

But after looking through lots of contradicting howtos, I've come up with a solution, which maps the left super key (left windows key / Mod4) in combination with hjkl to Left, Down, Up, Right. This is a system-wide setting.

Add this block to the end of the first section (right before };) of your /usr/share/X11/xkb/symbols/us:

//hjkl
//AltGr + hjkl
key <AC06> {        [         h, H, Left            ]       };
key <AC07> {        [         j, J, Down            ]       };
key <AC08> {        [         k, K, Up              ]       };
key <AC09> {        [         l, L, Right           ]       };
//Super_L -> Alt Gr
key <LWIN> { [ ISO_Level3_Shift ] }; //see below!

The first key line maps AltGr+h to Left.
The last key line makes the left super key behave like AltGr.
Here you go:

Super + h -> Left
Super + j -> Down
Super + k -> Up
Super + l -> Right

In order to apply the new settings, run setxkbmap or restart your system.

Important: This obviously disables the super key, so if you're actually using your super key for other purposes (i.e. moving a window to another workspace), you shouldn't remap it like this.
In order to use Caps Lock instead of Super, change the last key line with:

key <CAPS> { [ ISO_Level3_Shift ] };

Here's the complete first section of my config file:

default
partial alphanumeric_keys modifier_keys
xkb_symbols "basic" {

    name[Group1]= "English (US)";

    // Alphanumeric section
    key <TLDE> {        [     grave,    asciitilde      ]       };
    key <AE01> {        [         1,    exclam          ]       };
    key <AE02> {        [         2,    at              ]       };
    key <AE03> {        [         3,    numbersign      ]       };
    key <AE04> {        [         4,    dollar          ]       };
    key <AE05> {        [         5,    percent         ]       };
    key <AE06> {        [         6,    asciicircum     ]       };
    key <AE07> {        [         7,    ampersand       ]       };
    key <AE08> {        [         8,    asterisk        ]       };
    key <AE09> {        [         9,    parenleft       ]       };
    key <AE10> {        [         0,    parenright      ]       };
    key <AE11> {        [     minus,    underscore      ]       };
    key <AE12> {        [     equal,    plus            ]       };

    key <AD01> {        [         q,    Q               ]       };
    key <AD02> {        [         w,    W               ]       };
    key <AD03> {        [         e,    E               ]       };
    key <AD04> {        [         r,    R               ]       };
    key <AD05> {        [         t,    T               ]       };
    key <AD06> {        [         y,    Y               ]       };
    key <AD07> {        [         u,    U               ]       };
    key <AD08> {        [         i,    I               ]       };
    key <AD09> {        [         o,    O               ]       };
    key <AD10> {        [         p,    P               ]       };
    key <AD11> {        [ bracketleft,  braceleft       ]       };
    key <AD12> {        [ bracketright, braceright      ]       };

    key <AC01> {        [         a,    A               ]       };
    key <AC02> {        [         s,    S               ]       };
    key <AC03> {        [         d,    D               ]       };
    key <AC04> {        [         f,    F               ]       };
    key <AC05> {        [         g,    G               ]       };
    key <AC06> {        [         h,    H               ]       };
    key <AC07> {        [         j,    J               ]       };
    key <AC08> {        [         k,    K               ]       };
    key <AC09> {        [         l,    L               ]       };
    key <AC10> {        [ semicolon,    colon           ]       };
    key <AC11> {        [ apostrophe,   quotedbl        ]       };

    key <AB01> {        [         z,    Z               ]       };
    key <AB02> {        [         x,    X               ]       };
    key <AB03> {        [         c,    C               ]       };
    key <AB04> {        [         v,    V               ]       };
    key <AB05> {        [         b,    B               ]       };
    key <AB06> {        [         n,    N               ]       };
    key <AB07> {        [         m,    M               ]       };
    key <AB08> {        [     comma,    less            ]       };
    key <AB09> {        [    period,    greater         ]       };
    key <AB10> {        [     slash,    question        ]       };

    key <BKSL> {        [ backslash,         bar        ]       };
    // End alphanumeric section

    //hjkl
    //AltGr + hjkl
    key <AC06> {        [         h, H, Left            ]       };
    key <AC07> {        [         j, J, Down            ]       };
    key <AC08> {        [         k, K, Up              ]       };
    key <AC09> {        [         l, L, Right           ]       };
    //Super_L -> Alt Gr
    key <LWIN> { [ ISO_Level3_Shift ] };


};

I hope this helps somebody out there...

If anyone has a better solution, please let me know.

Edit: Tested on Fedora.

basic6

Posted 2010-01-15T16:38:41.117

Reputation: 2 032

Thank you basic6, it works on Ubuntu after the steps described below. There is an issue on Ubuntu (tested on Ubuntu 14.04) that .xkm files are not recompiled, and thus changes in /usr/share/X11/xkb/symbols/* have no effect. In order to improve it remove all *.xkm files from /var/lib/xkb and reboot system. After that the *.xkm files will be recompiled. For more information please have a look: http://ubuntuforums.org/showthread.php?t=1589744

– MPtr – 2014-07-24T07:54:28.990

I've done this approach myself, but it's not working for all applications! xev clearly says Left and it works for most applications. But some programs only react to the "real" arrow keys, like sublime text editor and others. – Tarrasch – 2012-02-17T08:18:59.543

1Works as described on Redhat 6.2. My sore wrists thank you! – BuckFilledPlatypus – 2013-02-21T15:53:46.183

3

No sudo needed, derivated from here, modified to make it work also when combined with Alt.

create a file w the following content:

! remove Caps Lock
clear lock
! remove Lock = Caps_Lock
! remove Shift = Caps_Lock
keycode 66 = NoSymbol NoSymbol
keycode 66 = ISO_Level3_Shift

keysym h = h H NoSymbol NoSymbol Left Left
keysym j = j J NoSymbol NoSymbol Down Down
keysym k = k K NoSymbol NoSymbol Up Up
keysym l = l L NoSymbol NoSymbol Right Right

! some sugar
keysym o = o O NoSymbol NoSymbol BackSpace NoSymbol
keysym i = i I NoSymbol NoSymbol Delete NoSymbol`

invoke

xmodmap file

It maps AltGr to Caps instead of Super, so you might rather set

keycode 66 = Super_L

(or watever xev gives you on hitting Super)

The sugar part gives backspace and Del as a special assignment to i and o, you might omit that, or see it as a bonus or motivation to expand/ adjust it on your own ;)

PS: if experiment with it, reset "default" mapping by invoking

setxkbmap

Zeitvertreib

Posted 2010-01-15T16:38:41.117

Reputation: 31

This did not work for me, but got me on the right track. This works for me: https://github.com/sblask/dotfiles/commit/605db73cc1acbdbc718e242d24d08c353e998dee

– Sebastian Blask – 2017-04-07T12:29:27.823

3

I haven't tried this myself but it looks like xkb might do what you want http://en.wikipedia.org/wiki/X_keyboard_extension.

I have a package in Ubuntu called x11-xkb-utils that sounds promising :)

gacrux

Posted 2010-01-15T16:38:41.117

Reputation: 1 611

xkb cannot work with the Super key as a modifier. xkb only works with (in order) Unmodified, Shift, AltGr, Shift-AltGr. Higher-level modifiers can also be assigned (such as in Bill Casarin's CapsLock example) but they do not come on a standard keyboard. Mapping Super to a higher modifier removes it from functioning as Super (as in basic6's example). – dotancohen – 2012-02-03T23:06:34.180

2

At last it seems that I found the solution that works with all modifiers (Ctrl+, Shift+, Ctrl+Shift+) and Sublime Text 2.

All glory goes to this gem configuration that I found recently http://www.spinics.net/lists/xorg/msg35931.html. It describes ijkl arrows, but it can be easily modified for hjkl navigation. You need to update your keyboard layout file(s) /usr/share/X11/xkb/symbols/* (personaly, I use /usr/share/X11/xkb/symbols/typo, which I include to my keyboard layout with Xkb option "misc:typo", so it works for any keyboard layout). Configuration assumes that modifier key send ISO_Level3_Shift (there are many ways how to bind Super or Alt to ISO_Level3_Shift).

Key definitions should look like (use NoSymbol if you're modifying ../symbols/typo):

key <AC07> {    
    type="MOD5_NAV",
    [NoSymbol, NoSymbol, Down, Down],   
    actions[Group1] = [NoAction(), NoAction(), RedirectKey(key=<DOWN>, clearmods=ISO_Level3_Shift)]
};

Also you need to edit /usr/share/X11/types/basic and declare type "MOD5_NAV":

type "MOD5_NAV" {
    modifiers = Shift+Mod5;
    map[None] = level1;
    map[Shift] = level2;
    map[Mod5] = level3;
    map[Mod5+Shift] = level3;
    level_name[Level1] = "Base";
    level_name[Level2] = "Caps";
    level_name[Level3] = "Arrows";
};

As for Sublime Text 2 the solution is more tricky and hackish. As mentioned above, Sublime Text 2 reads keycodes directly from the device and so ignores some features of Xkb (and xkb trick with arrows has no effect). There is an almost abandoned but still working project, Gizmo Daemon http://gizmod.sourceforge.net/. After some struggling and googling I successfully compiled it on my Debian Wheezy. Then I created this gizmod script and placed it to ~/.gizmod/modules.d/010-KeyboardViMode-SublimeText2.py http://pastebin.com/HNQgGEwD

P.S. On Linux I miss KeyboardRemap4MacBook sometimes. This great peace of OS X software can enable such navigation (and a lot of other things) with just few checkboxes.

sgtpep

Posted 2010-01-15T16:38:41.117

Reputation: 256

1

This one works for me on Arch. It remaps Caps+hjkl to arrow keys, and Shift+Caps to Caps.

Put the following in ~/.Xmodmap:

! Remap caps lock to special modifier, but still allow shift+caps to 
toggle caps lock
clear lock
clear mod5
add lock = Mode_switch
keycode 66 = Mode_switch Caps_Lock NoSymbol NoSymbol
keycode 43 = h H Left Left
keycode 44 = j J Down Down
keycode 45 = k K Up Up
keycode 46 = l L Right Right

Reboot or set it with xmodmap ~/.Xmodmap

If you get an error like:

X Error of failed request:  BadValue (integer parameter out of range for operation)

It probably means that you need to clear something other than mod5 (whatever is currently set to Mode_switch). Check your current modifier mappings with xmodmap.

Huon Imberger

Posted 2010-01-15T16:38:41.117

Reputation: 11

1

I am a HHKB user on Debian/Ubuntu and this solution works for me.

use Left Ctrl to active key.

$ vi ~/.Xmodmap
keycode 37 = ISO_Level3_Shift

Add this code under // End alphanumeric section in the basic block in /usr/share/X11/xkb/symbols/us

//hjkl
//Ctrl + hjkl
key <AC06> {    [   h,  H,  Left    ]   };
key <AC07> {    [   j,  J,  Down    ]   };
key <AC08> {    [   k,  K,  Up      ]   };
key <AC09> {    [   l,  L,  Right   ]   };

Now, you should be able to use left, down, up and right key with Ctrl + h, j, k, l.

By the way, if you have used pentadactyl on Firefox, you can add this code in ~/.pentadactylrc

map -modes=i,c <C-down> <down>
map -modes=i,c <C-up> <up>

Chu-Saing Lai

Posted 2010-01-15T16:38:41.117

Reputation: 171

1

I found autokey and it is better for mapping.

I believe the link key binding - Emulate Keypad on Laptop - Ask Ubuntu might help you.

Chu-Saing Lai

Posted 2010-01-15T16:38:41.117

Reputation: 171