After remapping my grave-tilde `~
key to its original function for my Keychron K6 on Linux, I coudn't help but wonder how those keys are implemented scancode-wise on 60/65% keyboards. FWIW, on a ANSI layout keyboard, the tilde ~
symbol exist only on the second layer of grave-tilde `~
key (by pressing Shift
+ `
) and this is handled by the operating system. So how do these small-form-factor keyboards manage to enter the `
and ~
with manufactors' choice of modifiers?
In this article I will experiment with the scancodes sent while entering ESC
, `
, ~
on two 65% keyboards: Keychron K6 and Qisan Magiforce 68.
How does it normally work?
Normally, pressing the `~
key on a keyboard sends scancode 41
, signalling the operating system that the `
key has pressed. When on ANSI layout, typing ~
is achieved by pressing Shift
+ `
; operating systems interpret this combo-key and enter a ~
symbol for you.
Keychon K6
The Keychron K6 is a 65% keyboard with bluetooth connectivity. ESC
is entered normally; `
and ~
are entered entirely using function keys as modifiers.
Symbol | Key Press(es) |
---|---|
ESC |
ESC |
` |
fn1 + ESC |
~ |
fn2 + ESC |
Debugging with evtest
Entering ESC
, `
, ~
while running evetst
gives the following
$ sudo evtest /dev/input/by-id/usb-Keychron_Keychron_K6-event-kbd
...
Event: time 1634444664.936753, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70029
Event: time 1634444664.936753, type 1 (EV_KEY), code 1 (KEY_ESC), value 1
Event: time 1634444664.936753, -------------- SYN_REPORT ------------
`Event: time 1634444665.027811, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70029
Event: time 1634444665.027811, type 1 (EV_KEY), code 1 (KEY_ESC), value 0
Event: time 1634444665.027811, -------------- SYN_REPORT ------------
Event: time 1634444667.688758, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634444667.688758, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 1
Event: time 1634444667.688758, -------------- SYN_REPORT ------------
`Event: time 1634444667.779851, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634444667.779851, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 0
Event: time 1634444667.779851, -------------- SYN_REPORT ------------
Event: time 1634444671.726653, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1634444671.726653, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1634444671.726653, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634444671.726653, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 1
Event: time 1634444671.726653, -------------- SYN_REPORT ------------
~Event: time 1634444671.739657, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1634444671.739657, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1634444671.739657, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634444671.739657, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 0
Event: time 1634444671.739657, -------------- SYN_REPORT ------------
The first half of output snippet is fairly standard. What was interesting is the last final portion: when fn2
+ ESC
are pressed, the keyboard sends the following key sequence:
Left Shift
ON,GRAVE
ON,Left Shift
OFF,GRAVE
OFF.
Essentially, when one presses fn2
+ ESC
, the Keychron K6 sends a "ghost" Shift
key press, immediately followed by the `
key, thereby "tricking" the operating system into thinking that you pressed Shift
+ `
to type the ~
symbol.
Symbol | Key Press(es) | Keyboard scancodes sent |
---|---|---|
ESC |
ESC |
01 ESC |
` |
fn1 + ESC |
41 ` |
~ |
fn2 + ESC |
42 Left Shift , 41 ` |
Qisan Magicforce 68
The Qisan Magicforce 68 is a budget 65% keyboard. ESC
, `
, ~
are entered by:
Symbol | Key Press(es) |
---|---|
ESC |
ESC |
` |
Fn + ESC |
~ |
Shift + ESC |
Debugging with evtest
Entering ESC
, `
, ~
while running evetst
gives the following
$ sudo evtest /dev/input/by-id/usb-HOLDCHIP_USB_Gaming_Keyboard-event-kbd
...
Event: time 1634446951.832094, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70029
Event: time 1634446951.832094, type 1 (EV_KEY), code 1 (KEY_ESC), value 1
Event: time 1634446951.832094, -------------- SYN_REPORT ------------
`Event: time 1634446951.888008, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70029
Event: time 1634446951.888008, type 1 (EV_KEY), code 1 (KEY_ESC), value 0
Event: time 1634446951.888008, -------------- SYN_REPORT ------------
Event: time 1634446954.473025, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634446954.473025, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 1
Event: time 1634446954.473025, -------------- SYN_REPORT ------------
`Event: time 1634446954.526951, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634446954.526951, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 0
Event: time 1634446954.526951, -------------- SYN_REPORT ------------
Event: time 1634446955.289994, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1634446955.289994, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1634446955.289994, -------------- SYN_REPORT ------------
Event: time 1634446955.421018, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634446955.421018, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 1
Event: time 1634446955.421018, -------------- SYN_REPORT ------------
~Event: time 1634446955.447924, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1634446955.447924, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1634446955.447924, -------------- SYN_REPORT ------------
Event: time 1634446955.518009, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70035
Event: time 1634446955.518009, type 1 (EV_KEY), code 41 (KEY_GRAVE), value 0
Event: time 1634446955.518009, -------------- SYN_REPORT ------------
As it turns out, and kind of expectedly, the Magiforce 68 uses the same "ghost key press" principle to mimick key presses for `
and ~
; the only difference is the key combinations chosen by the manufacturer for triggering such scancodes.
Symbol | Key Press(es) | Keyboard scancodes sent |
---|---|---|
ESC |
ESC |
01 ESC |
` |
Fn + ESC |
41 ` |
~ |
Shift + ESC |
42 Left Shift , 41 ` |