Gebruik je toetsenbord anders met KMonad

Zonder je toetsenbord aan te passen toch knoppen anders indelen

Eén van de redenen waarom mensen aan mechanische toetsenborden beginnen — naast dat het, godverpielekes, goddelijk tikt, waarom heb ik dit niet eerder gedaan, etc. — is om meer vrijheid te hebben om er aanpassingen aan te maken.

Dat kan aan de buitenkant (een ander setje keycaps of switches bijvoorbeeld), maar ook op het gebied van software valt er nog wel wat te pielen. Misschien klinkt dat wat overdreven nerderig, maar afhankelijk van je werk ben je soms hele dagen aan het typen - het is dus absoluut lonend om die ervaring zo efficiënt en prettig mogelijk te maken.

In mijn geval heb ik twee simpele wensen:

  • Ik wil mijn Delete-knop verplaatsen; normaal zit die op de Keychron boven de Backspace, maar daarvoor moet ik dus nogal omhoog reiken met mijn hand, en de kans bestaat dat ik een screenshot- of lichtshow-knop raak. Op een groter toetsenbord zit de Delete rechts van de backslash, waar op de keychron Page Down zit.
  • Ik wil met een combinatie van een modifier en het cursoreilandje snel door pagina's willen rammen. Een modifier is een toets die op zichzelf niets doet, maar in combinatie gebruikt wordt met andere toetsen — Shift, Control enzovoorts zijn allemaal modifiers. Op het Bluetooth Apple-toetsenbordje waar ik vroeger een tijd op gewerkt heb, was dat in combinatie met Cmd. De cursortoetsen en worden dan Home en End, en worden Page Up en Page Down.

Misschien dat ik in de toekomst nog wat wildere dingen wil, zoals CapsLock ombatterijen naar Escape of Control, of misschien zelfs alles vanaf de home row gaan bestieren om de afstand die mijn vingers moeten afleggen te minimaliseren. Daarmee komen we wel een beetje in nerderij-gebied, natuurlijk...

Rommelen met de software kan op twee plekken: op het toetsenbord zelf — elk toetsenbord heeft een klein stukje hardware (de MCU) met firmware om de toetsaanslagen te registreren en over een USB-kabeltje of Bluetooth-verbinding heen te drukken — óf op de computer waar dat toetsenbord aan is gekoppeld.

Firmware vervangen

Vervangen van je firmware is niet altijd mogelijk. De hardware is in theorie natuurlijk altijd te herprogrammeren, maar als het een onbekende of niet-ondersteunde MCU is of de hoeveelheid geheugen is te sneu om mee te werken, dan wordt het een lastig verhaal.

Mocht de firmware aan te passen zijn, dan is QMK een veelgebruikte (en open source) firmware, met heel veel mogelijkheden om alles naar je hand te zetten. Toetsenborden die uit de doos QMK ondersteunen of er zelfs mee geleverd worden, zitten over het algemeen in een iets hoger prijssegment dan waar de K2 in zit, omdat er iets duurdere MCU's gebruikt worden. Een groot voordeel van je aanpassingen in het toetsenbord zélf kunnen maken, is dat het dan meteen geldig is voor alle apparaten waar je dat toetsenbord aan koppelt.

Er is wel een project gaande om QMK te porten naar de MCU die onder andere in dit toetsenbord wordt gebruikt, maar voorlopig gaat dat nog ten koste van Bluetooth, en ik weet nog niet of ik dat wil opgeven. Ik hou het project wel nauwlettend in de gaten.

Een kwestie van interpretatie

Het alternatief voor het vervangen van je firmware is om simpelweg de toetsaanslagen die het toetsenbord aan je computer doorgeeft, anders te interpreteren. Ook daar is software voor, en ook die is open source: KMonad. Het is zelfs cross-platform, dus niet voorbehouden aan Linux-gebruikers!

KMonad schuif je tussen de input uit je toetsenbord en het daadwerkelijk uitvoeren van toetsaanslagen naar je besturingssysteem. Een beperking van KMonad-op-de-computer versus QMK-op-het-toetsenbord, is dat het toetsenbord sommige toetsen domweg niet rapporteert, en dan kan KMonad (of welke andere software dan ook) er niets mee, natuurlijk. Op de Keychron zijn dat de fn en de lichtshow-knop, en de sliders aan de zijkant.

De configuratie bestaat op zijn minst uit "het apparaat", "een uitvoerapparaat", "de knoppen waarop op het apparaat gedrukt kan worden" en "de knoppen(-combinaties) die we aan het besturingssysteem willen rapporteren". Voor die laatste, die layers worden genoemd, kun je er ook meerdere specificeren, en dan kun je met bepaalde toetsen tussen layers wisselen. Er zijn ook nog allerlei mogelijkheden om een knop op meerdere manieren te laten reageren, al naar gelang je hem kort, lang of meermalen indrukt. Behoorlijk veelzijdig.

Een voorbeeld

Omdat er nogal wat opties zijn, is het absoluut nodig om de tutorial-configuratie op zijn minst goed door te nemen. Alle mogelijkheden komen daar wel aan bod. Let ook op welke versie van KMonad je gebruikt, er worden op de GitHub-pagina wat precompiled binaries aangeboden, maar die lopen een beetje achter. Voor mij werkte het het beste om het repository binnen te halen en via Docker een binary te bouwen.

Die binary heeft dan vervolgens een configuratie-bestand nodig. Omdat er voor de K2 nog geen definitie voorhanden was, heb ik die zelf aangemaakt. Ziehier de standaard toetsindeling en de vertaling naar de configuratie van KMonad:

Keychron K2 key map

(defsrc
  esc  f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11  f12  print del
  grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc  pgup
  tab   q    w    e    r    t    y    u    i    o    p    [    ]    \    pgdn
  caps   a    s    d    f    g    h    j    k    l    ;    '    ret      home
  lsft    z    x    c    v    b    n    m    ,    .    /    rsft      up end
  lctl lmet lalt             spc             ralt        rctl  left down rght
)

Elke vorm van witruimte is verder overbodig, da's puur voor de leuk en herkenning. Je kunt ook alles op één regel zetten, of elke toets op een losse regel. Op de bovenste rij ontbreekt helemaal aan het eind de lichtshow-knop, en op de onderste rij mist tussen de rechter alt (ralt) en control (rctl) de fn-toets. Beide worden door het toetsenbord niet doorgegeven, dus als ik daar iets zou definiëren, zou dat de toetsen erna doorschuiven.

Dat regelt de invoer waar KMonad vanaf weet; nu de uitvoer nog:

(deflayer qwerty
  esc  f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11  f12  print pgup
  grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc  pgdn
  tab   q    w    e    r    t    y    u    i    o    p    [    ]    \\   del
  caps   a    s    d    f    g    h    j    k    l    ;    '    ret      home
  lsft    z    x    c    v    b    n    m    ,    .    /    rsft      up end
  lctl lmet lalt             spc             ralt         @sup left down rght
)

(deflayer empty
  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _
  _    _    _    _    _    _    _    _    _    _    _    _    _    _     _
  _     _    _    _    _    _    _    _    _    _    _    _    _    _    _
  _      _    _    _    _    _    _    _    _    _    _    _    _        _
  _       _    _    _    _    _    _    _    _    _    _    _         _  _
  _    _    _                _               _            _    _    _    _
)

(deflayer super
  @qwe _    _    _    _    _    _    _    _    _    _    _    _    _      _
  _    _    _    _    _    _    _    _    _    _    _    _    _    del    _
  _     _    _    _    _    _    _    _    _    _    _    _    _    _     _
  _      _    _    _    _    _    _    _    _    _    _    _    _         _
  _       _    _    _    _    _    _    _    _    _    _    _        pgup _
  _    _    _                _               _            _    home pgdn end
)

Hee, dat zijn er ineens drie. De eerste, querty, is de standaardlaag. Daar komen bijna alle toetsen gewoon ongewijzigd op terug, behalve dat ik in de meest rechtse kolom de del-toets naar beneden heb verplaatst, en rctl nu als @sup wordt vertaald. Daar kom ik nog op terug.

De tweede layout is een lege layer, die ik alleen heb gemaakt om makkelijk nieuwe layers te kunnen aanmaken. Een underscore in een layer betekent namelijk "laat deze toets doordruppelen naar de laag eronder". Inn mijn geval is dat dus die querty-laag.

De laatste layer is een interessante, daar heb ik op de locaties van de cursortoetsen de gewenste nieuwe toetsen gedefineerd en, voor de compleetheid, wordt op deze laag de backspace naar del vertaald.

Om de configuratie af te maken hebben we ook nog wat aliassen nodig die corresponderen met de toetsen die met een @ beginnen:

(defalias
  qwe (layer-switch qwerty)
  sup (layer-toggle super)
)

Eindresultaat is dat, zolang ik de rechter Control-toets ingedrukt houd, het toetsenbord naar de laag super wordt geschoven. Alles wat in die laag is gedefinieerd, krijgt dan voorrang. Voor de zekerheid, maar in dit geval niet strikt noodzakelijk is de alias qwe, die ik in de super-laag heb gemapt op Escape, en die me altijd weer terugbrengt in de querty-laag.

Als ik dit nu uitprobeer door KMonad met die config-file te laten starten, heb ik inderdaad voor elkaar dat del verplaatst is. Ik heb dat op mijn fysieke toetsenbord ook maar even bewerkstelligd, hoewel dat er door verschillende hoogtes van keycaps wat mal uitziet...

Bump.
De Del-toets steekt een beetje boven de rest uit, en pgdn ligt juist wat onder de zeespiegel

Stiekem maakt dat het wel makkelijker om die knop te vinden, en hoe dan ook is er een setje keycaps onderweg in een vlak profiel.

Verdere aanpassingen en een stukje statistiek

Een stukje terug schreef ik al iets over werken vanaf de home row. Dat spreekt me ergens wel aan, al zal het een beste gewenning met zich meebrengen. Iets minder ingrijpend maar nog steeds interessant is het ombouwen van nog een paar andere toetsen, misschien, maar voor ik daaraan begin wil ik eerst weten welke toetsen ik veel, weinig of niet gebruik.

Daar is met een beetje kunst- en vliegwerk met KMonad ook nog wel een antwoord op te krijgen: bij het opstarten kun je een log-level meegeven, en als je daarvoor debug gebruikt, wordt elke toetsaanslag en uitgevoerde toets gemeld. Dat kun je dan weer opvangen in een bestandje, en daar kun je later dan weer doorheen kammen.

Precies, een keylogger, dus. E erin, E eruit, in dit voorbeeld:

Received event: Press <e>
Running hooks
Registering untimed hook: 42526
Emitting: Press <e>

Ik ben vooral geïnteresseerd in de invoer, natuurlijk, en dan de aantallen. Met wat command-line-foo trekken we die statistieken er ook nog wel uit:

% grep 'event: Press' /tmp/keylog.log | sed 's/Received event: Press //' | sort | uniq -c | sort -rn | head

met als resultaat:

3062 <spc>
2620 <e>
1502 <bks>
1353 <n>
1231 <a>
1185 <t>
1095 <o>
1022 <i>
 937 <d>
 882 <r>

Blijkbaar kan ik, zelfs op dit prachtige staaltje tikvernuft, nog steeds niet typen en is de Backspace behoorlijk in de telling aanwezig... En de letter E komt inderdaad bovenmatig veel voor in wat ik zoal tik.

Op termijn wil ik hier iets van een heatmap van maken, en kijken of ik naast de rechter control, waarvan ik al wel wist dat ik die niet gebruikte, nog andere gaten zie. Daar kan ik dan nog extra functionaliteit aan hangen.

Al met al een handig gereedschap, zelfs al heb ik nog maar een fraktie van de mogelijkheden gebruikt!

Je gebruikt een browser die Google's FLOC gebruikt en daarmee op je spioneert. Lees hier meer over waarom dat een slecht idee is.