Author Topic: Numeric keypads with independent numlock and Macs  (Read 3066 times)

0 Members and 1 Guest are viewing this topic.

Offline abyrd

  • Thread Starter
  • Posts: 2
Numeric keypads with independent numlock and Macs
« on: Sun, 03 July 2022, 07:04:04 »
I am trying to understand (and ideally remedy) problems I'm encountering with USB and Bluetooth external numeric keypads, particularly with MacOS. The message boards here have already been very helpful in understanding the situation. If no solution can be found, I at least want to collect this information together in one place for anyone who needs it in the future.

I have tried several USB or Bluetooth numeric keypads from different manufacturers that intersperse numlock key down / key up events into the stream of numpad key events. This has no noticeable effect under Linux and I see the expected numbers, but it confuses Macs because they don't have stateful numeric keypads and have repurposed the numlock key as a "clear" key. One of these keypad devices has a special Apple mode that disables this behavior, sending single key down and key up events on each keypress with no added numlock key events. This default non-Apple mode is labeled as a "Windows mode".

After reading a lot of posts here, I understand there are several interrelated issues here:
- Contemporary Macs do not have numlock state, always use the numpad for numbers, and repurpose the numlock key as a "clear" key.
- Key codes emitted by keyboards represent physical keys rather than a meaning, so keyboard output does not distinguish between keypad-1 and "end" for example.
- Numlock state is typically not maintained by keyboards but by the OS, which sets the LED on the keyboard to match its own state.
- Systems that have numlock state maintain a single system-wide numlock state, not a per-device numlock state.
- If an external keyboard sends a numlock key code to a laptop keyboard with a number overlay, the OS will begin interpreting both external keyboard and laptop keyboard keypresses as numbers.
- External numpads first tried to work around this by sending top row (R5) key codes instead of numpad key codes, but some use cases require numpad key codes so users considered this broken.
- External numpads then switched to sending numpad key codes, but tracking their own numlock state independently of the host system, monitoring the system numlock state and injecting numlock keypresses to switch state on and off during typing.
- MacOS interprets this as someone hammering the "clear" button while typing numbers.

I found this kind of absurd and was surprised that this is not clearly documented by the manufacturers, but at least I see what's going on here and understand that they make these devices to please most of their customers most of the time: people want numpad key codes for games or specialist applications, have laptops with number overlays, and have operating systems that track numlock state.

However I still haven't fully understood some details I observed, and cannot figure out how to work around the numlock injection behavior in MacOS. First, one numpad device appears to send different key codes when its internal independent numlock is disabled than when it's enabled. Not just additional numlock keycodes, but different keycodes for the navigation keys themselves, and I can't track down the meaning of these codes anywhere. This seems to contradict the idea that key codes only ever represent physical keys, which is a root cause of this problem. Second, it should be possible to just filter out all the injected numlock key codes and retain only the desired key codes, but doing so in Karabiner under MacOS does not seem to solve anything. Alternatively, if I could signal this USB numpad that system numlock was enabled (i.e. tell it to turn on the numlock LED) then it would stop injecting numlock events, but I can't find any way to do this under MacOS.

Does anyone have any insight on this?

Full-size keyboards do not have this same behavior, and they cooperate reasonably well with multiple different operating systems. I think the key fact here is that when someone plugs in a full-size keyboard, they typically are not using the laptop keyboard at the same time. When they plug in a ten key pad, they typically do continue using the laptop keyboard at the same time, which leads to the numlock state conflicts and the numlock-injection workaround.

The following is a dump of all my observations as I explored this problem, in case it helps with the above problems, or is of use to anyone confronting this problem in the future.

The devices in question are:

Filco Majestouch TenKeyPad 2 "Professional"
Model no. FILCTKP15
Part no. FTKP22MBS/B2

Varmilo VB21M Bluetooth Numpad

Key codes were examined with Karabiner-Eventviewer and the Key Codes app on MacOS, and with showkey on Linux.

When you press the numlock key on the Filco, the LED on the unit toggles but it does not send any keycodes. When numlock is disabled, the Filco behaves as I'd expect: escape, tab, backspace, navigation keys etc. all send one key down and one key up event. The equals key is the only exception - it sends a sequence of ten key codes, but I'll ignore that for now.

When numlock is enabled on the Filco, the keys esc, tab, backspace, slash, asterisk, dash, plus, and enter continue to send one key down and one key up event for each keypress. But the numeric keys behave differently: under MacOS they appear to all send the same key down/up events 0x47 (71 dec) only, with no numpad key down or up event. These events seem to be rate-limited: if I type numbers quickly, only the first one triggers an event pair, and subsequent ones appear to send no codes at all.

The equals key is quite special. When numlock is engaged, it appears to send numlock 0x47 down-up only, just like the number keys. When numlock is disengaged, it sends a sequence of 10 events including alt modifiers and the numbers 6 and 1.

It seems like the event sequences are being filtered somehow before they reach the MacOS utilities. I get more plausible output from showkey on Linux. Typing a number key gives numlock down-up, number down, numlock down-up, number up. The details are included below. The key codes reported are different than those under MacOS, and match the scan code set 1 codes for numlock and numpad keys.

The Varmilo device has similar but slightly different behavior. On first keystroke it sends numlock down-up, but not on subsequent ones. Unlike the Filco, even on a Mac I can actually see the numpad number key events for the keys pressed. Then after any quiet period of about 1 second without typing, it again sends numlock down-up sequence.

The Varmilo enables this behavior by default and calls it "Windows mode", and the mode where it just sends events for exactly the keys that you press is a special "Apple Mode" that you have to enable via the fn-tab key combination.

The Filco website and box insert sheet provide some hints. From the Filco product page at  https://www.diatec.co.jp/en/det.php?prod_c=3241, Independent NumLock: keypads NumLock won't affect keyboards NumLock and vice versa. Machine translating from the Japanese-language leaflet in the package: Because it has a non-interlocking numlock, it can be connected to a notebook PC and used immediately. When using with a notebook PC, the main unit and the numlock on the numeric keypad do not work together.

Here is the output from showkey under Linux:

Typing 123 on the Filco with numlock engaged:
1
keycode  69 press
keycode  69 release
keycode  79 press
keycode  69 press
keycode  69 release
keycode  79 release
2
keycode  69 press
keycode  69 release
keycode  80 press
keycode  69 press
keycode  69 release
keycode  80 release
3
keycode  69 press
keycode  69 release
keycode  81 press
keycode  69 press
keycode  69 release
keycode  81 release

And here is pressing "equals" first with numlock disengaged, then with it engaged:
61
keycode  56 press
keycode  69 press
keycode  77 press
keycode  69 release
keycode  77 release
keycode  79 press
keycode  79 release
keycode  56 release
keycode  69 press
keycode  69 release
61
keycode  69 press
keycode  56 press
keycode  69 release
keycode  77 press
keycode  77 release
keycode  79 press
keycode  79 release
keycode  56 release
keycode  69 press
keycode  69 release

Bizarrely, when numlock is off the Filco keypad 1, 2, 3 produce codes 107, 108, 109. This seems to contradict the idea that key codes always correspond to physical keys. There are distinct codes for numpad pgdn, down, end as opposed to numpad 1, 2, 3. A USB-attached Apple keyboard with numpad always shows codes 79, 80, 81 as the Filco does with numlock enabled.

These would be 0x4F, 0x50, 0x51 for numpad 1, 2, 3, and 0x6B, 0x6C, 0x6D for numpad end, down, pgdn. I am unable to find these latter codes on any table of scancodes.

Interestingly, the output of the Filco changes depending on the system numlock state. Somehow it's being informed of this state change.

If you plug an Apple keyboard into a Linux machine and look at the output of showkey, the key codes of the numpad 1, 2, 3 are always 79, 80, 81 (0x4F, 0x50, x51) and the "clear" key sends code 69 (0x45) toggling the OS numlock state. You can use the Apple numpad to type numbers or navigate, and toggle between the two with the "clear" key. The keycodes remain the same, corresponding to the physical keys.

The Filco behaves differently. When its numlock is off, it sends scan codes 107, 108, 109 (0x6B, 0x6C, 0x6D) for numpad 1, 2, 3 (end, down, pgdn). When its numlock is on, it sends 79, 80, 81 (0x4F, 0x50, x51) for numpad 1, 2, 3, so the codes are not mapped one to one to physical keys. In addition, it sends a numlock down-up sequence interspersed with these number key scan codes, but only when the OS numlock state is off.

(The MacOS utility reports 119, 125, 121 (0x77, 0x7d, 0x79) for numpad 1, 2, 3 with numlock disabled. These are different than the codes with numlock enabled, and also different from the codes reported on Linux.)

My understanding is that the keyboard protocol was made bidirectional in the move from the PC XT to PC AT. State is managed by the OS and the LED status is transmitted back to the keyboard. The Filco must be receiving the OS signal to light the numlock LED, not changing its own independent numlock status, but still keeping track of the OS numlock status. It then inserts key codes to turn on the system numlock, send the codes, then turn the system numlock back off. It does this despite the fact that it apparently sends distinct keycodes for the navigation actions as opposed to the numbers.

Presumably we could just send it a numlock LED signal and it would stop injecting numlock codes. Here's a similar situation with a Realforce keyboard: https://geekhack.org/index.php?topic=20826.0
The binaries supplied there to set the HID numlock LED status on the keyboard would need to be recompiled under xcode assuming the approach employed there still works.

Thanks to anyone who has any solutions or insight on this topic!

Offline abyrd

  • Thread Starter
  • Posts: 2
Re: Numeric keypads with independent numlock and Macs
« Reply #1 on: Sun, 16 October 2022, 10:43:31 »
Following up on my own message for anyone who lands on this in the future. I never found an explanation or workaround for the Filco's bizarre behavior. The solution was to sell it and use a different numpad.

The Varmilo VB21M works great as it has a MacOS mode.

The Leopold FC210TP also works great with MacOS. It does not have a MacOS mode (and specifically states it does not support MacOS) but its behavior is just consistent with Apple hardware - the numpad keys send only numbers and calculator operators, they can't be used for navigation. Just don't enable numlock, which will cause it to intersperse "clear" keystrokes.