I've had a
limited go at software remapping the Shift key to the thumb clusters (Home and End keys) on Linux
using xkb but without success so far: it tends to change other keys as well. eg. My model has '(' on
the 5 key but after my mods, it reverted to '%' like a standard keyboard. There was also some other
weird behavior with the underscore key, which seemed to want to become 'home + _'. I'm thinking it
can probably be done, I just need to learn how to do it, but I'm also not sure if the unusual
placement of the symbols results in Shift remapping limitations or anything. Has anyone had success
at software remapping Shift keys in Linux, Windows and Mac? Having to figure out remapping for each
OS sounds painful vs native hardware support.!
Just an update in case it's useful for anyone. I don't think this can be done on an old Maltron L89 layout, which is different to the newer L89s, due to the shenanigans the firmware does (and has to do, I think) in order to have the symbols in non-standard locations. Couple of examples:
- ex1: the 1 key's shifted state is +. This is how the Maltron seems to achieve that:
- pressing 1 without shift sends keycode 10, as expected
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16300651, (573,559), root:(573,614),
state 0x0, keycode 10 (keysym 0x31, 1), same_screen YES,
XLookupString gives 1 bytes: (31) "1"
XmbLookupString gives 1 bytes: (31) "1"
XFilterEvent returns: False
- however, shift-1 sends shifted keycode 21. ie. it's pretending to be the =/+ key on a standard US keyboard.
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16302293, (573,559), root:(573,614),
state 0x0, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16302424, (573,559), root:(573,614),
state 0x1, keycode 21 (keysym 0x2b, plus), same_screen YES,
XLookupString gives 1 bytes: (2b) "+"
XmbLookupString gives 1 bytes: (2b) "+"
XFilterEvent returns: False
- ex2: there's a ! key with a shifted state of ] achieved via:
- pressing ! _without_ shift, sends shift and keycode 10 all on its own. ie. pretending to be the 1/! key on a standard keyboard
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16401878, (307,879), root:(307,934),
state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16401893, (307,879), root:(307,934),
state 0x1, keycode 10 (keysym 0x21, exclam), same_screen YES,
XLookupString gives 1 bytes: (21) "!"
XmbLookupString gives 1 bytes: (21) "!"
XFilterEvent returns: False
- pressing shift-! sends a bunch of shift events (weird) and keycode 35, again, pretending to be another key on a standard keyboard
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16519469, (301,227), root:(301,282),
state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16519920, (301,227), root:(301,282),
state 0x1, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16519940, (301,227), root:(301,282),
state 0x0, keycode 35 (keysym 0x5d, bracketright), same_screen YES,
XLookupString gives 1 bytes: (5d) "]"
XmbLookupString gives 1 bytes: (5d) "]"
XFilterEvent returns: False
KeyPress event, serial 40, synthetic NO, window 0x3400001,
root 0x1e1, subw 0x0, time 16519955, (301,227), root:(301,282),
state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
I think the above has to be done to be handled correctly as a US keyboard, due to the way the OS interprets (shift, keycode) pairs, which I only have a vague understanding of from
https://wiki.archlinux.org/title/X_keyboard_extension#Basic_information_on_XKB. I think it also explains something I wasn't clear about with the Ergodox EZ, that it didn't seem like you can customise the shifted state of keys; they just behave 'as normal'. Not needed with the layers feature but it seemed curious.
The newer L89 Maltron's leave the shifted states on the same keys as a standard keyboard. I wonder if it was done in response to user feedback about remapping difficulties.