cajhin / capsicain

Powerful low-level keyboard remapping tool for Windows
349 stars 18 forks source link

Unexpected NumLock and LED behavior #32

Closed bitoj closed 3 years ago

bitoj commented 3 years ago

Now testing with 2 full size keyboards, each with 3 LEDs. Also switched on audible confirmation of toggle key actions in Windows accessibility options.

Even when using the following almost empty ini

GLOBAL ActiveConfigOnStartup 0

Capsicain has an effect on the NumLock state at startup. More precisely, after starting the program, the Windows NumLock state and NumLock LEDs on both attached keyboards are switched on as soon as the first arbitrary key on either of the connected keyboards is pressed. The state can be restored by pressing a NumLock key on either keyboard.

Additionally, with the following line also present

GLOBAL capsicainOnOffKey SCRLOCK

things get more complicated. Example scenario:

  1. Clear Windows state: no toggles on.
  2. Start Capsicain with both ini lines above. ScrLk LED turns on to indicate Capsicain state.
  3. Tap Shift on either keyboard. NumLock Windows state and LEDs are on (as above without the second line in the ini).
  4. Tap NumLock on either keyboard. Windows NumLock state and NumLock LEDs switch off (as expected and intended). ScrLk LEDs also switch off. Capsicain remains active (no change in console window).
  5. Tap Shift on the other keyboard. The Windows NumLock state and LEDs and ScrLk LEDs are all switched on.
bitoj commented 3 years ago

Example 2:

  1. Switch on Windows NumLock and CapsLock state.
  2. Start Capsicain with the above 2-line ini. The ScrLk LEDs also switch on (as expected).
  3. Tap Shift. The Windows CapsLock state and LEDs unexpectedly turn off.
  4. Tap CapsLock. The Windows CapsLock state and LEDs turn on (as intended and expected). The ScrLk LEDs also turn off. Capsicain remains active.
  5. Tap ScrLk. Capsicain switches to the inactive state. The ScrLk LEDs remain off (as expected). The CapsLock state and LEDs also remain on (as expected).
  6. Tap ScrLk. The ScrLk LEDs turn on and Capsicain becomes active again (as expected). But the CapsLock Windows state and LEDs turn off again, this time immediately.
bitoj commented 3 years ago

After looking at the code I noticed that part of this unexpected behavior seems to be by design. So no PR without knowing the rationale.

However, most problems are solved by eliminating resetCapsNumScrollLock.

What then remains is the effect that probably should be expected: Windows appears to reset the LEDs it doesn't know about. So the LED that corresponds with capsicainOnOffKey is switched off by Windows, when another toggle state changes.

I suspect most of that remaining problem might be fixed by moving or copying the code that compensates for that from the end of sendVKeyEvent to somewhere in the main loop. Of course that code can only react to Windows toggle state changes that are the result of pressing a physical key. Changes of the toggle state by applications will not be detected. That would need periodic checks, I think.

cajhin commented 3 years ago

resetCapsNumScrollLock is called on reset (ESC-Backspace) and layer change (also the initial change on startup). I think it is better to reset the state of these keys to default, in case (for example) you toggled your ScrollLock and don't understand that/why this messes with your config.

Windows does not set the one corresponding LED on state change, it sets all three. So if you control the ScrLock LED, you must re-apply your LED state after you send out NumLock or CapsLock key events. Note: you must also consider the ESC key, since Windows turns NumLock off when you press ESC, and this again sets all three LEDs.

bitoj commented 3 years ago

resetCapsNumScrollLock is additionally called whenever the latest keypress was from a different keyboard than the immediately preceding keypress, or if there was no previous keypress. So it is called once at program startup, once shortly after, when setting the active configuration, then when the first key is pressed, and further more each time after switching keyboards.

That makes using a separate physical numeric keypad (or a full size keyboard, in the test configuration) as a navigation pad (i.e. with numlock off) a rather unpleasant experience. Each time you use a navigation action after typing something, you have to press NumLock again.

Windows 10 Pro 20H2 (19042.789) does not switch off NumLock (or any other toggle state) when pressing Esc.

cajhin commented 3 years ago

Right, it should not reset on keyboard change. I imagined that would be a big context switch, but of course a separate numpad isn't. I'll remove that. Also double reset on start is wrong (shouldn't have an observable effect but it's a waste)

cajhin commented 3 years ago

v92 should fix this. I've used it for a couple of hours and it works here. Please check in your env.

The state of the locking LED keys is not changed anymore. Only on ESC+Backspace (reset). If you start/use/stop capsicain, NumLock state should not change anymore (unless you tap the key of course)

I noticed a timing issue on the laptop that was not happening on my main PC. Basically, I send "NUMLOCK" to Windows, then ask Windows "what's the state of NumLock?" This is too fast on the laptop, Windows had no time to register the NumLock event. Now I sleep 50ms (unscientific number - it works with 1ms + safety overhead) after sending a state changing key.

bitoj commented 3 years ago

Looks good. It works in my set-up too, with numpad, without work-arounds.

Leaving the issue open for the moment, because I still hope to test some variations tomorrow. I'll also have a look at the documentation and examples, because of the change in behavior.

bitoj commented 3 years ago

After using v92 for a full day in my favorite configuration, everything worked as it should, i.e., completely predictably.

Because not setting the lock state at the very first key press is a potentially significant change of behavior, I tried to come up with situations where users might experience surprises. The effects of using config KINGCON_TAB_TO_NUMPAD could change, for example.

I haven't found any.

There is obviously a change for people who switched off NumLock and then start Capsicain, but that would probably be visible on a keyboard that has this key, or would be a deliberate change in the BIOS or the default registry configuration

[HKEY_CURRENT_USER\Control Panel\Keyboard]
"InitialKeyboardIndicators"="2"

In other words, a perfect solution and a real improvement in usability. Thank you.