Skip to content

Instantly share code, notes, and snippets.

@xkonni
Last active February 15, 2021 13:27
Show Gist options
  • Save xkonni/895b3ae4a1cd9bde0d14312cd7bf1a28 to your computer and use it in GitHub Desktop.
Save xkonni/895b3ae4a1cd9bde0d14312cd7bf1a28 to your computer and use it in GitHub Desktop.
QMK functionality via XKB eight-level config

QMK functionality via XKB eight-level config

Description

Redefine a regular/laptop keyboard to have caps as level5 modifier with special combinations, e.g.

  • vim
    • caps + h = arrow left
    • caps + j = arrow down
    • caps + k = arrow up
    • caps + l = arrow right
  • fn
    • caps + backspace = delete

And many more. Those can easily be customized.

Note: XF86 Keys are not working properly, they're still coming out masked and the applications do not listen to them like this.

Installation

add to /usr/share/X11/xkb/symbols/xk5

default partial alphanumeric_keys modifier_keys
xkb_symbols "vim"  {
  name[Group1]= "xk5: vim arrow keys";
  key <AC06> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [          h,          H,     ugrave,     Ugrave,       Left,       Left,       Left,       Left ]
  };
  key <AC07> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [          j,          J,     uacute,     Uacute,       Down,       Down,       Down,       Down ]
  };
  key <AC08> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [          k,          K,      U0133,      U0132,         Up,         Up,         Up,         Up ]
  };
  key <AC09> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [          l,          L,     oslash,     Oslash,      Right,      Right,      Right,      Right ]
  };
  include "level5(caps_switch)"
};

xkb_symbols "media"  {
  name[Group1]= "xk5: media keys";
  key <AD01> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [                    q,                    Q,                   ae,                   AE,
                               XF86AudioPrev,        XF86AudioPrev,        XF86AudioPrev,        XF86AudioPrev ]
  };
  key <AD02> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [                    w,                    W,                aring,                Aring,
                               XF86AudioPlay,        XF86AudioPlay,        XF86AudioPlay,        XF86AudioPlay ]
  };
  key <AD03> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [                    e,                    E,           ediaeresis,            diaeresis,
                               XF86AudioNext,        XF86AudioNext,        XF86AudioNext,        XF86AudioNext ]
  };
  key <AC01> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [                    a,                    A,           adiaeresis,           Adiaeresis,
                             XF86LowerVolume,      XF86LowerVolume,      XF86LowerVolume,      XF86LowerVolume ]
  };
  key <AC02> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [                    s,                    S,               ssharp,              section,
                               XF86AudioMute,        XF86AudioMute,        XF86AudioMute,        XF86AudioMute ]
  };
  key <AC03> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [                    d,                    D,                  eth,                  Eth,
                        XF86AudioRaiseVolume, XF86AudioRaiseVolume, XF86AudioRaiseVolume, XF86AudioRaiseVolume ]
  };
  include "level5(caps_switch)"
};

xkb_symbols "fn"  {
  name[Group1]= "xk5: fn keys";
  key <BKSP> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [      BackSpace,      BackSpace,      BackSpace,      BackSpace,
                                Delete,         Delete,         Delete,         Delete ]
  };
  key <AD06> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [              y,              Y,     ydiaeresis,     Ydiaeresis,
                                  Home,           Home,           Home,           Home ]
  };
  key <AD09> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [              o,              O,     odiaeresis,     Odiaeresis,
                                   End,            End,            End,            End ]
  };
  key <AD10> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [              p,              P,             oe,             OE,
                                 Print,          Print,          Print,          Print ]
  };
  key <AD11> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [    bracketleft,      braceleft,    bracketleft,      braceleft,
                                 Prior,          Prior,          Prior,          Prior ]
  };
  key <AD12> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [   bracketright,     braceright,   bracketright,     braceright,
                                  Next,           Next,           Next,           Next ]
  };
  key <AC10> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [      semicolon,          colon,         degree, periodcentered,
                               Insert,          Insert,         Insert,         Insert ]
  };
  key <AC11> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [     apostrophe,       quotedbl,     dead_acute, dead_diaeresis,
                                Delete,         Delete,         Delete,         Delete ]
  };
  include "level5(caps_switch)"
};

xkb_symbols "tl_esc"  {
  name[Group1]= "xk5: fn keys";
  key <TLDE> {
    type = "EIGHT_LEVEL",
    symbols[Group1] = [         Escape,     asciitilde,         Escape,         Escape,
                                 grave,     asciitilde,          grave,     asciitilde ]
  };
  include "level5(caps_switch)"
};

add to /usr/share/X11/xkb/rules/evdev

xk5:vim               = +xk5(vim)
xk5:media             = +xk5(media)
xk5:fn                = +xk5(fn)
xk5:tl_esc            = +xk5(tl_esc)
lv5:caps_switch   = +level5(caps_switch)

add to /usr/share/X11/xkb/rules/evdev.xml

<group allowMultipleSelection="true">                                                           
 <configItem>                                                                                  
   <name>lv5</name>                                                                                                                                                                                        
   <description>Key to choose 5th level</description>                                          
 </configItem>                                                                                 
 <option>                                                                                      
   <configItem>                                                                                
     <name>lv5:caps_switch</name>                                                              
     <description>Caps chooses 5th level</description>                                         
   </configItem>                                                                               
 </option>    
 ... 
 existing entries!
 ...
</group>  
  
<group allowMultipleSelection="true">
<configItem>
  <name>xk5</name>
  <description>Level5 keys</description>
</configItem>
<option>
  <configItem>
    <name>xk5:vim</name>
    <description>vim: hjkl arrows</description>
  </configItem>
</option>
<option>
  <configItem>
    <name>xk5:media</name>
    <description>media: qwe play, asd volume</description>
  </configItem>
</option>
<option>
  <configItem>
    <name>xk5:fn</name>
    <description>Bksp Delete, y Home, o End, p Print, [ Prior, ] Next, ; Insert, ' Delete </description>
  </configItem>
</option>
<option>
  <configItem>
    <name>xk5:tl_esc</name>
    <description>fn: ~ Esc</description>
  </configItem>
</option>
</group>

Activation

  • setxkbmap
    • use -o xk5:vim
  • gnome
    • Select the modifiers in gnome-tweaks
  • sway
    • use options in input-block
input "1:1:AT_Translated_Set_2_keyboard" {
  xkb_layout "eu"
  xkb_options "xk5:vim,xk5:fn"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment